wbuf.c 37.4 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1 2 3
/*
 * JFFS2 -- Journalling Flash File System, Version 2.
 *
4 5
 * Copyright © 2001-2007 Red Hat, Inc.
 * Copyright © 2004 Thomas Gleixner <tglx@linutronix.de>
Linus Torvalds's avatar
Linus Torvalds committed
6 7 8 9 10 11 12 13
 *
 * Created by David Woodhouse <dwmw2@infradead.org>
 * Modified debugged and enhanced by Thomas Gleixner <tglx@linutronix.de>
 *
 * For licensing information, see the file 'LICENCE' in this directory.
 *
 */

14 15
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

Linus Torvalds's avatar
Linus Torvalds committed
16 17 18 19 20
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/crc32.h>
#include <linux/mtd/nand.h>
21
#include <linux/jiffies.h>
22
#include <linux/sched.h>
23
#include <linux/writeback.h>
24

Linus Torvalds's avatar
Linus Torvalds committed
25 26 27 28 29 30 31 32 33 34
#include "nodelist.h"

/* For testing write failures */
#undef BREAKME
#undef BREAKMEHEADER

#ifdef BREAKME
static unsigned char *brokenbuf;
#endif

35 36 37
#define PAGE_DIV(x) ( ((unsigned long)(x) / (unsigned long)(c->wbuf_pagesize)) * (unsigned long)(c->wbuf_pagesize) )
#define PAGE_MOD(x) ( (unsigned long)(x) % (unsigned long)(c->wbuf_pagesize) )

Linus Torvalds's avatar
Linus Torvalds committed
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
/* max. erase failures before we mark a block bad */
#define MAX_ERASE_FAILURES 	2

struct jffs2_inodirty {
	uint32_t ino;
	struct jffs2_inodirty *next;
};

static struct jffs2_inodirty inodirty_nomem;

static int jffs2_wbuf_pending_for_ino(struct jffs2_sb_info *c, uint32_t ino)
{
	struct jffs2_inodirty *this = c->wbuf_inodes;

	/* If a malloc failed, consider _everything_ dirty */
	if (this == &inodirty_nomem)
		return 1;

	/* If ino == 0, _any_ non-GC writes mean 'yes' */
	if (this && !ino)
		return 1;

	/* Look to see if the inode in question is pending in the wbuf */
	while (this) {
		if (this->ino == ino)
			return 1;
		this = this->next;
	}
	return 0;
}

static void jffs2_clear_wbuf_ino_list(struct jffs2_sb_info *c)
{
	struct jffs2_inodirty *this;

	this = c->wbuf_inodes;

	if (this != &inodirty_nomem) {
		while (this) {
			struct jffs2_inodirty *next = this->next;
			kfree(this);
			this = next;
		}
	}
	c->wbuf_inodes = NULL;
}

static void jffs2_wbuf_dirties_inode(struct jffs2_sb_info *c, uint32_t ino)
{
	struct jffs2_inodirty *new;

89
	/* Schedule delayed write-buffer write-out */
90
	jffs2_dirty_trigger(c);
Linus Torvalds's avatar
Linus Torvalds committed
91 92 93 94 95 96

	if (jffs2_wbuf_pending_for_ino(c, ino))
		return;

	new = kmalloc(sizeof(*new), GFP_KERNEL);
	if (!new) {
97
		jffs2_dbg(1, "No memory to allocate inodirty. Fallback to all considered dirty\n");
Linus Torvalds's avatar
Linus Torvalds committed
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
		jffs2_clear_wbuf_ino_list(c);
		c->wbuf_inodes = &inodirty_nomem;
		return;
	}
	new->ino = ino;
	new->next = c->wbuf_inodes;
	c->wbuf_inodes = new;
	return;
}

static inline void jffs2_refile_wbuf_blocks(struct jffs2_sb_info *c)
{
	struct list_head *this, *next;
	static int n;

	if (list_empty(&c->erasable_pending_wbuf_list))
		return;

	list_for_each_safe(this, next, &c->erasable_pending_wbuf_list) {
		struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);

119 120
		jffs2_dbg(1, "Removing eraseblock at 0x%08x from erasable_pending_wbuf_list...\n",
			  jeb->offset);
Linus Torvalds's avatar
Linus Torvalds committed
121 122 123 124
		list_del(this);
		if ((jiffies + (n++)) & 127) {
			/* Most of the time, we just erase it immediately. Otherwise we
			   spend ages scanning it on mount, etc. */
125
			jffs2_dbg(1, "...and adding to erase_pending_list\n");
Linus Torvalds's avatar
Linus Torvalds committed
126 127
			list_add_tail(&jeb->list, &c->erase_pending_list);
			c->nr_erasing_blocks++;
128
			jffs2_garbage_collect_trigger(c);
Linus Torvalds's avatar
Linus Torvalds committed
129 130 131
		} else {
			/* Sometimes, however, we leave it elsewhere so it doesn't get
			   immediately reused, and we spread the load a bit. */
132
			jffs2_dbg(1, "...and adding to erasable_list\n");
Linus Torvalds's avatar
Linus Torvalds committed
133 134 135 136 137
			list_add_tail(&jeb->list, &c->erasable_list);
		}
	}
}

138 139 140 141
#define REFILE_NOTEMPTY 0
#define REFILE_ANYWAY   1

static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, int allow_empty)
Linus Torvalds's avatar
Linus Torvalds committed
142
{
143
	jffs2_dbg(1, "About to refile bad block at %08x\n", jeb->offset);
Linus Torvalds's avatar
Linus Torvalds committed
144 145 146 147 148 149 150

	/* File the existing block on the bad_used_list.... */
	if (c->nextblock == jeb)
		c->nextblock = NULL;
	else /* Not sure this should ever happen... need more coffee */
		list_del(&jeb->list);
	if (jeb->first_node) {
151 152
		jffs2_dbg(1, "Refiling block at %08x to bad_used_list\n",
			  jeb->offset);
Linus Torvalds's avatar
Linus Torvalds committed
153 154
		list_add(&jeb->list, &c->bad_used_list);
	} else {
155
		BUG_ON(allow_empty == REFILE_NOTEMPTY);
Linus Torvalds's avatar
Linus Torvalds committed
156
		/* It has to have had some nodes or we couldn't be here */
157 158
		jffs2_dbg(1, "Refiling block at %08x to erase_pending_list\n",
			  jeb->offset);
Linus Torvalds's avatar
Linus Torvalds committed
159 160
		list_add(&jeb->list, &c->erase_pending_list);
		c->nr_erasing_blocks++;
161
		jffs2_garbage_collect_trigger(c);
Linus Torvalds's avatar
Linus Torvalds committed
162 163
	}

164 165 166 167 168 169 170 171 172 173 174 175
	if (!jffs2_prealloc_raw_node_refs(c, jeb, 1)) {
		uint32_t oldfree = jeb->free_size;

		jffs2_link_node_ref(c, jeb, 
				    (jeb->offset+c->sector_size-oldfree) | REF_OBSOLETE,
				    oldfree, NULL);
		/* convert to wasted */
		c->wasted_size += oldfree;
		jeb->wasted_size += oldfree;
		c->dirty_size -= oldfree;
		jeb->dirty_size -= oldfree;
	}
Linus Torvalds's avatar
Linus Torvalds committed
176

177 178 179
	jffs2_dbg_dump_block_lists_nolock(c);
	jffs2_dbg_acct_sanity_check_nolock(c,jeb);
	jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
Linus Torvalds's avatar
Linus Torvalds committed
180 181
}

182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
static struct jffs2_raw_node_ref **jffs2_incore_replace_raw(struct jffs2_sb_info *c,
							    struct jffs2_inode_info *f,
							    struct jffs2_raw_node_ref *raw,
							    union jffs2_node_union *node)
{
	struct jffs2_node_frag *frag;
	struct jffs2_full_dirent *fd;

	dbg_noderef("incore_replace_raw: node at %p is {%04x,%04x}\n",
		    node, je16_to_cpu(node->u.magic), je16_to_cpu(node->u.nodetype));

	BUG_ON(je16_to_cpu(node->u.magic) != 0x1985 &&
	       je16_to_cpu(node->u.magic) != 0);

	switch (je16_to_cpu(node->u.nodetype)) {
	case JFFS2_NODETYPE_INODE:
198 199 200 201
		if (f->metadata && f->metadata->raw == raw) {
			dbg_noderef("Will replace ->raw in f->metadata at %p\n", f->metadata);
			return &f->metadata->raw;
		}
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
		frag = jffs2_lookup_node_frag(&f->fragtree, je32_to_cpu(node->i.offset));
		BUG_ON(!frag);
		/* Find a frag which refers to the full_dnode we want to modify */
		while (!frag->node || frag->node->raw != raw) {
			frag = frag_next(frag);
			BUG_ON(!frag);
		}
		dbg_noderef("Will replace ->raw in full_dnode at %p\n", frag->node);
		return &frag->node->raw;

	case JFFS2_NODETYPE_DIRENT:
		for (fd = f->dents; fd; fd = fd->next) {
			if (fd->raw == raw) {
				dbg_noderef("Will replace ->raw in full_dirent at %p\n", fd);
				return &fd->raw;
			}
		}
		BUG();
220

221 222 223 224 225 226 227 228
	default:
		dbg_noderef("Don't care about replacing raw for nodetype %x\n",
			    je16_to_cpu(node->u.nodetype));
		break;
	}
	return NULL;
}

229 230 231 232 233 234 235 236
#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
static int jffs2_verify_write(struct jffs2_sb_info *c, unsigned char *buf,
			      uint32_t ofs)
{
	int ret;
	size_t retlen;
	char *eccstr;

237
	ret = mtd_read(c->mtd, ofs, c->wbuf_pagesize, &retlen, c->wbuf_verify);
238
	if (ret && ret != -EUCLEAN && ret != -EBADMSG) {
239 240
		pr_warn("%s(): Read back of page at %08x failed: %d\n",
			__func__, c->wbuf_ofs, ret);
241 242
		return ret;
	} else if (retlen != c->wbuf_pagesize) {
243 244
		pr_warn("%s(): Read back of page at %08x gave short read: %zd not %d\n",
			__func__, ofs, retlen, c->wbuf_pagesize);
245 246 247 248 249 250 251 252 253 254 255 256
		return -EIO;
	}
	if (!memcmp(buf, c->wbuf_verify, c->wbuf_pagesize))
		return 0;

	if (ret == -EUCLEAN)
		eccstr = "corrected";
	else if (ret == -EBADMSG)
		eccstr = "correction failed";
	else
		eccstr = "OK or unused";

257 258
	pr_warn("Write verify error (ECC %s) at %08x. Wrote:\n",
		eccstr, c->wbuf_ofs);
259 260 261
	print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1,
		       c->wbuf, c->wbuf_pagesize, 0);

262
	pr_warn("Read back:\n");
263 264 265 266 267 268 269 270 271
	print_hex_dump(KERN_WARNING, "", DUMP_PREFIX_OFFSET, 16, 1,
		       c->wbuf_verify, c->wbuf_pagesize, 0);

	return -EIO;
}
#else
#define jffs2_verify_write(c,b,o) (0)
#endif

Linus Torvalds's avatar
Linus Torvalds committed
272 273 274 275 276 277
/* Recover from failure to write wbuf. Recover the nodes up to the
 * wbuf, not the one which we were starting to try to write. */

static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
{
	struct jffs2_eraseblock *jeb, *new_jeb;
278
	struct jffs2_raw_node_ref *raw, *next, *first_raw = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
279 280
	size_t retlen;
	int ret;
281
	int nr_refile = 0;
Linus Torvalds's avatar
Linus Torvalds committed
282 283 284
	unsigned char *buf;
	uint32_t start, end, ofs, len;

285 286
	jeb = &c->blocks[c->wbuf_ofs / c->sector_size];

Linus Torvalds's avatar
Linus Torvalds committed
287
	spin_lock(&c->erase_completion_lock);
288 289 290 291
	if (c->wbuf_ofs % c->mtd->erasesize)
		jffs2_block_refile(c, jeb, REFILE_NOTEMPTY);
	else
		jffs2_block_refile(c, jeb, REFILE_ANYWAY);
292 293 294
	spin_unlock(&c->erase_completion_lock);

	BUG_ON(!ref_obsolete(jeb->last_node));
Linus Torvalds's avatar
Linus Torvalds committed
295 296 297

	/* Find the first node to be recovered, by skipping over every
	   node which ends before the wbuf starts, or which is obsolete. */
298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
	for (next = raw = jeb->first_node; next; raw = next) {
		next = ref_next(raw);

		if (ref_obsolete(raw) || 
		    (next && ref_offset(next) <= c->wbuf_ofs)) {
			dbg_noderef("Skipping node at 0x%08x(%d)-0x%08x which is either before 0x%08x or obsolete\n",
				    ref_offset(raw), ref_flags(raw),
				    (ref_offset(raw) + ref_totlen(c, jeb, raw)),
				    c->wbuf_ofs);
			continue;
		}
		dbg_noderef("First node to be recovered is at 0x%08x(%d)-0x%08x\n",
			    ref_offset(raw), ref_flags(raw),
			    (ref_offset(raw) + ref_totlen(c, jeb, raw)));

		first_raw = raw;
		break;
	}

	if (!first_raw) {
Linus Torvalds's avatar
Linus Torvalds committed
318
		/* All nodes were obsolete. Nothing to recover. */
319
		jffs2_dbg(1, "No non-obsolete nodes to be recovered. Just filing block bad\n");
320
		c->wbuf_len = 0;
Linus Torvalds's avatar
Linus Torvalds committed
321 322 323
		return;
	}

324 325 326
	start = ref_offset(first_raw);
	end = ref_offset(jeb->last_node);
	nr_refile = 1;
Linus Torvalds's avatar
Linus Torvalds committed
327

328 329 330
	/* Count the number of refs which need to be copied */
	while ((raw = ref_next(raw)) != jeb->last_node)
		nr_refile++;
Linus Torvalds's avatar
Linus Torvalds committed
331

332 333
	dbg_noderef("wbuf recover %08x-%08x (%d bytes in %d nodes)\n",
		    start, end, end - start, nr_refile);
Linus Torvalds's avatar
Linus Torvalds committed
334 335 336 337 338 339 340 341

	buf = NULL;
	if (start < c->wbuf_ofs) {
		/* First affected node was already partially written.
		 * Attempt to reread the old data into our buffer. */

		buf = kmalloc(end - start, GFP_KERNEL);
		if (!buf) {
342
			pr_crit("Malloc failure in wbuf recovery. Data loss ensues.\n");
Linus Torvalds's avatar
Linus Torvalds committed
343 344 345 346 347

			goto read_failed;
		}

		/* Do the read... */
348 349
		ret = mtd_read(c->mtd, start, c->wbuf_ofs - start, &retlen,
			       buf);
350

351 352 353
		/* ECC recovered ? */
		if ((ret == -EUCLEAN || ret == -EBADMSG) &&
		    (retlen == c->wbuf_ofs - start))
Linus Torvalds's avatar
Linus Torvalds committed
354
			ret = 0;
355

Linus Torvalds's avatar
Linus Torvalds committed
356
		if (ret || retlen != c->wbuf_ofs - start) {
357
			pr_crit("Old data are already lost in wbuf recovery. Data loss ensues.\n");
Linus Torvalds's avatar
Linus Torvalds committed
358 359 360 361

			kfree(buf);
			buf = NULL;
		read_failed:
362 363 364 365 366 367 368
			first_raw = ref_next(first_raw);
			nr_refile--;
			while (first_raw && ref_obsolete(first_raw)) {
				first_raw = ref_next(first_raw);
				nr_refile--;
			}

Linus Torvalds's avatar
Linus Torvalds committed
369
			/* If this was the only node to be recovered, give up */
370 371
			if (!first_raw) {
				c->wbuf_len = 0;
Linus Torvalds's avatar
Linus Torvalds committed
372
				return;
373
			}
Linus Torvalds's avatar
Linus Torvalds committed
374 375

			/* It wasn't. Go on and try to recover nodes complete in the wbuf */
376 377 378 379
			start = ref_offset(first_raw);
			dbg_noderef("wbuf now recover %08x-%08x (%d bytes in %d nodes)\n",
				    start, end, end - start, nr_refile);

Linus Torvalds's avatar
Linus Torvalds committed
380 381 382 383 384 385 386 387 388
		} else {
			/* Read succeeded. Copy the remaining data from the wbuf */
			memcpy(buf + (c->wbuf_ofs - start), c->wbuf, end - c->wbuf_ofs);
		}
	}
	/* OK... we're to rewrite (end-start) bytes of data from first_raw onwards.
	   Either 'buf' contains the data, or we find it in the wbuf */

	/* ... and get an allocation of space from a shiny new block instead */
389
	ret = jffs2_reserve_space_gc(c, end-start, &len, JFFS2_SUMMARY_NOSUM_SIZE);
Linus Torvalds's avatar
Linus Torvalds committed
390
	if (ret) {
391
		pr_warn("Failed to allocate space for wbuf recovery. Data loss ensues.\n");
392
		kfree(buf);
Linus Torvalds's avatar
Linus Torvalds committed
393 394
		return;
	}
395

396 397 398
	/* The summary is not recovered, so it must be disabled for this erase block */
	jffs2_sum_disable_collecting(c->summary);

399 400
	ret = jffs2_prealloc_raw_node_refs(c, c->nextblock, nr_refile);
	if (ret) {
401
		pr_warn("Failed to allocate node refs for wbuf recovery. Data loss ensues.\n");
402 403 404 405
		kfree(buf);
		return;
	}

406 407
	ofs = write_ofs(c);

Linus Torvalds's avatar
Linus Torvalds committed
408
	if (end-start >= c->wbuf_pagesize) {
409
		/* Need to do another write immediately, but it's possible
410
		   that this is just because the wbuf itself is completely
411 412
		   full, and there's nothing earlier read back from the
		   flash. Hence 'buf' isn't necessarily what we're writing
413
		   from. */
414
		unsigned char *rewrite_buf = buf?:c->wbuf;
Linus Torvalds's avatar
Linus Torvalds committed
415 416
		uint32_t towrite = (end-start) - ((end-start)%c->wbuf_pagesize);

417 418
		jffs2_dbg(1, "Write 0x%x bytes at 0x%08x in wbuf recover\n",
			  towrite, ofs);
419

Linus Torvalds's avatar
Linus Torvalds committed
420 421 422
#ifdef BREAKMEHEADER
		static int breakme;
		if (breakme++ == 20) {
423
			pr_notice("Faking write error at 0x%08x\n", ofs);
Linus Torvalds's avatar
Linus Torvalds committed
424
			breakme = 0;
425
			mtd_write(c->mtd, ofs, towrite, &retlen, brokenbuf);
Linus Torvalds's avatar
Linus Torvalds committed
426 427 428
			ret = -EIO;
		} else
#endif
429 430
			ret = mtd_write(c->mtd, ofs, towrite, &retlen,
					rewrite_buf);
Linus Torvalds's avatar
Linus Torvalds committed
431

432
		if (ret || retlen != towrite || jffs2_verify_write(c, rewrite_buf, ofs)) {
Linus Torvalds's avatar
Linus Torvalds committed
433
			/* Argh. We tried. Really we did. */
434
			pr_crit("Recovery of wbuf failed due to a second write error\n");
435
			kfree(buf);
Linus Torvalds's avatar
Linus Torvalds committed
436

437
			if (retlen)
438
				jffs2_add_physical_node_ref(c, ofs | REF_OBSOLETE, ref_totlen(c, jeb, first_raw), NULL);
Linus Torvalds's avatar
Linus Torvalds committed
439 440 441

			return;
		}
442
		pr_notice("Recovery of wbuf succeeded to %08x\n", ofs);
Linus Torvalds's avatar
Linus Torvalds committed
443 444 445

		c->wbuf_len = (end - start) - towrite;
		c->wbuf_ofs = ofs + towrite;
446
		memmove(c->wbuf, rewrite_buf + towrite, c->wbuf_len);
Linus Torvalds's avatar
Linus Torvalds committed
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462
		/* Don't muck about with c->wbuf_inodes. False positives are harmless. */
	} else {
		/* OK, now we're left with the dregs in whichever buffer we're using */
		if (buf) {
			memcpy(c->wbuf, buf, end-start);
		} else {
			memmove(c->wbuf, c->wbuf + (start - c->wbuf_ofs), end - start);
		}
		c->wbuf_ofs = ofs;
		c->wbuf_len = end - start;
	}

	/* Now sort out the jffs2_raw_node_refs, moving them from the old to the next block */
	new_jeb = &c->blocks[ofs / c->sector_size];

	spin_lock(&c->erase_completion_lock);
463 464 465 466 467 468
	for (raw = first_raw; raw != jeb->last_node; raw = ref_next(raw)) {
		uint32_t rawlen = ref_totlen(c, jeb, raw);
		struct jffs2_inode_cache *ic;
		struct jffs2_raw_node_ref *new_ref;
		struct jffs2_raw_node_ref **adjust_ref = NULL;
		struct jffs2_inode_info *f = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
469

470 471
		jffs2_dbg(1, "Refiling block of %08x at %08x(%d) to %08x\n",
			  rawlen, ref_offset(raw), ref_flags(raw), ofs);
472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499

		ic = jffs2_raw_ref_to_ic(raw);

		/* Ick. This XATTR mess should be fixed shortly... */
		if (ic && ic->class == RAWNODE_CLASS_XATTR_DATUM) {
			struct jffs2_xattr_datum *xd = (void *)ic;
			BUG_ON(xd->node != raw);
			adjust_ref = &xd->node;
			raw->next_in_ino = NULL;
			ic = NULL;
		} else if (ic && ic->class == RAWNODE_CLASS_XATTR_REF) {
			struct jffs2_xattr_datum *xr = (void *)ic;
			BUG_ON(xr->node != raw);
			adjust_ref = &xr->node;
			raw->next_in_ino = NULL;
			ic = NULL;
		} else if (ic && ic->class == RAWNODE_CLASS_INODE_CACHE) {
			struct jffs2_raw_node_ref **p = &ic->nodes;

			/* Remove the old node from the per-inode list */
			while (*p && *p != (void *)ic) {
				if (*p == raw) {
					(*p) = (raw->next_in_ino);
					raw->next_in_ino = NULL;
					break;
				}
				p = &((*p)->next_in_ino);
			}
Linus Torvalds's avatar
Linus Torvalds committed
500

501 502 503 504
			if (ic->state == INO_STATE_PRESENT && !ref_obsolete(raw)) {
				/* If it's an in-core inode, then we have to adjust any
				   full_dirent or full_dnode structure to point to the
				   new version instead of the old */
505
				f = jffs2_gc_fetch_inode(c, ic->ino, !ic->pino_nlink);
506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536
				if (IS_ERR(f)) {
					/* Should never happen; it _must_ be present */
					JFFS2_ERROR("Failed to iget() ino #%u, err %ld\n",
						    ic->ino, PTR_ERR(f));
					BUG();
				}
				/* We don't lock f->sem. There's a number of ways we could
				   end up in here with it already being locked, and nobody's
				   going to modify it on us anyway because we hold the
				   alloc_sem. We're only changing one ->raw pointer too,
				   which we can get away with without upsetting readers. */
				adjust_ref = jffs2_incore_replace_raw(c, f, raw,
								      (void *)(buf?:c->wbuf) + (ref_offset(raw) - start));
			} else if (unlikely(ic->state != INO_STATE_PRESENT &&
					    ic->state != INO_STATE_CHECKEDABSENT &&
					    ic->state != INO_STATE_GC)) {
				JFFS2_ERROR("Inode #%u is in strange state %d!\n", ic->ino, ic->state);
				BUG();
			}
		}

		new_ref = jffs2_link_node_ref(c, new_jeb, ofs | ref_flags(raw), rawlen, ic);

		if (adjust_ref) {
			BUG_ON(*adjust_ref != raw);
			*adjust_ref = new_ref;
		}
		if (f)
			jffs2_gc_release_inode(c, f);

		if (!ref_obsolete(raw)) {
Linus Torvalds's avatar
Linus Torvalds committed
537 538 539
			jeb->dirty_size += rawlen;
			jeb->used_size  -= rawlen;
			c->dirty_size += rawlen;
540 541 542
			c->used_size -= rawlen;
			raw->flash_offset = ref_offset(raw) | REF_OBSOLETE;
			BUG_ON(raw->next_in_ino);
Linus Torvalds's avatar
Linus Torvalds committed
543 544 545 546
		}
		ofs += rawlen;
	}

547 548
	kfree(buf);

Linus Torvalds's avatar
Linus Torvalds committed
549
	/* Fix up the original jeb now it's on the bad_list */
550
	if (first_raw == jeb->first_node) {
551 552
		jffs2_dbg(1, "Failing block at %08x is now empty. Moving to erase_pending_list\n",
			  jeb->offset);
553
		list_move(&jeb->list, &c->erase_pending_list);
Linus Torvalds's avatar
Linus Torvalds committed
554
		c->nr_erasing_blocks++;
555
		jffs2_garbage_collect_trigger(c);
Linus Torvalds's avatar
Linus Torvalds committed
556 557
	}

558
	jffs2_dbg_acct_sanity_check_nolock(c, jeb);
559
	jffs2_dbg_acct_paranoia_check_nolock(c, jeb);
Linus Torvalds's avatar
Linus Torvalds committed
560

561
	jffs2_dbg_acct_sanity_check_nolock(c, new_jeb);
562
	jffs2_dbg_acct_paranoia_check_nolock(c, new_jeb);
Linus Torvalds's avatar
Linus Torvalds committed
563 564 565

	spin_unlock(&c->erase_completion_lock);

566 567
	jffs2_dbg(1, "wbuf recovery completed OK. wbuf_ofs 0x%08x, len 0x%x\n",
		  c->wbuf_ofs, c->wbuf_len);
568

Linus Torvalds's avatar
Linus Torvalds committed
569 570 571 572 573 574 575 576 577 578 579 580 581
}

/* Meaning of pad argument:
   0: Do not pad. Probably pointless - we only ever use this when we can't pad anyway.
   1: Pad, do not adjust nextblock free_size
   2: Pad, adjust nextblock free_size
*/
#define NOPAD		0
#define PAD_NOACCOUNT	1
#define PAD_ACCOUNTING	2

static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
{
582
	struct jffs2_eraseblock *wbuf_jeb;
Linus Torvalds's avatar
Linus Torvalds committed
583 584 585
	int ret;
	size_t retlen;

586
	/* Nothing to do if not write-buffering the flash. In particular, we shouldn't
Linus Torvalds's avatar
Linus Torvalds committed
587
	   del_timer() the timer we never initialised. */
588
	if (!jffs2_is_writebuffered(c))
Linus Torvalds's avatar
Linus Torvalds committed
589 590
		return 0;

591
	if (!mutex_is_locked(&c->alloc_sem)) {
592
		pr_crit("jffs2_flush_wbuf() called with alloc_sem not locked!\n");
Linus Torvalds's avatar
Linus Torvalds committed
593 594 595
		BUG();
	}

596
	if (!c->wbuf_len)	/* already checked c->wbuf above */
Linus Torvalds's avatar
Linus Torvalds committed
597 598
		return 0;

599 600
	wbuf_jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
	if (jffs2_prealloc_raw_node_refs(c, wbuf_jeb, c->nextblock->allocated_refs + 1))
601 602
		return -ENOMEM;

Linus Torvalds's avatar
Linus Torvalds committed
603 604 605 606
	/* claim remaining space on the page
	   this happens, if we have a change to a new block,
	   or if fsync forces us to flush the writebuffer.
	   if we have a switch to next page, we will not have
607
	   enough remaining space for this.
Linus Torvalds's avatar
Linus Torvalds committed
608
	*/
609
	if (pad ) {
Linus Torvalds's avatar
Linus Torvalds committed
610 611 612 613 614
		c->wbuf_len = PAD(c->wbuf_len);

		/* Pad with JFFS2_DIRTY_BITMASK initially.  this helps out ECC'd NOR
		   with 8 byte page size */
		memset(c->wbuf + c->wbuf_len, 0, c->wbuf_pagesize - c->wbuf_len);
615

Linus Torvalds's avatar
Linus Torvalds committed
616 617 618 619 620 621 622 623 624 625
		if ( c->wbuf_len + sizeof(struct jffs2_unknown_node) < c->wbuf_pagesize) {
			struct jffs2_unknown_node *padnode = (void *)(c->wbuf + c->wbuf_len);
			padnode->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
			padnode->nodetype = cpu_to_je16(JFFS2_NODETYPE_PADDING);
			padnode->totlen = cpu_to_je32(c->wbuf_pagesize - c->wbuf_len);
			padnode->hdr_crc = cpu_to_je32(crc32(0, padnode, sizeof(*padnode)-4));
		}
	}
	/* else jffs2_flash_writev has actually filled in the rest of the
	   buffer for us, and will deal with the node refs etc. later. */
626

Linus Torvalds's avatar
Linus Torvalds committed
627 628 629
#ifdef BREAKME
	static int breakme;
	if (breakme++ == 20) {
630
		pr_notice("Faking write error at 0x%08x\n", c->wbuf_ofs);
Linus Torvalds's avatar
Linus Torvalds committed
631
		breakme = 0;
632 633
		mtd_write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize, &retlen,
			  brokenbuf);
Linus Torvalds's avatar
Linus Torvalds committed
634
		ret = -EIO;
635
	} else
Linus Torvalds's avatar
Linus Torvalds committed
636
#endif
637

638 639
		ret = mtd_write(c->mtd, c->wbuf_ofs, c->wbuf_pagesize,
				&retlen, c->wbuf);
Linus Torvalds's avatar
Linus Torvalds committed
640

641
	if (ret) {
642
		pr_warn("jffs2_flush_wbuf(): Write failed with %d\n", ret);
643 644
		goto wfail;
	} else if (retlen != c->wbuf_pagesize) {
645 646
		pr_warn("jffs2_flush_wbuf(): Write was short: %zd instead of %d\n",
			retlen, c->wbuf_pagesize);
647 648 649 650
		ret = -EIO;
		goto wfail;
	} else if ((ret = jffs2_verify_write(c, c->wbuf, c->wbuf_ofs))) {
	wfail:
Linus Torvalds's avatar
Linus Torvalds committed
651 652 653 654 655 656
		jffs2_wbuf_recover(c);

		return ret;
	}

	/* Adjust free size of the block if we padded. */
657
	if (pad) {
658
		uint32_t waste = c->wbuf_pagesize - c->wbuf_len;
Linus Torvalds's avatar
Linus Torvalds committed
659

660 661 662
		jffs2_dbg(1, "jffs2_flush_wbuf() adjusting free_size of %sblock at %08x\n",
			  (wbuf_jeb == c->nextblock) ? "next" : "",
			  wbuf_jeb->offset);
Linus Torvalds's avatar
Linus Torvalds committed
663

664
		/* wbuf_pagesize - wbuf_len is the amount of space that's to be
Linus Torvalds's avatar
Linus Torvalds committed
665 666
		   padded. If there is less free space in the block than that,
		   something screwed up */
667
		if (wbuf_jeb->free_size < waste) {
668 669 670 671
			pr_crit("jffs2_flush_wbuf(): Accounting error. wbuf at 0x%08x has 0x%03x bytes, 0x%03x left.\n",
				c->wbuf_ofs, c->wbuf_len, waste);
			pr_crit("jffs2_flush_wbuf(): But free_size for block at 0x%08x is only 0x%08x\n",
				wbuf_jeb->offset, wbuf_jeb->free_size);
Linus Torvalds's avatar
Linus Torvalds committed
672 673
			BUG();
		}
674 675 676

		spin_lock(&c->erase_completion_lock);

677
		jffs2_link_node_ref(c, wbuf_jeb, (c->wbuf_ofs + c->wbuf_len) | REF_OBSOLETE, waste, NULL);
678
		/* FIXME: that made it count as dirty. Convert to wasted */
679
		wbuf_jeb->dirty_size -= waste;
680
		c->dirty_size -= waste;
681
		wbuf_jeb->wasted_size += waste;
682 683 684
		c->wasted_size += waste;
	} else
		spin_lock(&c->erase_completion_lock);
Linus Torvalds's avatar
Linus Torvalds committed
685 686 687 688 689 690 691 692

	/* Stick any now-obsoleted blocks on the erase_pending_list */
	jffs2_refile_wbuf_blocks(c);
	jffs2_clear_wbuf_ino_list(c);
	spin_unlock(&c->erase_completion_lock);

	memset(c->wbuf,0xff,c->wbuf_pagesize);
	/* adjust write buffer offset, else we get a non contiguous write bug */
693
	c->wbuf_ofs += c->wbuf_pagesize;
Linus Torvalds's avatar
Linus Torvalds committed
694 695 696 697
	c->wbuf_len = 0;
	return 0;
}

698
/* Trigger garbage collection to flush the write-buffer.
Linus Torvalds's avatar
Linus Torvalds committed
699
   If ino arg is zero, do it if _any_ real (i.e. not GC) writes are
700
   outstanding. If ino arg non-zero, do it only if a write for the
Linus Torvalds's avatar
Linus Torvalds committed
701 702 703 704 705 706 707
   given inode is outstanding. */
int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino)
{
	uint32_t old_wbuf_ofs;
	uint32_t old_wbuf_len;
	int ret = 0;

708
	jffs2_dbg(1, "jffs2_flush_wbuf_gc() called for ino #%u...\n", ino);
Linus Torvalds's avatar
Linus Torvalds committed
709

710 711 712
	if (!c->wbuf)
		return 0;

713
	mutex_lock(&c->alloc_sem);
Linus Torvalds's avatar
Linus Torvalds committed
714
	if (!jffs2_wbuf_pending_for_ino(c, ino)) {
715
		jffs2_dbg(1, "Ino #%d not pending in wbuf. Returning\n", ino);
716
		mutex_unlock(&c->alloc_sem);
Linus Torvalds's avatar
Linus Torvalds committed
717 718 719 720 721 722 723 724
		return 0;
	}

	old_wbuf_ofs = c->wbuf_ofs;
	old_wbuf_len = c->wbuf_len;

	if (c->unchecked_size) {
		/* GC won't make any progress for a while */
725 726
		jffs2_dbg(1, "%s(): padding. Not finished checking\n",
			  __func__);
Linus Torvalds's avatar
Linus Torvalds committed
727 728
		down_write(&c->wbuf_sem);
		ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING);
729 730 731 732
		/* retry flushing wbuf in case jffs2_wbuf_recover
		   left some data in the wbuf */
		if (ret)
			ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING);
Linus Torvalds's avatar
Linus Torvalds committed
733 734 735 736
		up_write(&c->wbuf_sem);
	} else while (old_wbuf_len &&
		      old_wbuf_ofs == c->wbuf_ofs) {

737
		mutex_unlock(&c->alloc_sem);
Linus Torvalds's avatar
Linus Torvalds committed
738

739
		jffs2_dbg(1, "%s(): calls gc pass\n", __func__);
Linus Torvalds's avatar
Linus Torvalds committed
740 741 742 743

		ret = jffs2_garbage_collect_pass(c);
		if (ret) {
			/* GC failed. Flush it with padding instead */
744
			mutex_lock(&c->alloc_sem);
Linus Torvalds's avatar
Linus Torvalds committed
745 746
			down_write(&c->wbuf_sem);
			ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING);
747 748 749 750
			/* retry flushing wbuf in case jffs2_wbuf_recover
			   left some data in the wbuf */
			if (ret)
				ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING);
Linus Torvalds's avatar
Linus Torvalds committed
751 752 753
			up_write(&c->wbuf_sem);
			break;
		}
754
		mutex_lock(&c->alloc_sem);
Linus Torvalds's avatar
Linus Torvalds committed
755 756
	}

757
	jffs2_dbg(1, "%s(): ends...\n", __func__);
Linus Torvalds's avatar
Linus Torvalds committed
758

759
	mutex_unlock(&c->alloc_sem);
Linus Torvalds's avatar
Linus Torvalds committed
760 761 762 763 764 765 766 767
	return ret;
}

/* Pad write-buffer to end and write it, wasting space. */
int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c)
{
	int ret;

768 769 770
	if (!c->wbuf)
		return 0;

Linus Torvalds's avatar
Linus Torvalds committed
771 772
	down_write(&c->wbuf_sem);
	ret = __jffs2_flush_wbuf(c, PAD_NOACCOUNT);
773 774 775
	/* retry - maybe wbuf recover left some data in wbuf. */
	if (ret)
		ret = __jffs2_flush_wbuf(c, PAD_NOACCOUNT);
Linus Torvalds's avatar
Linus Torvalds committed
776 777 778 779
	up_write(&c->wbuf_sem);

	return ret;
}
780 781 782

static size_t jffs2_fill_wbuf(struct jffs2_sb_info *c, const uint8_t *buf,
			      size_t len)
Linus Torvalds's avatar
Linus Torvalds committed
783
{
784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799
	if (len && !c->wbuf_len && (len >= c->wbuf_pagesize))
		return 0;

	if (len > (c->wbuf_pagesize - c->wbuf_len))
		len = c->wbuf_pagesize - c->wbuf_len;
	memcpy(c->wbuf + c->wbuf_len, buf, len);
	c->wbuf_len += (uint32_t) len;
	return len;
}

int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs,
		       unsigned long count, loff_t to, size_t *retlen,
		       uint32_t ino)
{
	struct jffs2_eraseblock *jeb;
	size_t wbuf_retlen, donelen = 0;
Linus Torvalds's avatar
Linus Torvalds committed
800
	uint32_t outvec_to = to;
801
	int ret, invec;
Linus Torvalds's avatar
Linus Torvalds committed
802

803
	/* If not writebuffered flash, don't bother */
804
	if (!jffs2_is_writebuffered(c))
Linus Torvalds's avatar
Linus Torvalds committed
805
		return jffs2_flash_direct_writev(c, invecs, count, to, retlen);
806

Linus Torvalds's avatar
Linus Torvalds committed
807 808 809 810 811
	down_write(&c->wbuf_sem);

	/* If wbuf_ofs is not initialized, set it to target address */
	if (c->wbuf_ofs == 0xFFFFFFFF) {
		c->wbuf_ofs = PAGE_DIV(to);
812
		c->wbuf_len = PAGE_MOD(to);
Linus Torvalds's avatar
Linus Torvalds committed
813 814 815
		memset(c->wbuf,0xff,c->wbuf_pagesize);
	}

816 817 818 819 820 821 822
	/*
	 * Sanity checks on target address.  It's permitted to write
	 * at PAD(c->wbuf_len+c->wbuf_ofs), and it's permitted to
	 * write at the beginning of a new erase block. Anything else,
	 * and you die.  New block starts at xxx000c (0-b = block
	 * header)
	 */
823
	if (SECTOR_ADDR(to) != SECTOR_ADDR(c->wbuf_ofs)) {
Linus Torvalds's avatar
Linus Torvalds committed
824 825
		/* It's a write to a new block */
		if (c->wbuf_len) {
826 827
			jffs2_dbg(1, "%s(): to 0x%lx causes flush of wbuf at 0x%08x\n",
				  __func__, (unsigned long)to, c->wbuf_ofs);
Linus Torvalds's avatar
Linus Torvalds committed
828
			ret = __jffs2_flush_wbuf(c, PAD_NOACCOUNT);
829 830
			if (ret)
				goto outerr;
Linus Torvalds's avatar
Linus Torvalds committed
831 832 833
		}
		/* set pointer to new block */
		c->wbuf_ofs = PAGE_DIV(to);
834 835
		c->wbuf_len = PAGE_MOD(to);
	}
Linus Torvalds's avatar
Linus Torvalds committed
836 837 838

	if (to != PAD(c->wbuf_ofs + c->wbuf_len)) {
		/* We're not writing immediately after the writebuffer. Bad. */
839 840
		pr_crit("%s(): Non-contiguous write to %08lx\n",
			__func__, (unsigned long)to);
Linus Torvalds's avatar
Linus Torvalds committed
841
		if (c->wbuf_len)
842 843
			pr_crit("wbuf was previously %08x-%08x\n",
				c->wbuf_ofs, c->wbuf_ofs + c->wbuf_len);
Linus Torvalds's avatar
Linus Torvalds committed
844 845 846
		BUG();
	}

847 848 849 850 851 852 853 854 855
	/* adjust alignment offset */
	if (c->wbuf_len != PAGE_MOD(to)) {
		c->wbuf_len = PAGE_MOD(to);
		/* take care of alignment to next page */
		if (!c->wbuf_len) {
			c->wbuf_len = c->wbuf_pagesize;
			ret = __jffs2_flush_wbuf(c, NOPAD);
			if (ret)
				goto outerr;
Linus Torvalds's avatar
Linus Torvalds committed
856 857 858
		}
	}

859 860 861
	for (invec = 0; invec < count; invec++) {
		int vlen = invecs[invec].iov_len;
		uint8_t *v = invecs[invec].iov_base;
862

863
		wbuf_retlen = jffs2_fill_wbuf(c, v, vlen);
864

865 866 867 868
		if (c->wbuf_len == c->wbuf_pagesize) {
			ret = __jffs2_flush_wbuf(c, NOPAD);
			if (ret)
				goto outerr;
Linus Torvalds's avatar
Linus Torvalds committed
869
		}
870 871
		vlen -= wbuf_retlen;
		outvec_to += wbuf_retlen;
Linus Torvalds's avatar
Linus Torvalds committed
872
		donelen += wbuf_retlen;
873 874 875
		v += wbuf_retlen;

		if (vlen >= c->wbuf_pagesize) {
876 877
			ret = mtd_write(c->mtd, outvec_to, PAGE_DIV(vlen),
					&wbuf_retlen, v);
878 879 880 881 882 883 884 885
			if (ret < 0 || wbuf_retlen != PAGE_DIV(vlen))
				goto outfile;

			vlen -= wbuf_retlen;
			outvec_to += wbuf_retlen;
			c->wbuf_ofs = outvec_to;
			donelen += wbuf_retlen;
			v += wbuf_retlen;
Linus Torvalds's avatar
Linus Torvalds committed
886 887
		}

888 889 890 891 892 893
		wbuf_retlen = jffs2_fill_wbuf(c, v, vlen);
		if (c->wbuf_len == c->wbuf_pagesize) {
			ret = __jffs2_flush_wbuf(c, NOPAD);
			if (ret)
				goto outerr;
		}
Linus Torvalds's avatar
Linus Torvalds committed
894

895 896
		outvec_to += wbuf_retlen;
		donelen += wbuf_retlen;
Linus Torvalds's avatar
Linus Torvalds committed
897 898
	}

899 900 901 902
	/*
	 * If there's a remainder in the wbuf and it's a non-GC write,
	 * remember that the wbuf affects this ino
	 */
Linus Torvalds's avatar
Linus Torvalds committed
903 904
	*retlen = donelen;

905 906 907 908 909 910
	if (jffs2_sum_active()) {
		int res = jffs2_sum_add_kvec(c, invecs, count, (uint32_t) to);
		if (res)
			return res;
	}

Linus Torvalds's avatar
Linus Torvalds committed
911 912 913 914
	if (c->wbuf_len && ino)
		jffs2_wbuf_dirties_inode(c, ino);

	ret = 0;
915 916 917 918 919 920 921 922 923 924 925 926 927 928 929
	up_write(&c->wbuf_sem);
	return ret;

outfile:
	/*
	 * At this point we have no problem, c->wbuf is empty. However
	 * refile nextblock to avoid writing again to same address.
	 */

	spin_lock(&c->erase_completion_lock);

	jeb = &c->blocks[outvec_to / c->sector_size];
	jffs2_block_refile(c, jeb, REFILE_ANYWAY);

	spin_unlock(&c->erase_completion_lock);
930

931 932
outerr:
	*retlen = 0;
Linus Torvalds's avatar
Linus Torvalds committed
933 934 935 936 937 938 939 940
	up_write(&c->wbuf_sem);
	return ret;
}

/*
 *	This is the entry for flash write.
 *	Check, if we work on NAND FLASH, if so build an kvec and write it via vritev
*/
941 942
int jffs2_flash_write(struct jffs2_sb_info *c, loff_t ofs, size_t len,
		      size_t *retlen, const u_char *buf)
Linus Torvalds's avatar
Linus Torvalds committed
943 944 945
{
	struct kvec vecs[1];

946
	if (!jffs2_is_writebuffered(c))
947
		return jffs2_flash_direct_write(c, ofs, len, retlen, buf);
Linus Torvalds's avatar
Linus Torvalds committed
948 949 950 951 952 953 954 955 956 957 958 959 960 961

	vecs[0].iov_base = (unsigned char *) buf;
	vecs[0].iov_len = len;
	return jffs2_flash_writev(c, vecs, 1, ofs, retlen, 0);
}

/*
	Handle readback from writebuffer and ECC failure return
*/
int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *retlen, u_char *buf)
{
	loff_t	orbf = 0, owbf = 0, lwbf = 0;
	int	ret;

962
	if (!jffs2_is_writebuffered(c))
963
		return mtd_read(c->mtd, ofs, len, retlen, buf);
Linus Torvalds's avatar
Linus Torvalds committed
964

965
	/* Read flash */
966
	down_read(&c->wbuf_sem);
967
	ret = mtd_read(c->mtd, ofs, len, retlen, buf);
968

969 970
	if ( (ret == -EBADMSG || ret == -EUCLEAN) && (*retlen == len) ) {
		if (ret == -EBADMSG)
971 972
			pr_warn("mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n",
				len, ofs);
973
		/*
974 975 976 977 978 979 980
		 * We have the raw data without ECC correction in the buffer,
		 * maybe we are lucky and all data or parts are correct. We
		 * check the node.  If data are corrupted node check will sort
		 * it out.  We keep this block, it will fail on write or erase
		 * and the we mark it bad. Or should we do that now? But we
		 * should give him a chance.  Maybe we had a system crash or
		 * power loss before the ecc write or a erase was completed.
981 982
		 * So we return success. :)
		 */
983
		ret = 0;
984
	}
985

Linus Torvalds's avatar
Linus Torvalds committed
986 987
	/* if no writebuffer available or write buffer empty, return */
	if (!c->wbuf_pagesize || !c->wbuf_len)
988
		goto exit;
Linus Torvalds's avatar
Linus Torvalds committed
989 990

	/* if we read in a different block, return */
991
	if (SECTOR_ADDR(ofs) != SECTOR_ADDR(c->wbuf_ofs))
992
		goto exit;
Linus Torvalds's avatar
Linus Torvalds committed
993 994 995 996 997 998

	if (ofs >= c->wbuf_ofs) {
		owbf = (ofs - c->wbuf_ofs);	/* offset in write buffer */
		if (owbf > c->wbuf_len)		/* is read beyond write buffer ? */
			goto exit;
		lwbf = c->wbuf_len - owbf;	/* number of bytes to copy */
999
		if (lwbf > len)
Linus Torvalds's avatar
Linus Torvalds committed
1000
			lwbf = len;
1001
	} else {
Linus Torvalds's avatar
Linus Torvalds committed
1002 1003 1004
		orbf = (c->wbuf_ofs - ofs);	/* offset in read buffer */
		if (orbf > len)			/* is write beyond write buffer ? */
			goto exit;
1005
		lwbf = len - orbf;		/* number of bytes to copy */
1006
		if (lwbf > c->wbuf_len)
Linus Torvalds's avatar
Linus Torvalds committed
1007
			lwbf = c->wbuf_len;
1008
	}
Linus Torvalds's avatar
Linus Torvalds committed
1009 1010 1011 1012 1013 1014 1015 1016
	if (lwbf > 0)
		memcpy(buf+orbf,c->wbuf+owbf,lwbf);

exit:
	up_read(&c->wbuf_sem);
	return ret;
}

1017 1018
#define NR_OOB_SCAN_PAGES 4

1019 1020
/* For historical reasons we use only 8 bytes for OOB clean marker */
#define OOB_CM_SIZE 8
1021 1022 1023

static const struct jffs2_unknown_node oob_cleanmarker =
{
1024 1025 1026
	.magic = constant_cpu_to_je16(JFFS2_MAGIC_BITMASK),
	.nodetype = constant_cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER),
	.totlen = constant_cpu_to_je32(8)
1027
};
1028

Linus Torvalds's avatar
Linus Torvalds committed
1029
/*
1030 1031
 * Check, if the out of band area is empty. This function knows about the clean
 * marker and if it is present in OOB, treats the OOB as empty anyway.
Linus Torvalds's avatar
Linus Torvalds committed
1032
 */
1033 1034
int jffs2_check_oob_empty(struct jffs2_sb_info *c,
			  struct jffs2_eraseblock *jeb, int mode)
Linus Torvalds's avatar
Linus Torvalds committed
1035
{
1036 1037
	int i, ret;
	int cmlen = min_t(int, c->oobavail, OOB_CM_SIZE);
1038 1039
	struct mtd_oob_ops ops;

1040
	ops.mode = MTD_OPS_AUTO_OOB;
1041
	ops.ooblen = NR_OOB_SCAN_PAGES * c->oobavail;
1042
	ops.oobbuf = c->oobbuf;
1043
	ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
1044 1045
	ops.datbuf = NULL;

1046
	ret = mtd_read_oob(c->mtd, jeb->offset, &ops);
1047
	if ((ret && !mtd_is_bitflip(ret)) || ops.oobretlen != ops.ooblen) {
1048 1049
		pr_err("cannot read OOB for EB at %08x, requested %zd bytes, read %zd bytes, error %d\n",
		       jeb->offset, ops.ooblen, ops.oobretlen, ret);
1050
		if (!ret || mtd_is_bitflip(ret))
1051
			ret = -EIO;
1052
		return ret;
Linus Torvalds's avatar
Linus Torvalds committed
1053
	}
1054

1055 1056 1057
	for(i = 0; i < ops.ooblen; i++) {
		if (mode && i < cmlen)
			/* Yeah, we know about the cleanmarker */
Linus Torvalds's avatar
Linus Torvalds committed
1058 1059
			continue;

1060
		if (ops.oobbuf[i] != 0xFF) {
1061 1062
			jffs2_dbg(2, "Found %02x at %x in OOB for "
				  "%08x\n", ops.oobbuf[i], i, jeb->offset);
1063
			return 1;
Linus Torvalds's avatar
Linus Torvalds committed
1064 1065 1066
		}
	}

1067
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
1068 1069 1070
}

/*
1071 1072
 * Check for a valid cleanmarker.
 * Returns: 0 if a valid cleanmarker was found
1073 1074
 *	    1 if no cleanmarker was found
 *	    negative error code if an error occurred
1075
 */
1076 1077
int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c,
				 struct jffs2_eraseblock *jeb)
Linus Torvalds's avatar
Linus Torvalds committed
1078
{
1079
	struct mtd_oob_ops ops;
1080
	int ret, cmlen = min_t(int, c->oobavail, OOB_CM_SIZE);
Linus Torvalds's avatar
Linus Torvalds committed
1081

1082
	ops.mode = MTD_OPS_AUTO_OOB;
1083
	ops.ooblen = cmlen;
1084
	ops.oobbuf = c->oobbuf;
1085
	ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
1086
	ops.datbuf = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
1087

1088
	ret = mtd_read_oob(c->mtd, jeb->offset, &ops);
1089
	if ((ret && !mtd_is_bitflip(ret)) || ops.oobretlen != ops.ooblen) {
1090 1091
		pr_err("cannot read OOB for EB at %08x, requested %zd bytes, read %zd bytes, error %d\n",
		       jeb->offset, ops.ooblen, ops.oobretlen, ret);
1092
		if (!ret || mtd_is_bitflip(ret))
1093
			ret = -EIO;
1094 1095
		return ret;
	}
Linus Torvalds's avatar
Linus Torvalds committed
1096

1097
	return !!memcmp(&oob_cleanmarker, c->oobbuf, cmlen);
Linus Torvalds's avatar
Linus Torvalds committed
1098 1099
}

1100 1101
int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c,
				 struct jffs2_eraseblock *jeb)
Linus Torvalds's avatar
Linus Torvalds committed
1102
{
1103
	int ret;
1104
	struct mtd_oob_ops ops;
1105
	int cmlen = min_t(int, c->oobavail, OOB_CM_SIZE);
Linus Torvalds's avatar
Linus Torvalds committed
1106

1107
	ops.mode = MTD_OPS_AUTO_OOB;
1108 1109 1110
	ops.ooblen = cmlen;
	ops.oobbuf = (uint8_t *)&oob_cleanmarker;
	ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
1111 1112
	ops.datbuf = NULL;

1113
	ret = mtd_write_oob(c->mtd, jeb->offset, &ops);
1114
	if (ret || ops.oobretlen != ops.ooblen) {
1115 1116
		pr_err("cannot write OOB for EB at %08x, requested %zd bytes, read %zd bytes, error %d\n",
		       jeb->offset, ops.ooblen, ops.oobretlen, ret);
1117 1118
		if (!ret)
			ret = -EIO;
Linus Torvalds's avatar
Linus Torvalds committed
1119 1120
		return ret;
	}
1121

Linus Torvalds's avatar
Linus Torvalds committed
1122 1123 1124
	return 0;
}

1125
/*
Linus Torvalds's avatar
Linus Torvalds committed
1126
 * On NAND we try to mark this block bad. If the block was erased more
1127
 * than MAX_ERASE_FAILURES we mark it finally bad.
Linus Torvalds's avatar
Linus Torvalds committed
1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140
 * Don't care about failures. This block remains on the erase-pending
 * or badblock list as long as nobody manipulates the flash with
 * a bootloader or something like that.
 */

int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t bad_offset)
{
	int 	ret;

	/* if the count is < max, we try to write the counter to the 2nd page oob area */
	if( ++jeb->bad_count < MAX_ERASE_FAILURES)
		return 0;

1141
	pr_warn("marking eraseblock at %08x as bad\n", bad_offset);
1142
	ret = mtd_block_markbad(c->mtd, bad_offset);
1143

Linus Torvalds's avatar
Linus Torvalds committed
1144
	if (ret) {
1145 1146
		jffs2_dbg(1, "%s(): Write failed for block at %08x: error %d\n",
			  __func__, jeb->offset, ret);
Linus Torvalds's avatar
Linus Torvalds committed
1147 1148 1149 1150 1151
		return ret;
	}
	return 1;
}

1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192
static struct jffs2_sb_info *work_to_sb(struct work_struct *work)
{
	struct delayed_work *dwork;

	dwork = container_of(work, struct delayed_work, work);
	return container_of(dwork, struct jffs2_sb_info, wbuf_dwork);
}

static void delayed_wbuf_sync(struct work_struct *work)
{
	struct jffs2_sb_info *c = work_to_sb(work);
	struct super_block *sb = OFNI_BS_2SFFJ(c);

	spin_lock(&c->wbuf_dwork_lock);
	c->wbuf_queued = 0;
	spin_unlock(&c->wbuf_dwork_lock);

	if (!(sb->s_flags & MS_RDONLY)) {
		jffs2_dbg(1, "%s()\n", __func__);
		jffs2_flush_wbuf_gc(c, 0);
	}
}

void jffs2_dirty_trigger(struct jffs2_sb_info *c)
{
	struct super_block *sb = OFNI_BS_2SFFJ(c);
	unsigned long delay;

	if (sb->s_flags & MS_RDONLY)
		return;

	spin_lock(&c->wbuf_dwork_lock);
	if (!c->wbuf_queued) {
		jffs2_dbg(1, "%s()\n", __func__);
		delay = msecs_to_jiffies(dirty_writeback_interval * 10);
		queue_delayed_work(system_long_wq, &c->wbuf_dwork, delay);
		c->wbuf_queued = 1;
	}
	spin_unlock(&c->wbuf_dwork_lock);
}

1193
int jffs2_nand_flash_setup(struct jffs2_sb_info *c)
Linus Torvalds's avatar
Linus Torvalds committed
1194
{
1195
	struct nand_ecclayout *oinfo = c->mtd->ecclayout;
Linus Torvalds's avatar
Linus Torvalds committed
1196 1197 1198

	if (!c->mtd->oobsize)
		return 0;
1199

Linus Torvalds's avatar
Linus Torvalds committed
1200 1201 1202
	/* Cleanmarker is out-of-band, so inline size zero */
	c->cleanmarker_size = 0;

1203
	if (!oinfo || oinfo->oobavail == 0) {
1204
		pr_err("inconsistent device description\n");
1205 1206
		return -EINVAL;
	}
1207

1208
	jffs2_dbg(1, "using OOB on NAND\n");
1209

1210
	c->oobavail = oinfo->oobavail;
Linus Torvalds's avatar
Linus Torvalds committed
1211 1212 1213

	/* Initialise write buffer */
	init_rwsem(&c->wbuf_sem);
1214 1215
	spin_lock_init(&c->wbuf_dwork_lock);
	INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync);
Joern Engel's avatar
Joern Engel committed
1216
	c->wbuf_pagesize = c->mtd->writesize;
Linus Torvalds's avatar
Linus Torvalds committed
1217
	c->wbuf_ofs = 0xFFFFFFFF;
1218

Linus Torvalds's avatar
Linus Torvalds committed
1219 1220 1221 1222
	c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
	if (!c->wbuf)
		return -ENOMEM;

1223 1224
	c->oobbuf = kmalloc(NR_OOB_SCAN_PAGES * c->oobavail, GFP_KERNEL);
	if (!c->oobbuf) {
Linus Torvalds's avatar
Linus Torvalds committed
1225 1226 1227
		kfree(c->wbuf);
		return -ENOMEM;
	}
1228

1229 1230 1231 1232 1233 1234 1235 1236
#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
	c->wbuf_verify = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
	if (!c->wbuf_verify) {
		kfree(c->oobbuf);
		kfree(c->wbuf);
		return -ENOMEM;
	}
#endif
1237
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
1238 1239 1240 1241
}

void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c)
{
1242 1243 1244
#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
	kfree(c->wbuf_verify);
#endif
Linus Torvalds's avatar
Linus Torvalds committed
1245
	kfree(c->wbuf);
1246
	kfree(c->oobbuf);
Linus Torvalds's avatar
Linus Torvalds committed
1247 1248
}

1249 1250
int jffs2_dataflash_setup(struct jffs2_sb_info *c) {
	c->cleanmarker_size = 0;		/* No cleanmarkers needed */
1251

1252 1253
	/* Initialize write buffer */
	init_rwsem(&c->wbuf_sem);
1254 1255
	spin_lock_init(&c->wbuf_dwork_lock);
	INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync);
1256
	c->wbuf_pagesize =  c->mtd->erasesize;
1257

1258 1259 1260 1261 1262 1263 1264 1265 1266
	/* Find a suitable c->sector_size
	 * - Not too much sectors
	 * - Sectors have to be at least 4 K + some bytes
	 * - All known dataflashes have erase sizes of 528 or 1056
	 * - we take at least 8 eraseblocks and want to have at least 8K size
	 * - The concatenation should be a power of 2
	*/

	c->sector_size = 8 * c->mtd->erasesize;
1267

1268 1269 1270
	while (c->sector_size < 8192) {
		c->sector_size *= 2;
	}
1271

1272 1273
	/* It may be necessary to adjust the flash size */
	c->flash_size = c->mtd->size;
1274

1275 1276
	if ((c->flash_size % c->sector_size) != 0) {
		c->flash_size = (c->flash_size / c->sector_size) * c->sector_size;
1277
		pr_warn("flash size adjusted to %dKiB\n", c->flash_size);
1278
	};
1279

1280
	c->wbuf_ofs = 0xFFFFFFFF;
1281 1282 1283 1284
	c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
	if (!c->wbuf)
		return -ENOMEM;

1285 1286 1287 1288 1289 1290 1291 1292 1293
#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
	c->wbuf_verify = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
	if (!c->wbuf_verify) {
		kfree(c->oobbuf);
		kfree(c->wbuf);
		return -ENOMEM;
	}
#endif

1294
	pr_info("write-buffering enabled buffer (%d) erasesize (%d)\n",
1295
		c->wbuf_pagesize, c->sector_size);
1296 1297 1298 1299 1300

	return 0;
}

void jffs2_dataflash_cleanup(struct jffs2_sb_info *c) {
1301 1302 1303
#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
	kfree(c->wbuf_verify);
#endif
1304 1305 1306
	kfree(c->wbuf);
}

1307
int jffs2_nor_wbuf_flash_setup(struct jffs2_sb_info *c) {
1308 1309 1310
	/* Cleanmarker currently occupies whole programming regions,
	 * either one or 2 for 8Byte STMicro flashes. */
	c->cleanmarker_size = max(16u, c->mtd->writesize);
1311 1312 1313

	/* Initialize write buffer */
	init_rwsem(&c->wbuf_sem);
1314 1315 1316
	spin_lock_init(&c->wbuf_dwork_lock);
	INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync);

Joern Engel's avatar
Joern Engel committed
1317
	c->wbuf_pagesize = c->mtd->writesize;
1318 1319 1320 1321 1322 1323
	c->wbuf_ofs = 0xFFFFFFFF;

	c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
	if (!c->wbuf)
		return -ENOMEM;

1324 1325 1326 1327 1328 1329 1330
#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
	c->wbuf_verify = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
	if (!c->wbuf_verify) {
		kfree(c->wbuf);
		return -ENOMEM;
	}
#endif
1331 1332 1333 1334
	return 0;
}

void jffs2_nor_wbuf_flash_cleanup(struct jffs2_sb_info *c) {
1335 1336 1337
#ifdef CONFIG_JFFS2_FS_WBUF_VERIFY
	kfree(c->wbuf_verify);
#endif
1338 1339
	kfree(c->wbuf);
}
1340 1341 1342 1343 1344 1345 1346 1347 1348

int jffs2_ubivol_setup(struct jffs2_sb_info *c) {
	c->cleanmarker_size = 0;

	if (c->mtd->writesize == 1)
		/* We do not need write-buffer */
		return 0;

	init_rwsem(&c->wbuf_sem);
1349 1350
	spin_lock_init(&c->wbuf_dwork_lock);
	INIT_DELAYED_WORK(&c->wbuf_dwork, delayed_wbuf_sync);
1351 1352 1353 1354 1355 1356 1357

	c->wbuf_pagesize =  c->mtd->writesize;
	c->wbuf_ofs = 0xFFFFFFFF;