162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * JFFS2 -- Journalling Flash File System, Version 2.
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Copyright © 2001-2007 Red Hat, Inc.
562306a36Sopenharmony_ci * Copyright © 2004-2010 David Woodhouse <dwmw2@infradead.org>
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Created by David Woodhouse <dwmw2@infradead.org>
862306a36Sopenharmony_ci *
962306a36Sopenharmony_ci * For licensing information, see the file 'LICENCE' in this directory.
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci */
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <linux/kernel.h>
1662306a36Sopenharmony_ci#include <linux/mtd/mtd.h>
1762306a36Sopenharmony_ci#include <linux/slab.h>
1862306a36Sopenharmony_ci#include <linux/pagemap.h>
1962306a36Sopenharmony_ci#include <linux/crc32.h>
2062306a36Sopenharmony_ci#include <linux/compiler.h>
2162306a36Sopenharmony_ci#include <linux/stat.h>
2262306a36Sopenharmony_ci#include "nodelist.h"
2362306a36Sopenharmony_ci#include "compr.h"
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_cistatic int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
2662306a36Sopenharmony_ci					  struct jffs2_inode_cache *ic,
2762306a36Sopenharmony_ci					  struct jffs2_raw_node_ref *raw);
2862306a36Sopenharmony_cistatic int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
2962306a36Sopenharmony_ci					struct jffs2_inode_info *f, struct jffs2_full_dnode *fd);
3062306a36Sopenharmony_cistatic int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
3162306a36Sopenharmony_ci					struct jffs2_inode_info *f, struct jffs2_full_dirent *fd);
3262306a36Sopenharmony_cistatic int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
3362306a36Sopenharmony_ci					struct jffs2_inode_info *f, struct jffs2_full_dirent *fd);
3462306a36Sopenharmony_cistatic int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
3562306a36Sopenharmony_ci				      struct jffs2_inode_info *f, struct jffs2_full_dnode *fn,
3662306a36Sopenharmony_ci				      uint32_t start, uint32_t end);
3762306a36Sopenharmony_cistatic int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
3862306a36Sopenharmony_ci				       struct jffs2_inode_info *f, struct jffs2_full_dnode *fn,
3962306a36Sopenharmony_ci				       uint32_t start, uint32_t end);
4062306a36Sopenharmony_cistatic int jffs2_garbage_collect_live(struct jffs2_sb_info *c,  struct jffs2_eraseblock *jeb,
4162306a36Sopenharmony_ci			       struct jffs2_raw_node_ref *raw, struct jffs2_inode_info *f);
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci/* Called with erase_completion_lock held */
4462306a36Sopenharmony_cistatic struct jffs2_eraseblock *jffs2_find_gc_block(struct jffs2_sb_info *c)
4562306a36Sopenharmony_ci{
4662306a36Sopenharmony_ci	struct jffs2_eraseblock *ret;
4762306a36Sopenharmony_ci	struct list_head *nextlist = NULL;
4862306a36Sopenharmony_ci	int n = jiffies % 128;
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	/* Pick an eraseblock to garbage collect next. This is where we'll
5162306a36Sopenharmony_ci	   put the clever wear-levelling algorithms. Eventually.  */
5262306a36Sopenharmony_ci	/* We possibly want to favour the dirtier blocks more when the
5362306a36Sopenharmony_ci	   number of free blocks is low. */
5462306a36Sopenharmony_ciagain:
5562306a36Sopenharmony_ci	if (!list_empty(&c->bad_used_list) && c->nr_free_blocks > c->resv_blocks_gcbad) {
5662306a36Sopenharmony_ci		jffs2_dbg(1, "Picking block from bad_used_list to GC next\n");
5762306a36Sopenharmony_ci		nextlist = &c->bad_used_list;
5862306a36Sopenharmony_ci	} else if (n < 50 && !list_empty(&c->erasable_list)) {
5962306a36Sopenharmony_ci		/* Note that most of them will have gone directly to be erased.
6062306a36Sopenharmony_ci		   So don't favour the erasable_list _too_ much. */
6162306a36Sopenharmony_ci		jffs2_dbg(1, "Picking block from erasable_list to GC next\n");
6262306a36Sopenharmony_ci		nextlist = &c->erasable_list;
6362306a36Sopenharmony_ci	} else if (n < 110 && !list_empty(&c->very_dirty_list)) {
6462306a36Sopenharmony_ci		/* Most of the time, pick one off the very_dirty list */
6562306a36Sopenharmony_ci		jffs2_dbg(1, "Picking block from very_dirty_list to GC next\n");
6662306a36Sopenharmony_ci		nextlist = &c->very_dirty_list;
6762306a36Sopenharmony_ci	} else if (n < 126 && !list_empty(&c->dirty_list)) {
6862306a36Sopenharmony_ci		jffs2_dbg(1, "Picking block from dirty_list to GC next\n");
6962306a36Sopenharmony_ci		nextlist = &c->dirty_list;
7062306a36Sopenharmony_ci	} else if (!list_empty(&c->clean_list)) {
7162306a36Sopenharmony_ci		jffs2_dbg(1, "Picking block from clean_list to GC next\n");
7262306a36Sopenharmony_ci		nextlist = &c->clean_list;
7362306a36Sopenharmony_ci	} else if (!list_empty(&c->dirty_list)) {
7462306a36Sopenharmony_ci		jffs2_dbg(1, "Picking block from dirty_list to GC next (clean_list was empty)\n");
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci		nextlist = &c->dirty_list;
7762306a36Sopenharmony_ci	} else if (!list_empty(&c->very_dirty_list)) {
7862306a36Sopenharmony_ci		jffs2_dbg(1, "Picking block from very_dirty_list to GC next (clean_list and dirty_list were empty)\n");
7962306a36Sopenharmony_ci		nextlist = &c->very_dirty_list;
8062306a36Sopenharmony_ci	} else if (!list_empty(&c->erasable_list)) {
8162306a36Sopenharmony_ci		jffs2_dbg(1, "Picking block from erasable_list to GC next (clean_list and {very_,}dirty_list were empty)\n");
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci		nextlist = &c->erasable_list;
8462306a36Sopenharmony_ci	} else if (!list_empty(&c->erasable_pending_wbuf_list)) {
8562306a36Sopenharmony_ci		/* There are blocks are wating for the wbuf sync */
8662306a36Sopenharmony_ci		jffs2_dbg(1, "Synching wbuf in order to reuse erasable_pending_wbuf_list blocks\n");
8762306a36Sopenharmony_ci		spin_unlock(&c->erase_completion_lock);
8862306a36Sopenharmony_ci		jffs2_flush_wbuf_pad(c);
8962306a36Sopenharmony_ci		spin_lock(&c->erase_completion_lock);
9062306a36Sopenharmony_ci		goto again;
9162306a36Sopenharmony_ci	} else {
9262306a36Sopenharmony_ci		/* Eep. All were empty */
9362306a36Sopenharmony_ci		jffs2_dbg(1, "No clean, dirty _or_ erasable blocks to GC from! Where are they all?\n");
9462306a36Sopenharmony_ci		return NULL;
9562306a36Sopenharmony_ci	}
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci	ret = list_entry(nextlist->next, struct jffs2_eraseblock, list);
9862306a36Sopenharmony_ci	list_del(&ret->list);
9962306a36Sopenharmony_ci	c->gcblock = ret;
10062306a36Sopenharmony_ci	ret->gc_node = ret->first_node;
10162306a36Sopenharmony_ci	if (!ret->gc_node) {
10262306a36Sopenharmony_ci		pr_warn("Eep. ret->gc_node for block at 0x%08x is NULL\n",
10362306a36Sopenharmony_ci			ret->offset);
10462306a36Sopenharmony_ci		BUG();
10562306a36Sopenharmony_ci	}
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	/* Have we accidentally picked a clean block with wasted space ? */
10862306a36Sopenharmony_ci	if (ret->wasted_size) {
10962306a36Sopenharmony_ci		jffs2_dbg(1, "Converting wasted_size %08x to dirty_size\n",
11062306a36Sopenharmony_ci			  ret->wasted_size);
11162306a36Sopenharmony_ci		ret->dirty_size += ret->wasted_size;
11262306a36Sopenharmony_ci		c->wasted_size -= ret->wasted_size;
11362306a36Sopenharmony_ci		c->dirty_size += ret->wasted_size;
11462306a36Sopenharmony_ci		ret->wasted_size = 0;
11562306a36Sopenharmony_ci	}
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci	return ret;
11862306a36Sopenharmony_ci}
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci/* jffs2_garbage_collect_pass
12162306a36Sopenharmony_ci * Make a single attempt to progress GC. Move one node, and possibly
12262306a36Sopenharmony_ci * start erasing one eraseblock.
12362306a36Sopenharmony_ci */
12462306a36Sopenharmony_ciint jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
12562306a36Sopenharmony_ci{
12662306a36Sopenharmony_ci	struct jffs2_inode_info *f;
12762306a36Sopenharmony_ci	struct jffs2_inode_cache *ic;
12862306a36Sopenharmony_ci	struct jffs2_eraseblock *jeb;
12962306a36Sopenharmony_ci	struct jffs2_raw_node_ref *raw;
13062306a36Sopenharmony_ci	uint32_t gcblock_dirty;
13162306a36Sopenharmony_ci	int ret = 0, inum, nlink;
13262306a36Sopenharmony_ci	int xattr = 0;
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci	if (mutex_lock_interruptible(&c->alloc_sem))
13562306a36Sopenharmony_ci		return -EINTR;
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci	for (;;) {
13962306a36Sopenharmony_ci		/* We can't start doing GC until we've finished checking
14062306a36Sopenharmony_ci		   the node CRCs etc. */
14162306a36Sopenharmony_ci		int bucket, want_ino;
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci		spin_lock(&c->erase_completion_lock);
14462306a36Sopenharmony_ci		if (!c->unchecked_size)
14562306a36Sopenharmony_ci			break;
14662306a36Sopenharmony_ci		spin_unlock(&c->erase_completion_lock);
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci		if (!xattr)
14962306a36Sopenharmony_ci			xattr = jffs2_verify_xattr(c);
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci		spin_lock(&c->inocache_lock);
15262306a36Sopenharmony_ci		/* Instead of doing the inodes in numeric order, doing a lookup
15362306a36Sopenharmony_ci		 * in the hash for each possible number, just walk the hash
15462306a36Sopenharmony_ci		 * buckets of *existing* inodes. This means that we process
15562306a36Sopenharmony_ci		 * them out-of-order, but it can be a lot faster if there's
15662306a36Sopenharmony_ci		 * a sparse inode# space. Which there often is. */
15762306a36Sopenharmony_ci		want_ino = c->check_ino;
15862306a36Sopenharmony_ci		for (bucket = c->check_ino % c->inocache_hashsize ; bucket < c->inocache_hashsize; bucket++) {
15962306a36Sopenharmony_ci			for (ic = c->inocache_list[bucket]; ic; ic = ic->next) {
16062306a36Sopenharmony_ci				if (ic->ino < want_ino)
16162306a36Sopenharmony_ci					continue;
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci				if (ic->state != INO_STATE_CHECKEDABSENT &&
16462306a36Sopenharmony_ci				    ic->state != INO_STATE_PRESENT)
16562306a36Sopenharmony_ci					goto got_next; /* with inocache_lock held */
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci				jffs2_dbg(1, "Skipping ino #%u already checked\n",
16862306a36Sopenharmony_ci					  ic->ino);
16962306a36Sopenharmony_ci			}
17062306a36Sopenharmony_ci			want_ino = 0;
17162306a36Sopenharmony_ci		}
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci		/* Point c->check_ino past the end of the last bucket. */
17462306a36Sopenharmony_ci		c->check_ino = ((c->highest_ino + c->inocache_hashsize + 1) &
17562306a36Sopenharmony_ci				~c->inocache_hashsize) - 1;
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci		spin_unlock(&c->inocache_lock);
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci		pr_crit("Checked all inodes but still 0x%x bytes of unchecked space?\n",
18062306a36Sopenharmony_ci			c->unchecked_size);
18162306a36Sopenharmony_ci		jffs2_dbg_dump_block_lists_nolock(c);
18262306a36Sopenharmony_ci		mutex_unlock(&c->alloc_sem);
18362306a36Sopenharmony_ci		return -ENOSPC;
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci	got_next:
18662306a36Sopenharmony_ci		/* For next time round the loop, we want c->checked_ino to indicate
18762306a36Sopenharmony_ci		 * the *next* one we want to check. And since we're walking the
18862306a36Sopenharmony_ci		 * buckets rather than doing it sequentially, it's: */
18962306a36Sopenharmony_ci		c->check_ino = ic->ino + c->inocache_hashsize;
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci		if (!ic->pino_nlink) {
19262306a36Sopenharmony_ci			jffs2_dbg(1, "Skipping check of ino #%d with nlink/pino zero\n",
19362306a36Sopenharmony_ci				  ic->ino);
19462306a36Sopenharmony_ci			spin_unlock(&c->inocache_lock);
19562306a36Sopenharmony_ci			jffs2_xattr_delete_inode(c, ic);
19662306a36Sopenharmony_ci			continue;
19762306a36Sopenharmony_ci		}
19862306a36Sopenharmony_ci		switch(ic->state) {
19962306a36Sopenharmony_ci		case INO_STATE_CHECKEDABSENT:
20062306a36Sopenharmony_ci		case INO_STATE_PRESENT:
20162306a36Sopenharmony_ci			spin_unlock(&c->inocache_lock);
20262306a36Sopenharmony_ci			continue;
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci		case INO_STATE_GC:
20562306a36Sopenharmony_ci		case INO_STATE_CHECKING:
20662306a36Sopenharmony_ci			pr_warn("Inode #%u is in state %d during CRC check phase!\n",
20762306a36Sopenharmony_ci				ic->ino, ic->state);
20862306a36Sopenharmony_ci			spin_unlock(&c->inocache_lock);
20962306a36Sopenharmony_ci			BUG();
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci		case INO_STATE_READING:
21262306a36Sopenharmony_ci			/* We need to wait for it to finish, lest we move on
21362306a36Sopenharmony_ci			   and trigger the BUG() above while we haven't yet
21462306a36Sopenharmony_ci			   finished checking all its nodes */
21562306a36Sopenharmony_ci			jffs2_dbg(1, "Waiting for ino #%u to finish reading\n",
21662306a36Sopenharmony_ci				  ic->ino);
21762306a36Sopenharmony_ci			/* We need to come back again for the _same_ inode. We've
21862306a36Sopenharmony_ci			 made no progress in this case, but that should be OK */
21962306a36Sopenharmony_ci			c->check_ino = ic->ino;
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci			mutex_unlock(&c->alloc_sem);
22262306a36Sopenharmony_ci			sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
22362306a36Sopenharmony_ci			return 0;
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci		default:
22662306a36Sopenharmony_ci			BUG();
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci		case INO_STATE_UNCHECKED:
22962306a36Sopenharmony_ci			;
23062306a36Sopenharmony_ci		}
23162306a36Sopenharmony_ci		ic->state = INO_STATE_CHECKING;
23262306a36Sopenharmony_ci		spin_unlock(&c->inocache_lock);
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci		jffs2_dbg(1, "%s(): triggering inode scan of ino#%u\n",
23562306a36Sopenharmony_ci			  __func__, ic->ino);
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci		ret = jffs2_do_crccheck_inode(c, ic);
23862306a36Sopenharmony_ci		if (ret)
23962306a36Sopenharmony_ci			pr_warn("Returned error for crccheck of ino #%u. Expect badness...\n",
24062306a36Sopenharmony_ci				ic->ino);
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci		jffs2_set_inocache_state(c, ic, INO_STATE_CHECKEDABSENT);
24362306a36Sopenharmony_ci		mutex_unlock(&c->alloc_sem);
24462306a36Sopenharmony_ci		return ret;
24562306a36Sopenharmony_ci	}
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci	/* If there are any blocks which need erasing, erase them now */
24862306a36Sopenharmony_ci	if (!list_empty(&c->erase_complete_list) ||
24962306a36Sopenharmony_ci	    !list_empty(&c->erase_pending_list)) {
25062306a36Sopenharmony_ci		spin_unlock(&c->erase_completion_lock);
25162306a36Sopenharmony_ci		mutex_unlock(&c->alloc_sem);
25262306a36Sopenharmony_ci		jffs2_dbg(1, "%s(): erasing pending blocks\n", __func__);
25362306a36Sopenharmony_ci		if (jffs2_erase_pending_blocks(c, 1))
25462306a36Sopenharmony_ci			return 0;
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci		jffs2_dbg(1, "No progress from erasing block; doing GC anyway\n");
25762306a36Sopenharmony_ci		mutex_lock(&c->alloc_sem);
25862306a36Sopenharmony_ci		spin_lock(&c->erase_completion_lock);
25962306a36Sopenharmony_ci	}
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	/* First, work out which block we're garbage-collecting */
26262306a36Sopenharmony_ci	jeb = c->gcblock;
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ci	if (!jeb)
26562306a36Sopenharmony_ci		jeb = jffs2_find_gc_block(c);
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci	if (!jeb) {
26862306a36Sopenharmony_ci		/* Couldn't find a free block. But maybe we can just erase one and make 'progress'? */
26962306a36Sopenharmony_ci		if (c->nr_erasing_blocks) {
27062306a36Sopenharmony_ci			spin_unlock(&c->erase_completion_lock);
27162306a36Sopenharmony_ci			mutex_unlock(&c->alloc_sem);
27262306a36Sopenharmony_ci			return -EAGAIN;
27362306a36Sopenharmony_ci		}
27462306a36Sopenharmony_ci		jffs2_dbg(1, "Couldn't find erase block to garbage collect!\n");
27562306a36Sopenharmony_ci		spin_unlock(&c->erase_completion_lock);
27662306a36Sopenharmony_ci		mutex_unlock(&c->alloc_sem);
27762306a36Sopenharmony_ci		return -EIO;
27862306a36Sopenharmony_ci	}
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci	jffs2_dbg(1, "GC from block %08x, used_size %08x, dirty_size %08x, free_size %08x\n",
28162306a36Sopenharmony_ci		  jeb->offset, jeb->used_size, jeb->dirty_size, jeb->free_size);
28262306a36Sopenharmony_ci	D1(if (c->nextblock)
28362306a36Sopenharmony_ci	   printk(KERN_DEBUG "Nextblock at  %08x, used_size %08x, dirty_size %08x, wasted_size %08x, free_size %08x\n", c->nextblock->offset, c->nextblock->used_size, c->nextblock->dirty_size, c->nextblock->wasted_size, c->nextblock->free_size));
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ci	if (!jeb->used_size) {
28662306a36Sopenharmony_ci		mutex_unlock(&c->alloc_sem);
28762306a36Sopenharmony_ci		goto eraseit;
28862306a36Sopenharmony_ci	}
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_ci	raw = jeb->gc_node;
29162306a36Sopenharmony_ci	gcblock_dirty = jeb->dirty_size;
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci	while(ref_obsolete(raw)) {
29462306a36Sopenharmony_ci		jffs2_dbg(1, "Node at 0x%08x is obsolete... skipping\n",
29562306a36Sopenharmony_ci			  ref_offset(raw));
29662306a36Sopenharmony_ci		raw = ref_next(raw);
29762306a36Sopenharmony_ci		if (unlikely(!raw)) {
29862306a36Sopenharmony_ci			pr_warn("eep. End of raw list while still supposedly nodes to GC\n");
29962306a36Sopenharmony_ci			pr_warn("erase block at 0x%08x. free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x\n",
30062306a36Sopenharmony_ci				jeb->offset, jeb->free_size,
30162306a36Sopenharmony_ci				jeb->dirty_size, jeb->used_size);
30262306a36Sopenharmony_ci			jeb->gc_node = raw;
30362306a36Sopenharmony_ci			spin_unlock(&c->erase_completion_lock);
30462306a36Sopenharmony_ci			mutex_unlock(&c->alloc_sem);
30562306a36Sopenharmony_ci			BUG();
30662306a36Sopenharmony_ci		}
30762306a36Sopenharmony_ci	}
30862306a36Sopenharmony_ci	jeb->gc_node = raw;
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_ci	jffs2_dbg(1, "Going to garbage collect node at 0x%08x\n",
31162306a36Sopenharmony_ci		  ref_offset(raw));
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci	if (!raw->next_in_ino) {
31462306a36Sopenharmony_ci		/* Inode-less node. Clean marker, snapshot or something like that */
31562306a36Sopenharmony_ci		spin_unlock(&c->erase_completion_lock);
31662306a36Sopenharmony_ci		if (ref_flags(raw) == REF_PRISTINE) {
31762306a36Sopenharmony_ci			/* It's an unknown node with JFFS2_FEATURE_RWCOMPAT_COPY */
31862306a36Sopenharmony_ci			jffs2_garbage_collect_pristine(c, NULL, raw);
31962306a36Sopenharmony_ci		} else {
32062306a36Sopenharmony_ci			/* Just mark it obsolete */
32162306a36Sopenharmony_ci			jffs2_mark_node_obsolete(c, raw);
32262306a36Sopenharmony_ci		}
32362306a36Sopenharmony_ci		mutex_unlock(&c->alloc_sem);
32462306a36Sopenharmony_ci		goto eraseit_lock;
32562306a36Sopenharmony_ci	}
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_ci	ic = jffs2_raw_ref_to_ic(raw);
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci#ifdef CONFIG_JFFS2_FS_XATTR
33062306a36Sopenharmony_ci	/* When 'ic' refers xattr_datum/xattr_ref, this node is GCed as xattr.
33162306a36Sopenharmony_ci	 * We can decide whether this node is inode or xattr by ic->class.     */
33262306a36Sopenharmony_ci	if (ic->class == RAWNODE_CLASS_XATTR_DATUM
33362306a36Sopenharmony_ci	    || ic->class == RAWNODE_CLASS_XATTR_REF) {
33462306a36Sopenharmony_ci		spin_unlock(&c->erase_completion_lock);
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci		if (ic->class == RAWNODE_CLASS_XATTR_DATUM) {
33762306a36Sopenharmony_ci			ret = jffs2_garbage_collect_xattr_datum(c, (struct jffs2_xattr_datum *)ic, raw);
33862306a36Sopenharmony_ci		} else {
33962306a36Sopenharmony_ci			ret = jffs2_garbage_collect_xattr_ref(c, (struct jffs2_xattr_ref *)ic, raw);
34062306a36Sopenharmony_ci		}
34162306a36Sopenharmony_ci		goto test_gcnode;
34262306a36Sopenharmony_ci	}
34362306a36Sopenharmony_ci#endif
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ci	/* We need to hold the inocache. Either the erase_completion_lock or
34662306a36Sopenharmony_ci	   the inocache_lock are sufficient; we trade down since the inocache_lock
34762306a36Sopenharmony_ci	   causes less contention. */
34862306a36Sopenharmony_ci	spin_lock(&c->inocache_lock);
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_ci	spin_unlock(&c->erase_completion_lock);
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci	jffs2_dbg(1, "%s(): collecting from block @0x%08x. Node @0x%08x(%d), ino #%u\n",
35362306a36Sopenharmony_ci		  __func__, jeb->offset, ref_offset(raw), ref_flags(raw),
35462306a36Sopenharmony_ci		  ic->ino);
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci	/* Three possibilities:
35762306a36Sopenharmony_ci	   1. Inode is already in-core. We must iget it and do proper
35862306a36Sopenharmony_ci	      updating to its fragtree, etc.
35962306a36Sopenharmony_ci	   2. Inode is not in-core, node is REF_PRISTINE. We lock the
36062306a36Sopenharmony_ci	      inocache to prevent a read_inode(), copy the node intact.
36162306a36Sopenharmony_ci	   3. Inode is not in-core, node is not pristine. We must iget()
36262306a36Sopenharmony_ci	      and take the slow path.
36362306a36Sopenharmony_ci	*/
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci	switch(ic->state) {
36662306a36Sopenharmony_ci	case INO_STATE_CHECKEDABSENT:
36762306a36Sopenharmony_ci		/* It's been checked, but it's not currently in-core.
36862306a36Sopenharmony_ci		   We can just copy any pristine nodes, but have
36962306a36Sopenharmony_ci		   to prevent anyone else from doing read_inode() while
37062306a36Sopenharmony_ci		   we're at it, so we set the state accordingly */
37162306a36Sopenharmony_ci		if (ref_flags(raw) == REF_PRISTINE)
37262306a36Sopenharmony_ci			ic->state = INO_STATE_GC;
37362306a36Sopenharmony_ci		else {
37462306a36Sopenharmony_ci			jffs2_dbg(1, "Ino #%u is absent but node not REF_PRISTINE. Reading.\n",
37562306a36Sopenharmony_ci				  ic->ino);
37662306a36Sopenharmony_ci		}
37762306a36Sopenharmony_ci		break;
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_ci	case INO_STATE_PRESENT:
38062306a36Sopenharmony_ci		/* It's in-core. GC must iget() it. */
38162306a36Sopenharmony_ci		break;
38262306a36Sopenharmony_ci
38362306a36Sopenharmony_ci	case INO_STATE_UNCHECKED:
38462306a36Sopenharmony_ci	case INO_STATE_CHECKING:
38562306a36Sopenharmony_ci	case INO_STATE_GC:
38662306a36Sopenharmony_ci		/* Should never happen. We should have finished checking
38762306a36Sopenharmony_ci		   by the time we actually start doing any GC, and since
38862306a36Sopenharmony_ci		   we're holding the alloc_sem, no other garbage collection
38962306a36Sopenharmony_ci		   can happen.
39062306a36Sopenharmony_ci		*/
39162306a36Sopenharmony_ci		pr_crit("Inode #%u already in state %d in jffs2_garbage_collect_pass()!\n",
39262306a36Sopenharmony_ci			ic->ino, ic->state);
39362306a36Sopenharmony_ci		mutex_unlock(&c->alloc_sem);
39462306a36Sopenharmony_ci		spin_unlock(&c->inocache_lock);
39562306a36Sopenharmony_ci		BUG();
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_ci	case INO_STATE_READING:
39862306a36Sopenharmony_ci		/* Someone's currently trying to read it. We must wait for
39962306a36Sopenharmony_ci		   them to finish and then go through the full iget() route
40062306a36Sopenharmony_ci		   to do the GC. However, sometimes read_inode() needs to get
40162306a36Sopenharmony_ci		   the alloc_sem() (for marking nodes invalid) so we must
40262306a36Sopenharmony_ci		   drop the alloc_sem before sleeping. */
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ci		mutex_unlock(&c->alloc_sem);
40562306a36Sopenharmony_ci		jffs2_dbg(1, "%s(): waiting for ino #%u in state %d\n",
40662306a36Sopenharmony_ci			  __func__, ic->ino, ic->state);
40762306a36Sopenharmony_ci		sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
40862306a36Sopenharmony_ci		/* And because we dropped the alloc_sem we must start again from the
40962306a36Sopenharmony_ci		   beginning. Ponder chance of livelock here -- we're returning success
41062306a36Sopenharmony_ci		   without actually making any progress.
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci		   Q: What are the chances that the inode is back in INO_STATE_READING
41362306a36Sopenharmony_ci		   again by the time we next enter this function? And that this happens
41462306a36Sopenharmony_ci		   enough times to cause a real delay?
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_ci		   A: Small enough that I don't care :)
41762306a36Sopenharmony_ci		*/
41862306a36Sopenharmony_ci		return 0;
41962306a36Sopenharmony_ci	}
42062306a36Sopenharmony_ci
42162306a36Sopenharmony_ci	/* OK. Now if the inode is in state INO_STATE_GC, we are going to copy the
42262306a36Sopenharmony_ci	   node intact, and we don't have to muck about with the fragtree etc.
42362306a36Sopenharmony_ci	   because we know it's not in-core. If it _was_ in-core, we go through
42462306a36Sopenharmony_ci	   all the iget() crap anyway */
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci	if (ic->state == INO_STATE_GC) {
42762306a36Sopenharmony_ci		spin_unlock(&c->inocache_lock);
42862306a36Sopenharmony_ci
42962306a36Sopenharmony_ci		ret = jffs2_garbage_collect_pristine(c, ic, raw);
43062306a36Sopenharmony_ci
43162306a36Sopenharmony_ci		spin_lock(&c->inocache_lock);
43262306a36Sopenharmony_ci		ic->state = INO_STATE_CHECKEDABSENT;
43362306a36Sopenharmony_ci		wake_up(&c->inocache_wq);
43462306a36Sopenharmony_ci
43562306a36Sopenharmony_ci		if (ret != -EBADFD) {
43662306a36Sopenharmony_ci			spin_unlock(&c->inocache_lock);
43762306a36Sopenharmony_ci			goto test_gcnode;
43862306a36Sopenharmony_ci		}
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci		/* Fall through if it wanted us to, with inocache_lock held */
44162306a36Sopenharmony_ci	}
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci	/* Prevent the fairly unlikely race where the gcblock is
44462306a36Sopenharmony_ci	   entirely obsoleted by the final close of a file which had
44562306a36Sopenharmony_ci	   the only valid nodes in the block, followed by erasure,
44662306a36Sopenharmony_ci	   followed by freeing of the ic because the erased block(s)
44762306a36Sopenharmony_ci	   held _all_ the nodes of that inode.... never been seen but
44862306a36Sopenharmony_ci	   it's vaguely possible. */
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_ci	inum = ic->ino;
45162306a36Sopenharmony_ci	nlink = ic->pino_nlink;
45262306a36Sopenharmony_ci	spin_unlock(&c->inocache_lock);
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_ci	f = jffs2_gc_fetch_inode(c, inum, !nlink);
45562306a36Sopenharmony_ci	if (IS_ERR(f)) {
45662306a36Sopenharmony_ci		ret = PTR_ERR(f);
45762306a36Sopenharmony_ci		goto release_sem;
45862306a36Sopenharmony_ci	}
45962306a36Sopenharmony_ci	if (!f) {
46062306a36Sopenharmony_ci		ret = 0;
46162306a36Sopenharmony_ci		goto release_sem;
46262306a36Sopenharmony_ci	}
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_ci	ret = jffs2_garbage_collect_live(c, jeb, raw, f);
46562306a36Sopenharmony_ci
46662306a36Sopenharmony_ci	jffs2_gc_release_inode(c, f);
46762306a36Sopenharmony_ci
46862306a36Sopenharmony_ci test_gcnode:
46962306a36Sopenharmony_ci	if (jeb->dirty_size == gcblock_dirty && !ref_obsolete(jeb->gc_node)) {
47062306a36Sopenharmony_ci		/* Eep. This really should never happen. GC is broken */
47162306a36Sopenharmony_ci		pr_err("Error garbage collecting node at %08x!\n",
47262306a36Sopenharmony_ci		       ref_offset(jeb->gc_node));
47362306a36Sopenharmony_ci		ret = -ENOSPC;
47462306a36Sopenharmony_ci	}
47562306a36Sopenharmony_ci release_sem:
47662306a36Sopenharmony_ci	mutex_unlock(&c->alloc_sem);
47762306a36Sopenharmony_ci
47862306a36Sopenharmony_ci eraseit_lock:
47962306a36Sopenharmony_ci	/* If we've finished this block, start it erasing */
48062306a36Sopenharmony_ci	spin_lock(&c->erase_completion_lock);
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ci eraseit:
48362306a36Sopenharmony_ci	if (c->gcblock && !c->gcblock->used_size) {
48462306a36Sopenharmony_ci		jffs2_dbg(1, "Block at 0x%08x completely obsoleted by GC. Moving to erase_pending_list\n",
48562306a36Sopenharmony_ci			  c->gcblock->offset);
48662306a36Sopenharmony_ci		/* We're GC'ing an empty block? */
48762306a36Sopenharmony_ci		list_add_tail(&c->gcblock->list, &c->erase_pending_list);
48862306a36Sopenharmony_ci		c->gcblock = NULL;
48962306a36Sopenharmony_ci		c->nr_erasing_blocks++;
49062306a36Sopenharmony_ci		jffs2_garbage_collect_trigger(c);
49162306a36Sopenharmony_ci	}
49262306a36Sopenharmony_ci	spin_unlock(&c->erase_completion_lock);
49362306a36Sopenharmony_ci
49462306a36Sopenharmony_ci	return ret;
49562306a36Sopenharmony_ci}
49662306a36Sopenharmony_ci
49762306a36Sopenharmony_cistatic int jffs2_garbage_collect_live(struct jffs2_sb_info *c,  struct jffs2_eraseblock *jeb,
49862306a36Sopenharmony_ci				      struct jffs2_raw_node_ref *raw, struct jffs2_inode_info *f)
49962306a36Sopenharmony_ci{
50062306a36Sopenharmony_ci	struct jffs2_node_frag *frag;
50162306a36Sopenharmony_ci	struct jffs2_full_dnode *fn = NULL;
50262306a36Sopenharmony_ci	struct jffs2_full_dirent *fd;
50362306a36Sopenharmony_ci	uint32_t start = 0, end = 0, nrfrags = 0;
50462306a36Sopenharmony_ci	int ret = 0;
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ci	mutex_lock(&f->sem);
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ci	/* Now we have the lock for this inode. Check that it's still the one at the head
50962306a36Sopenharmony_ci	   of the list. */
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_ci	spin_lock(&c->erase_completion_lock);
51262306a36Sopenharmony_ci
51362306a36Sopenharmony_ci	if (c->gcblock != jeb) {
51462306a36Sopenharmony_ci		spin_unlock(&c->erase_completion_lock);
51562306a36Sopenharmony_ci		jffs2_dbg(1, "GC block is no longer gcblock. Restart\n");
51662306a36Sopenharmony_ci		goto upnout;
51762306a36Sopenharmony_ci	}
51862306a36Sopenharmony_ci	if (ref_obsolete(raw)) {
51962306a36Sopenharmony_ci		spin_unlock(&c->erase_completion_lock);
52062306a36Sopenharmony_ci		jffs2_dbg(1, "node to be GC'd was obsoleted in the meantime.\n");
52162306a36Sopenharmony_ci		/* They'll call again */
52262306a36Sopenharmony_ci		goto upnout;
52362306a36Sopenharmony_ci	}
52462306a36Sopenharmony_ci	spin_unlock(&c->erase_completion_lock);
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_ci	/* OK. Looks safe. And nobody can get us now because we have the semaphore. Move the block */
52762306a36Sopenharmony_ci	if (f->metadata && f->metadata->raw == raw) {
52862306a36Sopenharmony_ci		fn = f->metadata;
52962306a36Sopenharmony_ci		ret = jffs2_garbage_collect_metadata(c, jeb, f, fn);
53062306a36Sopenharmony_ci		goto upnout;
53162306a36Sopenharmony_ci	}
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_ci	/* FIXME. Read node and do lookup? */
53462306a36Sopenharmony_ci	for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) {
53562306a36Sopenharmony_ci		if (frag->node && frag->node->raw == raw) {
53662306a36Sopenharmony_ci			fn = frag->node;
53762306a36Sopenharmony_ci			end = frag->ofs + frag->size;
53862306a36Sopenharmony_ci			if (!nrfrags++)
53962306a36Sopenharmony_ci				start = frag->ofs;
54062306a36Sopenharmony_ci			if (nrfrags == frag->node->frags)
54162306a36Sopenharmony_ci				break; /* We've found them all */
54262306a36Sopenharmony_ci		}
54362306a36Sopenharmony_ci	}
54462306a36Sopenharmony_ci	if (fn) {
54562306a36Sopenharmony_ci		if (ref_flags(raw) == REF_PRISTINE) {
54662306a36Sopenharmony_ci			ret = jffs2_garbage_collect_pristine(c, f->inocache, raw);
54762306a36Sopenharmony_ci			if (!ret) {
54862306a36Sopenharmony_ci				/* Urgh. Return it sensibly. */
54962306a36Sopenharmony_ci				frag->node->raw = f->inocache->nodes;
55062306a36Sopenharmony_ci			}
55162306a36Sopenharmony_ci			if (ret != -EBADFD)
55262306a36Sopenharmony_ci				goto upnout;
55362306a36Sopenharmony_ci		}
55462306a36Sopenharmony_ci		/* We found a datanode. Do the GC */
55562306a36Sopenharmony_ci		if((start >> PAGE_SHIFT) < ((end-1) >> PAGE_SHIFT)) {
55662306a36Sopenharmony_ci			/* It crosses a page boundary. Therefore, it must be a hole. */
55762306a36Sopenharmony_ci			ret = jffs2_garbage_collect_hole(c, jeb, f, fn, start, end);
55862306a36Sopenharmony_ci		} else {
55962306a36Sopenharmony_ci			/* It could still be a hole. But we GC the page this way anyway */
56062306a36Sopenharmony_ci			ret = jffs2_garbage_collect_dnode(c, jeb, f, fn, start, end);
56162306a36Sopenharmony_ci		}
56262306a36Sopenharmony_ci		goto upnout;
56362306a36Sopenharmony_ci	}
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_ci	/* Wasn't a dnode. Try dirent */
56662306a36Sopenharmony_ci	for (fd = f->dents; fd; fd=fd->next) {
56762306a36Sopenharmony_ci		if (fd->raw == raw)
56862306a36Sopenharmony_ci			break;
56962306a36Sopenharmony_ci	}
57062306a36Sopenharmony_ci
57162306a36Sopenharmony_ci	if (fd && fd->ino) {
57262306a36Sopenharmony_ci		ret = jffs2_garbage_collect_dirent(c, jeb, f, fd);
57362306a36Sopenharmony_ci	} else if (fd) {
57462306a36Sopenharmony_ci		ret = jffs2_garbage_collect_deletion_dirent(c, jeb, f, fd);
57562306a36Sopenharmony_ci	} else {
57662306a36Sopenharmony_ci		pr_warn("Raw node at 0x%08x wasn't in node lists for ino #%u\n",
57762306a36Sopenharmony_ci			ref_offset(raw), f->inocache->ino);
57862306a36Sopenharmony_ci		if (ref_obsolete(raw)) {
57962306a36Sopenharmony_ci			pr_warn("But it's obsolete so we don't mind too much\n");
58062306a36Sopenharmony_ci		} else {
58162306a36Sopenharmony_ci			jffs2_dbg_dump_node(c, ref_offset(raw));
58262306a36Sopenharmony_ci			BUG();
58362306a36Sopenharmony_ci		}
58462306a36Sopenharmony_ci	}
58562306a36Sopenharmony_ci upnout:
58662306a36Sopenharmony_ci	mutex_unlock(&f->sem);
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_ci	return ret;
58962306a36Sopenharmony_ci}
59062306a36Sopenharmony_ci
59162306a36Sopenharmony_cistatic int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c,
59262306a36Sopenharmony_ci					  struct jffs2_inode_cache *ic,
59362306a36Sopenharmony_ci					  struct jffs2_raw_node_ref *raw)
59462306a36Sopenharmony_ci{
59562306a36Sopenharmony_ci	union jffs2_node_union *node;
59662306a36Sopenharmony_ci	size_t retlen;
59762306a36Sopenharmony_ci	int ret;
59862306a36Sopenharmony_ci	uint32_t phys_ofs, alloclen;
59962306a36Sopenharmony_ci	uint32_t crc, rawlen;
60062306a36Sopenharmony_ci	int retried = 0;
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_ci	jffs2_dbg(1, "Going to GC REF_PRISTINE node at 0x%08x\n",
60362306a36Sopenharmony_ci		  ref_offset(raw));
60462306a36Sopenharmony_ci
60562306a36Sopenharmony_ci	alloclen = rawlen = ref_totlen(c, c->gcblock, raw);
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_ci	/* Ask for a small amount of space (or the totlen if smaller) because we
60862306a36Sopenharmony_ci	   don't want to force wastage of the end of a block if splitting would
60962306a36Sopenharmony_ci	   work. */
61062306a36Sopenharmony_ci	if (ic && alloclen > sizeof(struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN)
61162306a36Sopenharmony_ci		alloclen = sizeof(struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN;
61262306a36Sopenharmony_ci
61362306a36Sopenharmony_ci	ret = jffs2_reserve_space_gc(c, alloclen, &alloclen, rawlen);
61462306a36Sopenharmony_ci	/* 'rawlen' is not the exact summary size; it is only an upper estimation */
61562306a36Sopenharmony_ci
61662306a36Sopenharmony_ci	if (ret)
61762306a36Sopenharmony_ci		return ret;
61862306a36Sopenharmony_ci
61962306a36Sopenharmony_ci	if (alloclen < rawlen) {
62062306a36Sopenharmony_ci		/* Doesn't fit untouched. We'll go the old route and split it */
62162306a36Sopenharmony_ci		return -EBADFD;
62262306a36Sopenharmony_ci	}
62362306a36Sopenharmony_ci
62462306a36Sopenharmony_ci	node = kmalloc(rawlen, GFP_KERNEL);
62562306a36Sopenharmony_ci	if (!node)
62662306a36Sopenharmony_ci		return -ENOMEM;
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_ci	ret = jffs2_flash_read(c, ref_offset(raw), rawlen, &retlen, (char *)node);
62962306a36Sopenharmony_ci	if (!ret && retlen != rawlen)
63062306a36Sopenharmony_ci		ret = -EIO;
63162306a36Sopenharmony_ci	if (ret)
63262306a36Sopenharmony_ci		goto out_node;
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_ci	crc = crc32(0, node, sizeof(struct jffs2_unknown_node)-4);
63562306a36Sopenharmony_ci	if (je32_to_cpu(node->u.hdr_crc) != crc) {
63662306a36Sopenharmony_ci		pr_warn("Header CRC failed on REF_PRISTINE node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
63762306a36Sopenharmony_ci			ref_offset(raw), je32_to_cpu(node->u.hdr_crc), crc);
63862306a36Sopenharmony_ci		goto bail;
63962306a36Sopenharmony_ci	}
64062306a36Sopenharmony_ci
64162306a36Sopenharmony_ci	switch(je16_to_cpu(node->u.nodetype)) {
64262306a36Sopenharmony_ci	case JFFS2_NODETYPE_INODE:
64362306a36Sopenharmony_ci		crc = crc32(0, node, sizeof(node->i)-8);
64462306a36Sopenharmony_ci		if (je32_to_cpu(node->i.node_crc) != crc) {
64562306a36Sopenharmony_ci			pr_warn("Node CRC failed on REF_PRISTINE data node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
64662306a36Sopenharmony_ci				ref_offset(raw), je32_to_cpu(node->i.node_crc),
64762306a36Sopenharmony_ci				crc);
64862306a36Sopenharmony_ci			goto bail;
64962306a36Sopenharmony_ci		}
65062306a36Sopenharmony_ci
65162306a36Sopenharmony_ci		if (je32_to_cpu(node->i.dsize)) {
65262306a36Sopenharmony_ci			crc = crc32(0, node->i.data, je32_to_cpu(node->i.csize));
65362306a36Sopenharmony_ci			if (je32_to_cpu(node->i.data_crc) != crc) {
65462306a36Sopenharmony_ci				pr_warn("Data CRC failed on REF_PRISTINE data node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
65562306a36Sopenharmony_ci					ref_offset(raw),
65662306a36Sopenharmony_ci					je32_to_cpu(node->i.data_crc), crc);
65762306a36Sopenharmony_ci				goto bail;
65862306a36Sopenharmony_ci			}
65962306a36Sopenharmony_ci		}
66062306a36Sopenharmony_ci		break;
66162306a36Sopenharmony_ci
66262306a36Sopenharmony_ci	case JFFS2_NODETYPE_DIRENT:
66362306a36Sopenharmony_ci		crc = crc32(0, node, sizeof(node->d)-8);
66462306a36Sopenharmony_ci		if (je32_to_cpu(node->d.node_crc) != crc) {
66562306a36Sopenharmony_ci			pr_warn("Node CRC failed on REF_PRISTINE dirent node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
66662306a36Sopenharmony_ci				ref_offset(raw),
66762306a36Sopenharmony_ci				je32_to_cpu(node->d.node_crc), crc);
66862306a36Sopenharmony_ci			goto bail;
66962306a36Sopenharmony_ci		}
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_ci		if (strnlen(node->d.name, node->d.nsize) != node->d.nsize) {
67262306a36Sopenharmony_ci			pr_warn("Name in dirent node at 0x%08x contains zeroes\n",
67362306a36Sopenharmony_ci				ref_offset(raw));
67462306a36Sopenharmony_ci			goto bail;
67562306a36Sopenharmony_ci		}
67662306a36Sopenharmony_ci
67762306a36Sopenharmony_ci		if (node->d.nsize) {
67862306a36Sopenharmony_ci			crc = crc32(0, node->d.name, node->d.nsize);
67962306a36Sopenharmony_ci			if (je32_to_cpu(node->d.name_crc) != crc) {
68062306a36Sopenharmony_ci				pr_warn("Name CRC failed on REF_PRISTINE dirent node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
68162306a36Sopenharmony_ci					ref_offset(raw),
68262306a36Sopenharmony_ci					je32_to_cpu(node->d.name_crc), crc);
68362306a36Sopenharmony_ci				goto bail;
68462306a36Sopenharmony_ci			}
68562306a36Sopenharmony_ci		}
68662306a36Sopenharmony_ci		break;
68762306a36Sopenharmony_ci	default:
68862306a36Sopenharmony_ci		/* If it's inode-less, we don't _know_ what it is. Just copy it intact */
68962306a36Sopenharmony_ci		if (ic) {
69062306a36Sopenharmony_ci			pr_warn("Unknown node type for REF_PRISTINE node at 0x%08x: 0x%04x\n",
69162306a36Sopenharmony_ci				ref_offset(raw), je16_to_cpu(node->u.nodetype));
69262306a36Sopenharmony_ci			goto bail;
69362306a36Sopenharmony_ci		}
69462306a36Sopenharmony_ci	}
69562306a36Sopenharmony_ci
69662306a36Sopenharmony_ci	/* OK, all the CRCs are good; this node can just be copied as-is. */
69762306a36Sopenharmony_ci retry:
69862306a36Sopenharmony_ci	phys_ofs = write_ofs(c);
69962306a36Sopenharmony_ci
70062306a36Sopenharmony_ci	ret = jffs2_flash_write(c, phys_ofs, rawlen, &retlen, (char *)node);
70162306a36Sopenharmony_ci
70262306a36Sopenharmony_ci	if (ret || (retlen != rawlen)) {
70362306a36Sopenharmony_ci		pr_notice("Write of %d bytes at 0x%08x failed. returned %d, retlen %zd\n",
70462306a36Sopenharmony_ci			  rawlen, phys_ofs, ret, retlen);
70562306a36Sopenharmony_ci		if (retlen) {
70662306a36Sopenharmony_ci			jffs2_add_physical_node_ref(c, phys_ofs | REF_OBSOLETE, rawlen, NULL);
70762306a36Sopenharmony_ci		} else {
70862306a36Sopenharmony_ci			pr_notice("Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n",
70962306a36Sopenharmony_ci				  phys_ofs);
71062306a36Sopenharmony_ci		}
71162306a36Sopenharmony_ci		if (!retried) {
71262306a36Sopenharmony_ci			/* Try to reallocate space and retry */
71362306a36Sopenharmony_ci			uint32_t dummy;
71462306a36Sopenharmony_ci			struct jffs2_eraseblock *jeb = &c->blocks[phys_ofs / c->sector_size];
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_ci			retried = 1;
71762306a36Sopenharmony_ci
71862306a36Sopenharmony_ci			jffs2_dbg(1, "Retrying failed write of REF_PRISTINE node.\n");
71962306a36Sopenharmony_ci
72062306a36Sopenharmony_ci			jffs2_dbg_acct_sanity_check(c,jeb);
72162306a36Sopenharmony_ci			jffs2_dbg_acct_paranoia_check(c, jeb);
72262306a36Sopenharmony_ci
72362306a36Sopenharmony_ci			ret = jffs2_reserve_space_gc(c, rawlen, &dummy, rawlen);
72462306a36Sopenharmony_ci						/* this is not the exact summary size of it,
72562306a36Sopenharmony_ci							it is only an upper estimation */
72662306a36Sopenharmony_ci
72762306a36Sopenharmony_ci			if (!ret) {
72862306a36Sopenharmony_ci				jffs2_dbg(1, "Allocated space at 0x%08x to retry failed write.\n",
72962306a36Sopenharmony_ci					  phys_ofs);
73062306a36Sopenharmony_ci
73162306a36Sopenharmony_ci				jffs2_dbg_acct_sanity_check(c,jeb);
73262306a36Sopenharmony_ci				jffs2_dbg_acct_paranoia_check(c, jeb);
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_ci				goto retry;
73562306a36Sopenharmony_ci			}
73662306a36Sopenharmony_ci			jffs2_dbg(1, "Failed to allocate space to retry failed write: %d!\n",
73762306a36Sopenharmony_ci				  ret);
73862306a36Sopenharmony_ci		}
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_ci		if (!ret)
74162306a36Sopenharmony_ci			ret = -EIO;
74262306a36Sopenharmony_ci		goto out_node;
74362306a36Sopenharmony_ci	}
74462306a36Sopenharmony_ci	jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, rawlen, ic);
74562306a36Sopenharmony_ci
74662306a36Sopenharmony_ci	jffs2_mark_node_obsolete(c, raw);
74762306a36Sopenharmony_ci	jffs2_dbg(1, "WHEEE! GC REF_PRISTINE node at 0x%08x succeeded\n",
74862306a36Sopenharmony_ci		  ref_offset(raw));
74962306a36Sopenharmony_ci
75062306a36Sopenharmony_ci out_node:
75162306a36Sopenharmony_ci	kfree(node);
75262306a36Sopenharmony_ci	return ret;
75362306a36Sopenharmony_ci bail:
75462306a36Sopenharmony_ci	ret = -EBADFD;
75562306a36Sopenharmony_ci	goto out_node;
75662306a36Sopenharmony_ci}
75762306a36Sopenharmony_ci
75862306a36Sopenharmony_cistatic int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
75962306a36Sopenharmony_ci					struct jffs2_inode_info *f, struct jffs2_full_dnode *fn)
76062306a36Sopenharmony_ci{
76162306a36Sopenharmony_ci	struct jffs2_full_dnode *new_fn;
76262306a36Sopenharmony_ci	struct jffs2_raw_inode ri;
76362306a36Sopenharmony_ci	struct jffs2_node_frag *last_frag;
76462306a36Sopenharmony_ci	union jffs2_device_node dev;
76562306a36Sopenharmony_ci	char *mdata = NULL;
76662306a36Sopenharmony_ci	int mdatalen = 0;
76762306a36Sopenharmony_ci	uint32_t alloclen, ilen;
76862306a36Sopenharmony_ci	int ret;
76962306a36Sopenharmony_ci
77062306a36Sopenharmony_ci	if (S_ISBLK(JFFS2_F_I_MODE(f)) ||
77162306a36Sopenharmony_ci	    S_ISCHR(JFFS2_F_I_MODE(f)) ) {
77262306a36Sopenharmony_ci		/* For these, we don't actually need to read the old node */
77362306a36Sopenharmony_ci		mdatalen = jffs2_encode_dev(&dev, JFFS2_F_I_RDEV(f));
77462306a36Sopenharmony_ci		mdata = (char *)&dev;
77562306a36Sopenharmony_ci		jffs2_dbg(1, "%s(): Writing %d bytes of kdev_t\n",
77662306a36Sopenharmony_ci			  __func__, mdatalen);
77762306a36Sopenharmony_ci	} else if (S_ISLNK(JFFS2_F_I_MODE(f))) {
77862306a36Sopenharmony_ci		mdatalen = fn->size;
77962306a36Sopenharmony_ci		mdata = kmalloc(fn->size, GFP_KERNEL);
78062306a36Sopenharmony_ci		if (!mdata) {
78162306a36Sopenharmony_ci			pr_warn("kmalloc of mdata failed in jffs2_garbage_collect_metadata()\n");
78262306a36Sopenharmony_ci			return -ENOMEM;
78362306a36Sopenharmony_ci		}
78462306a36Sopenharmony_ci		ret = jffs2_read_dnode(c, f, fn, mdata, 0, mdatalen);
78562306a36Sopenharmony_ci		if (ret) {
78662306a36Sopenharmony_ci			pr_warn("read of old metadata failed in jffs2_garbage_collect_metadata(): %d\n",
78762306a36Sopenharmony_ci				ret);
78862306a36Sopenharmony_ci			kfree(mdata);
78962306a36Sopenharmony_ci			return ret;
79062306a36Sopenharmony_ci		}
79162306a36Sopenharmony_ci		jffs2_dbg(1, "%s(): Writing %d bites of symlink target\n",
79262306a36Sopenharmony_ci			  __func__, mdatalen);
79362306a36Sopenharmony_ci
79462306a36Sopenharmony_ci	}
79562306a36Sopenharmony_ci
79662306a36Sopenharmony_ci	ret = jffs2_reserve_space_gc(c, sizeof(ri) + mdatalen, &alloclen,
79762306a36Sopenharmony_ci				JFFS2_SUMMARY_INODE_SIZE);
79862306a36Sopenharmony_ci	if (ret) {
79962306a36Sopenharmony_ci		pr_warn("jffs2_reserve_space_gc of %zd bytes for garbage_collect_metadata failed: %d\n",
80062306a36Sopenharmony_ci			sizeof(ri) + mdatalen, ret);
80162306a36Sopenharmony_ci		goto out;
80262306a36Sopenharmony_ci	}
80362306a36Sopenharmony_ci
80462306a36Sopenharmony_ci	last_frag = frag_last(&f->fragtree);
80562306a36Sopenharmony_ci	if (last_frag)
80662306a36Sopenharmony_ci		/* Fetch the inode length from the fragtree rather then
80762306a36Sopenharmony_ci		 * from i_size since i_size may have not been updated yet */
80862306a36Sopenharmony_ci		ilen = last_frag->ofs + last_frag->size;
80962306a36Sopenharmony_ci	else
81062306a36Sopenharmony_ci		ilen = JFFS2_F_I_SIZE(f);
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_ci	memset(&ri, 0, sizeof(ri));
81362306a36Sopenharmony_ci	ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
81462306a36Sopenharmony_ci	ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
81562306a36Sopenharmony_ci	ri.totlen = cpu_to_je32(sizeof(ri) + mdatalen);
81662306a36Sopenharmony_ci	ri.hdr_crc = cpu_to_je32(crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4));
81762306a36Sopenharmony_ci
81862306a36Sopenharmony_ci	ri.ino = cpu_to_je32(f->inocache->ino);
81962306a36Sopenharmony_ci	ri.version = cpu_to_je32(++f->highest_version);
82062306a36Sopenharmony_ci	ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f));
82162306a36Sopenharmony_ci	ri.uid = cpu_to_je16(JFFS2_F_I_UID(f));
82262306a36Sopenharmony_ci	ri.gid = cpu_to_je16(JFFS2_F_I_GID(f));
82362306a36Sopenharmony_ci	ri.isize = cpu_to_je32(ilen);
82462306a36Sopenharmony_ci	ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f));
82562306a36Sopenharmony_ci	ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f));
82662306a36Sopenharmony_ci	ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f));
82762306a36Sopenharmony_ci	ri.offset = cpu_to_je32(0);
82862306a36Sopenharmony_ci	ri.csize = cpu_to_je32(mdatalen);
82962306a36Sopenharmony_ci	ri.dsize = cpu_to_je32(mdatalen);
83062306a36Sopenharmony_ci	ri.compr = JFFS2_COMPR_NONE;
83162306a36Sopenharmony_ci	ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
83262306a36Sopenharmony_ci	ri.data_crc = cpu_to_je32(crc32(0, mdata, mdatalen));
83362306a36Sopenharmony_ci
83462306a36Sopenharmony_ci	new_fn = jffs2_write_dnode(c, f, &ri, mdata, mdatalen, ALLOC_GC);
83562306a36Sopenharmony_ci
83662306a36Sopenharmony_ci	if (IS_ERR(new_fn)) {
83762306a36Sopenharmony_ci		pr_warn("Error writing new dnode: %ld\n", PTR_ERR(new_fn));
83862306a36Sopenharmony_ci		ret = PTR_ERR(new_fn);
83962306a36Sopenharmony_ci		goto out;
84062306a36Sopenharmony_ci	}
84162306a36Sopenharmony_ci	jffs2_mark_node_obsolete(c, fn->raw);
84262306a36Sopenharmony_ci	jffs2_free_full_dnode(fn);
84362306a36Sopenharmony_ci	f->metadata = new_fn;
84462306a36Sopenharmony_ci out:
84562306a36Sopenharmony_ci	if (S_ISLNK(JFFS2_F_I_MODE(f)))
84662306a36Sopenharmony_ci		kfree(mdata);
84762306a36Sopenharmony_ci	return ret;
84862306a36Sopenharmony_ci}
84962306a36Sopenharmony_ci
85062306a36Sopenharmony_cistatic int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
85162306a36Sopenharmony_ci					struct jffs2_inode_info *f, struct jffs2_full_dirent *fd)
85262306a36Sopenharmony_ci{
85362306a36Sopenharmony_ci	struct jffs2_full_dirent *new_fd;
85462306a36Sopenharmony_ci	struct jffs2_raw_dirent rd;
85562306a36Sopenharmony_ci	uint32_t alloclen;
85662306a36Sopenharmony_ci	int ret;
85762306a36Sopenharmony_ci
85862306a36Sopenharmony_ci	rd.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
85962306a36Sopenharmony_ci	rd.nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT);
86062306a36Sopenharmony_ci	rd.nsize = strlen(fd->name);
86162306a36Sopenharmony_ci	rd.totlen = cpu_to_je32(sizeof(rd) + rd.nsize);
86262306a36Sopenharmony_ci	rd.hdr_crc = cpu_to_je32(crc32(0, &rd, sizeof(struct jffs2_unknown_node)-4));
86362306a36Sopenharmony_ci
86462306a36Sopenharmony_ci	rd.pino = cpu_to_je32(f->inocache->ino);
86562306a36Sopenharmony_ci	rd.version = cpu_to_je32(++f->highest_version);
86662306a36Sopenharmony_ci	rd.ino = cpu_to_je32(fd->ino);
86762306a36Sopenharmony_ci	/* If the times on this inode were set by explicit utime() they can be different,
86862306a36Sopenharmony_ci	   so refrain from splatting them. */
86962306a36Sopenharmony_ci	if (JFFS2_F_I_MTIME(f) == JFFS2_F_I_CTIME(f))
87062306a36Sopenharmony_ci		rd.mctime = cpu_to_je32(JFFS2_F_I_MTIME(f));
87162306a36Sopenharmony_ci	else
87262306a36Sopenharmony_ci		rd.mctime = cpu_to_je32(0);
87362306a36Sopenharmony_ci	rd.type = fd->type;
87462306a36Sopenharmony_ci	rd.node_crc = cpu_to_je32(crc32(0, &rd, sizeof(rd)-8));
87562306a36Sopenharmony_ci	rd.name_crc = cpu_to_je32(crc32(0, fd->name, rd.nsize));
87662306a36Sopenharmony_ci
87762306a36Sopenharmony_ci	ret = jffs2_reserve_space_gc(c, sizeof(rd)+rd.nsize, &alloclen,
87862306a36Sopenharmony_ci				JFFS2_SUMMARY_DIRENT_SIZE(rd.nsize));
87962306a36Sopenharmony_ci	if (ret) {
88062306a36Sopenharmony_ci		pr_warn("jffs2_reserve_space_gc of %zd bytes for garbage_collect_dirent failed: %d\n",
88162306a36Sopenharmony_ci			sizeof(rd)+rd.nsize, ret);
88262306a36Sopenharmony_ci		return ret;
88362306a36Sopenharmony_ci	}
88462306a36Sopenharmony_ci	new_fd = jffs2_write_dirent(c, f, &rd, fd->name, rd.nsize, ALLOC_GC);
88562306a36Sopenharmony_ci
88662306a36Sopenharmony_ci	if (IS_ERR(new_fd)) {
88762306a36Sopenharmony_ci		pr_warn("jffs2_write_dirent in garbage_collect_dirent failed: %ld\n",
88862306a36Sopenharmony_ci			PTR_ERR(new_fd));
88962306a36Sopenharmony_ci		return PTR_ERR(new_fd);
89062306a36Sopenharmony_ci	}
89162306a36Sopenharmony_ci	jffs2_add_fd_to_list(c, new_fd, &f->dents);
89262306a36Sopenharmony_ci	return 0;
89362306a36Sopenharmony_ci}
89462306a36Sopenharmony_ci
89562306a36Sopenharmony_cistatic int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
89662306a36Sopenharmony_ci					struct jffs2_inode_info *f, struct jffs2_full_dirent *fd)
89762306a36Sopenharmony_ci{
89862306a36Sopenharmony_ci	struct jffs2_full_dirent **fdp = &f->dents;
89962306a36Sopenharmony_ci	int found = 0;
90062306a36Sopenharmony_ci
90162306a36Sopenharmony_ci	/* On a medium where we can't actually mark nodes obsolete
90262306a36Sopenharmony_ci	   pernamently, such as NAND flash, we need to work out
90362306a36Sopenharmony_ci	   whether this deletion dirent is still needed to actively
90462306a36Sopenharmony_ci	   delete a 'real' dirent with the same name that's still
90562306a36Sopenharmony_ci	   somewhere else on the flash. */
90662306a36Sopenharmony_ci	if (!jffs2_can_mark_obsolete(c)) {
90762306a36Sopenharmony_ci		struct jffs2_raw_dirent *rd;
90862306a36Sopenharmony_ci		struct jffs2_raw_node_ref *raw;
90962306a36Sopenharmony_ci		int ret;
91062306a36Sopenharmony_ci		size_t retlen;
91162306a36Sopenharmony_ci		int name_len = strlen(fd->name);
91262306a36Sopenharmony_ci		uint32_t name_crc = crc32(0, fd->name, name_len);
91362306a36Sopenharmony_ci		uint32_t rawlen = ref_totlen(c, jeb, fd->raw);
91462306a36Sopenharmony_ci
91562306a36Sopenharmony_ci		rd = kmalloc(rawlen, GFP_KERNEL);
91662306a36Sopenharmony_ci		if (!rd)
91762306a36Sopenharmony_ci			return -ENOMEM;
91862306a36Sopenharmony_ci
91962306a36Sopenharmony_ci		/* Prevent the erase code from nicking the obsolete node refs while
92062306a36Sopenharmony_ci		   we're looking at them. I really don't like this extra lock but
92162306a36Sopenharmony_ci		   can't see any alternative. Suggestions on a postcard to... */
92262306a36Sopenharmony_ci		mutex_lock(&c->erase_free_sem);
92362306a36Sopenharmony_ci
92462306a36Sopenharmony_ci		for (raw = f->inocache->nodes; raw != (void *)f->inocache; raw = raw->next_in_ino) {
92562306a36Sopenharmony_ci
92662306a36Sopenharmony_ci			cond_resched();
92762306a36Sopenharmony_ci
92862306a36Sopenharmony_ci			/* We only care about obsolete ones */
92962306a36Sopenharmony_ci			if (!(ref_obsolete(raw)))
93062306a36Sopenharmony_ci				continue;
93162306a36Sopenharmony_ci
93262306a36Sopenharmony_ci			/* Any dirent with the same name is going to have the same length... */
93362306a36Sopenharmony_ci			if (ref_totlen(c, NULL, raw) != rawlen)
93462306a36Sopenharmony_ci				continue;
93562306a36Sopenharmony_ci
93662306a36Sopenharmony_ci			/* Doesn't matter if there's one in the same erase block. We're going to
93762306a36Sopenharmony_ci			   delete it too at the same time. */
93862306a36Sopenharmony_ci			if (SECTOR_ADDR(raw->flash_offset) == SECTOR_ADDR(fd->raw->flash_offset))
93962306a36Sopenharmony_ci				continue;
94062306a36Sopenharmony_ci
94162306a36Sopenharmony_ci			jffs2_dbg(1, "Check potential deletion dirent at %08x\n",
94262306a36Sopenharmony_ci				  ref_offset(raw));
94362306a36Sopenharmony_ci
94462306a36Sopenharmony_ci			/* This is an obsolete node belonging to the same directory, and it's of the right
94562306a36Sopenharmony_ci			   length. We need to take a closer look...*/
94662306a36Sopenharmony_ci			ret = jffs2_flash_read(c, ref_offset(raw), rawlen, &retlen, (char *)rd);
94762306a36Sopenharmony_ci			if (ret) {
94862306a36Sopenharmony_ci				pr_warn("%s(): Read error (%d) reading obsolete node at %08x\n",
94962306a36Sopenharmony_ci					__func__, ret, ref_offset(raw));
95062306a36Sopenharmony_ci				/* If we can't read it, we don't need to continue to obsolete it. Continue */
95162306a36Sopenharmony_ci				continue;
95262306a36Sopenharmony_ci			}
95362306a36Sopenharmony_ci			if (retlen != rawlen) {
95462306a36Sopenharmony_ci				pr_warn("%s(): Short read (%zd not %u) reading header from obsolete node at %08x\n",
95562306a36Sopenharmony_ci					__func__, retlen, rawlen,
95662306a36Sopenharmony_ci					ref_offset(raw));
95762306a36Sopenharmony_ci				continue;
95862306a36Sopenharmony_ci			}
95962306a36Sopenharmony_ci
96062306a36Sopenharmony_ci			if (je16_to_cpu(rd->nodetype) != JFFS2_NODETYPE_DIRENT)
96162306a36Sopenharmony_ci				continue;
96262306a36Sopenharmony_ci
96362306a36Sopenharmony_ci			/* If the name CRC doesn't match, skip */
96462306a36Sopenharmony_ci			if (je32_to_cpu(rd->name_crc) != name_crc)
96562306a36Sopenharmony_ci				continue;
96662306a36Sopenharmony_ci
96762306a36Sopenharmony_ci			/* If the name length doesn't match, or it's another deletion dirent, skip */
96862306a36Sopenharmony_ci			if (rd->nsize != name_len || !je32_to_cpu(rd->ino))
96962306a36Sopenharmony_ci				continue;
97062306a36Sopenharmony_ci
97162306a36Sopenharmony_ci			/* OK, check the actual name now */
97262306a36Sopenharmony_ci			if (memcmp(rd->name, fd->name, name_len))
97362306a36Sopenharmony_ci				continue;
97462306a36Sopenharmony_ci
97562306a36Sopenharmony_ci			/* OK. The name really does match. There really is still an older node on
97662306a36Sopenharmony_ci			   the flash which our deletion dirent obsoletes. So we have to write out
97762306a36Sopenharmony_ci			   a new deletion dirent to replace it */
97862306a36Sopenharmony_ci			mutex_unlock(&c->erase_free_sem);
97962306a36Sopenharmony_ci
98062306a36Sopenharmony_ci			jffs2_dbg(1, "Deletion dirent at %08x still obsoletes real dirent \"%s\" at %08x for ino #%u\n",
98162306a36Sopenharmony_ci				  ref_offset(fd->raw), fd->name,
98262306a36Sopenharmony_ci				  ref_offset(raw), je32_to_cpu(rd->ino));
98362306a36Sopenharmony_ci			kfree(rd);
98462306a36Sopenharmony_ci
98562306a36Sopenharmony_ci			return jffs2_garbage_collect_dirent(c, jeb, f, fd);
98662306a36Sopenharmony_ci		}
98762306a36Sopenharmony_ci
98862306a36Sopenharmony_ci		mutex_unlock(&c->erase_free_sem);
98962306a36Sopenharmony_ci		kfree(rd);
99062306a36Sopenharmony_ci	}
99162306a36Sopenharmony_ci
99262306a36Sopenharmony_ci	/* FIXME: If we're deleting a dirent which contains the current mtime and ctime,
99362306a36Sopenharmony_ci	   we should update the metadata node with those times accordingly */
99462306a36Sopenharmony_ci
99562306a36Sopenharmony_ci	/* No need for it any more. Just mark it obsolete and remove it from the list */
99662306a36Sopenharmony_ci	while (*fdp) {
99762306a36Sopenharmony_ci		if ((*fdp) == fd) {
99862306a36Sopenharmony_ci			found = 1;
99962306a36Sopenharmony_ci			*fdp = fd->next;
100062306a36Sopenharmony_ci			break;
100162306a36Sopenharmony_ci		}
100262306a36Sopenharmony_ci		fdp = &(*fdp)->next;
100362306a36Sopenharmony_ci	}
100462306a36Sopenharmony_ci	if (!found) {
100562306a36Sopenharmony_ci		pr_warn("Deletion dirent \"%s\" not found in list for ino #%u\n",
100662306a36Sopenharmony_ci			fd->name, f->inocache->ino);
100762306a36Sopenharmony_ci	}
100862306a36Sopenharmony_ci	jffs2_mark_node_obsolete(c, fd->raw);
100962306a36Sopenharmony_ci	jffs2_free_full_dirent(fd);
101062306a36Sopenharmony_ci	return 0;
101162306a36Sopenharmony_ci}
101262306a36Sopenharmony_ci
101362306a36Sopenharmony_cistatic int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
101462306a36Sopenharmony_ci				      struct jffs2_inode_info *f, struct jffs2_full_dnode *fn,
101562306a36Sopenharmony_ci				      uint32_t start, uint32_t end)
101662306a36Sopenharmony_ci{
101762306a36Sopenharmony_ci	struct jffs2_raw_inode ri;
101862306a36Sopenharmony_ci	struct jffs2_node_frag *frag;
101962306a36Sopenharmony_ci	struct jffs2_full_dnode *new_fn;
102062306a36Sopenharmony_ci	uint32_t alloclen, ilen;
102162306a36Sopenharmony_ci	int ret;
102262306a36Sopenharmony_ci
102362306a36Sopenharmony_ci	jffs2_dbg(1, "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n",
102462306a36Sopenharmony_ci		  f->inocache->ino, start, end);
102562306a36Sopenharmony_ci
102662306a36Sopenharmony_ci	memset(&ri, 0, sizeof(ri));
102762306a36Sopenharmony_ci
102862306a36Sopenharmony_ci	if(fn->frags > 1) {
102962306a36Sopenharmony_ci		size_t readlen;
103062306a36Sopenharmony_ci		uint32_t crc;
103162306a36Sopenharmony_ci		/* It's partially obsoleted by a later write. So we have to
103262306a36Sopenharmony_ci		   write it out again with the _same_ version as before */
103362306a36Sopenharmony_ci		ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(ri), &readlen, (char *)&ri);
103462306a36Sopenharmony_ci		if (readlen != sizeof(ri) || ret) {
103562306a36Sopenharmony_ci			pr_warn("Node read failed in jffs2_garbage_collect_hole. Ret %d, retlen %zd. Data will be lost by writing new hole node\n",
103662306a36Sopenharmony_ci				ret, readlen);
103762306a36Sopenharmony_ci			goto fill;
103862306a36Sopenharmony_ci		}
103962306a36Sopenharmony_ci		if (je16_to_cpu(ri.nodetype) != JFFS2_NODETYPE_INODE) {
104062306a36Sopenharmony_ci			pr_warn("%s(): Node at 0x%08x had node type 0x%04x instead of JFFS2_NODETYPE_INODE(0x%04x)\n",
104162306a36Sopenharmony_ci				__func__, ref_offset(fn->raw),
104262306a36Sopenharmony_ci				je16_to_cpu(ri.nodetype), JFFS2_NODETYPE_INODE);
104362306a36Sopenharmony_ci			return -EIO;
104462306a36Sopenharmony_ci		}
104562306a36Sopenharmony_ci		if (je32_to_cpu(ri.totlen) != sizeof(ri)) {
104662306a36Sopenharmony_ci			pr_warn("%s(): Node at 0x%08x had totlen 0x%x instead of expected 0x%zx\n",
104762306a36Sopenharmony_ci				__func__, ref_offset(fn->raw),
104862306a36Sopenharmony_ci				je32_to_cpu(ri.totlen), sizeof(ri));
104962306a36Sopenharmony_ci			return -EIO;
105062306a36Sopenharmony_ci		}
105162306a36Sopenharmony_ci		crc = crc32(0, &ri, sizeof(ri)-8);
105262306a36Sopenharmony_ci		if (crc != je32_to_cpu(ri.node_crc)) {
105362306a36Sopenharmony_ci			pr_warn("%s: Node at 0x%08x had CRC 0x%08x which doesn't match calculated CRC 0x%08x\n",
105462306a36Sopenharmony_ci				__func__, ref_offset(fn->raw),
105562306a36Sopenharmony_ci				je32_to_cpu(ri.node_crc), crc);
105662306a36Sopenharmony_ci			/* FIXME: We could possibly deal with this by writing new holes for each frag */
105762306a36Sopenharmony_ci			pr_warn("Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n",
105862306a36Sopenharmony_ci				start, end, f->inocache->ino);
105962306a36Sopenharmony_ci			goto fill;
106062306a36Sopenharmony_ci		}
106162306a36Sopenharmony_ci		if (ri.compr != JFFS2_COMPR_ZERO) {
106262306a36Sopenharmony_ci			pr_warn("%s(): Node 0x%08x wasn't a hole node!\n",
106362306a36Sopenharmony_ci				__func__, ref_offset(fn->raw));
106462306a36Sopenharmony_ci			pr_warn("Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n",
106562306a36Sopenharmony_ci				start, end, f->inocache->ino);
106662306a36Sopenharmony_ci			goto fill;
106762306a36Sopenharmony_ci		}
106862306a36Sopenharmony_ci	} else {
106962306a36Sopenharmony_ci	fill:
107062306a36Sopenharmony_ci		ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
107162306a36Sopenharmony_ci		ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
107262306a36Sopenharmony_ci		ri.totlen = cpu_to_je32(sizeof(ri));
107362306a36Sopenharmony_ci		ri.hdr_crc = cpu_to_je32(crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4));
107462306a36Sopenharmony_ci
107562306a36Sopenharmony_ci		ri.ino = cpu_to_je32(f->inocache->ino);
107662306a36Sopenharmony_ci		ri.version = cpu_to_je32(++f->highest_version);
107762306a36Sopenharmony_ci		ri.offset = cpu_to_je32(start);
107862306a36Sopenharmony_ci		ri.dsize = cpu_to_je32(end - start);
107962306a36Sopenharmony_ci		ri.csize = cpu_to_je32(0);
108062306a36Sopenharmony_ci		ri.compr = JFFS2_COMPR_ZERO;
108162306a36Sopenharmony_ci	}
108262306a36Sopenharmony_ci
108362306a36Sopenharmony_ci	frag = frag_last(&f->fragtree);
108462306a36Sopenharmony_ci	if (frag)
108562306a36Sopenharmony_ci		/* Fetch the inode length from the fragtree rather then
108662306a36Sopenharmony_ci		 * from i_size since i_size may have not been updated yet */
108762306a36Sopenharmony_ci		ilen = frag->ofs + frag->size;
108862306a36Sopenharmony_ci	else
108962306a36Sopenharmony_ci		ilen = JFFS2_F_I_SIZE(f);
109062306a36Sopenharmony_ci
109162306a36Sopenharmony_ci	ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f));
109262306a36Sopenharmony_ci	ri.uid = cpu_to_je16(JFFS2_F_I_UID(f));
109362306a36Sopenharmony_ci	ri.gid = cpu_to_je16(JFFS2_F_I_GID(f));
109462306a36Sopenharmony_ci	ri.isize = cpu_to_je32(ilen);
109562306a36Sopenharmony_ci	ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f));
109662306a36Sopenharmony_ci	ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f));
109762306a36Sopenharmony_ci	ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f));
109862306a36Sopenharmony_ci	ri.data_crc = cpu_to_je32(0);
109962306a36Sopenharmony_ci	ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
110062306a36Sopenharmony_ci
110162306a36Sopenharmony_ci	ret = jffs2_reserve_space_gc(c, sizeof(ri), &alloclen,
110262306a36Sopenharmony_ci				     JFFS2_SUMMARY_INODE_SIZE);
110362306a36Sopenharmony_ci	if (ret) {
110462306a36Sopenharmony_ci		pr_warn("jffs2_reserve_space_gc of %zd bytes for garbage_collect_hole failed: %d\n",
110562306a36Sopenharmony_ci			sizeof(ri), ret);
110662306a36Sopenharmony_ci		return ret;
110762306a36Sopenharmony_ci	}
110862306a36Sopenharmony_ci	new_fn = jffs2_write_dnode(c, f, &ri, NULL, 0, ALLOC_GC);
110962306a36Sopenharmony_ci
111062306a36Sopenharmony_ci	if (IS_ERR(new_fn)) {
111162306a36Sopenharmony_ci		pr_warn("Error writing new hole node: %ld\n", PTR_ERR(new_fn));
111262306a36Sopenharmony_ci		return PTR_ERR(new_fn);
111362306a36Sopenharmony_ci	}
111462306a36Sopenharmony_ci	if (je32_to_cpu(ri.version) == f->highest_version) {
111562306a36Sopenharmony_ci		jffs2_add_full_dnode_to_inode(c, f, new_fn);
111662306a36Sopenharmony_ci		if (f->metadata) {
111762306a36Sopenharmony_ci			jffs2_mark_node_obsolete(c, f->metadata->raw);
111862306a36Sopenharmony_ci			jffs2_free_full_dnode(f->metadata);
111962306a36Sopenharmony_ci			f->metadata = NULL;
112062306a36Sopenharmony_ci		}
112162306a36Sopenharmony_ci		return 0;
112262306a36Sopenharmony_ci	}
112362306a36Sopenharmony_ci
112462306a36Sopenharmony_ci	/*
112562306a36Sopenharmony_ci	 * We should only get here in the case where the node we are
112662306a36Sopenharmony_ci	 * replacing had more than one frag, so we kept the same version
112762306a36Sopenharmony_ci	 * number as before. (Except in case of error -- see 'goto fill;'
112862306a36Sopenharmony_ci	 * above.)
112962306a36Sopenharmony_ci	 */
113062306a36Sopenharmony_ci	D1(if(unlikely(fn->frags <= 1)) {
113162306a36Sopenharmony_ci			pr_warn("%s(): Replacing fn with %d frag(s) but new ver %d != highest_version %d of ino #%d\n",
113262306a36Sopenharmony_ci				__func__, fn->frags, je32_to_cpu(ri.version),
113362306a36Sopenharmony_ci				f->highest_version, je32_to_cpu(ri.ino));
113462306a36Sopenharmony_ci	});
113562306a36Sopenharmony_ci
113662306a36Sopenharmony_ci	/* This is a partially-overlapped hole node. Mark it REF_NORMAL not REF_PRISTINE */
113762306a36Sopenharmony_ci	mark_ref_normal(new_fn->raw);
113862306a36Sopenharmony_ci
113962306a36Sopenharmony_ci	for (frag = jffs2_lookup_node_frag(&f->fragtree, fn->ofs);
114062306a36Sopenharmony_ci	     frag; frag = frag_next(frag)) {
114162306a36Sopenharmony_ci		if (frag->ofs > fn->size + fn->ofs)
114262306a36Sopenharmony_ci			break;
114362306a36Sopenharmony_ci		if (frag->node == fn) {
114462306a36Sopenharmony_ci			frag->node = new_fn;
114562306a36Sopenharmony_ci			new_fn->frags++;
114662306a36Sopenharmony_ci			fn->frags--;
114762306a36Sopenharmony_ci		}
114862306a36Sopenharmony_ci	}
114962306a36Sopenharmony_ci	if (fn->frags) {
115062306a36Sopenharmony_ci		pr_warn("%s(): Old node still has frags!\n", __func__);
115162306a36Sopenharmony_ci		BUG();
115262306a36Sopenharmony_ci	}
115362306a36Sopenharmony_ci	if (!new_fn->frags) {
115462306a36Sopenharmony_ci		pr_warn("%s(): New node has no frags!\n", __func__);
115562306a36Sopenharmony_ci		BUG();
115662306a36Sopenharmony_ci	}
115762306a36Sopenharmony_ci
115862306a36Sopenharmony_ci	jffs2_mark_node_obsolete(c, fn->raw);
115962306a36Sopenharmony_ci	jffs2_free_full_dnode(fn);
116062306a36Sopenharmony_ci
116162306a36Sopenharmony_ci	return 0;
116262306a36Sopenharmony_ci}
116362306a36Sopenharmony_ci
116462306a36Sopenharmony_cistatic int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *orig_jeb,
116562306a36Sopenharmony_ci				       struct jffs2_inode_info *f, struct jffs2_full_dnode *fn,
116662306a36Sopenharmony_ci				       uint32_t start, uint32_t end)
116762306a36Sopenharmony_ci{
116862306a36Sopenharmony_ci	struct inode *inode = OFNI_EDONI_2SFFJ(f);
116962306a36Sopenharmony_ci	struct jffs2_full_dnode *new_fn;
117062306a36Sopenharmony_ci	struct jffs2_raw_inode ri;
117162306a36Sopenharmony_ci	uint32_t alloclen, offset, orig_end, orig_start;
117262306a36Sopenharmony_ci	int ret = 0;
117362306a36Sopenharmony_ci	unsigned char *comprbuf = NULL, *writebuf;
117462306a36Sopenharmony_ci	struct page *page;
117562306a36Sopenharmony_ci	unsigned char *pg_ptr;
117662306a36Sopenharmony_ci
117762306a36Sopenharmony_ci	memset(&ri, 0, sizeof(ri));
117862306a36Sopenharmony_ci
117962306a36Sopenharmony_ci	jffs2_dbg(1, "Writing replacement dnode for ino #%u from offset 0x%x to 0x%x\n",
118062306a36Sopenharmony_ci		  f->inocache->ino, start, end);
118162306a36Sopenharmony_ci
118262306a36Sopenharmony_ci	orig_end = end;
118362306a36Sopenharmony_ci	orig_start = start;
118462306a36Sopenharmony_ci
118562306a36Sopenharmony_ci	if (c->nr_free_blocks + c->nr_erasing_blocks > c->resv_blocks_gcmerge) {
118662306a36Sopenharmony_ci		/* Attempt to do some merging. But only expand to cover logically
118762306a36Sopenharmony_ci		   adjacent frags if the block containing them is already considered
118862306a36Sopenharmony_ci		   to be dirty. Otherwise we end up with GC just going round in
118962306a36Sopenharmony_ci		   circles dirtying the nodes it already wrote out, especially
119062306a36Sopenharmony_ci		   on NAND where we have small eraseblocks and hence a much higher
119162306a36Sopenharmony_ci		   chance of nodes having to be split to cross boundaries. */
119262306a36Sopenharmony_ci
119362306a36Sopenharmony_ci		struct jffs2_node_frag *frag;
119462306a36Sopenharmony_ci		uint32_t min, max;
119562306a36Sopenharmony_ci
119662306a36Sopenharmony_ci		min = start & ~(PAGE_SIZE-1);
119762306a36Sopenharmony_ci		max = min + PAGE_SIZE;
119862306a36Sopenharmony_ci
119962306a36Sopenharmony_ci		frag = jffs2_lookup_node_frag(&f->fragtree, start);
120062306a36Sopenharmony_ci
120162306a36Sopenharmony_ci		/* BUG_ON(!frag) but that'll happen anyway... */
120262306a36Sopenharmony_ci
120362306a36Sopenharmony_ci		BUG_ON(frag->ofs != start);
120462306a36Sopenharmony_ci
120562306a36Sopenharmony_ci		/* First grow down... */
120662306a36Sopenharmony_ci		while((frag = frag_prev(frag)) && frag->ofs >= min) {
120762306a36Sopenharmony_ci
120862306a36Sopenharmony_ci			/* If the previous frag doesn't even reach the beginning, there's
120962306a36Sopenharmony_ci			   excessive fragmentation. Just merge. */
121062306a36Sopenharmony_ci			if (frag->ofs > min) {
121162306a36Sopenharmony_ci				jffs2_dbg(1, "Expanding down to cover partial frag (0x%x-0x%x)\n",
121262306a36Sopenharmony_ci					  frag->ofs, frag->ofs+frag->size);
121362306a36Sopenharmony_ci				start = frag->ofs;
121462306a36Sopenharmony_ci				continue;
121562306a36Sopenharmony_ci			}
121662306a36Sopenharmony_ci			/* OK. This frag holds the first byte of the page. */
121762306a36Sopenharmony_ci			if (!frag->node || !frag->node->raw) {
121862306a36Sopenharmony_ci				jffs2_dbg(1, "First frag in page is hole (0x%x-0x%x). Not expanding down.\n",
121962306a36Sopenharmony_ci					  frag->ofs, frag->ofs+frag->size);
122062306a36Sopenharmony_ci				break;
122162306a36Sopenharmony_ci			} else {
122262306a36Sopenharmony_ci
122362306a36Sopenharmony_ci				/* OK, it's a frag which extends to the beginning of the page. Does it live
122462306a36Sopenharmony_ci				   in a block which is still considered clean? If so, don't obsolete it.
122562306a36Sopenharmony_ci				   If not, cover it anyway. */
122662306a36Sopenharmony_ci
122762306a36Sopenharmony_ci				struct jffs2_raw_node_ref *raw = frag->node->raw;
122862306a36Sopenharmony_ci				struct jffs2_eraseblock *jeb;
122962306a36Sopenharmony_ci
123062306a36Sopenharmony_ci				jeb = &c->blocks[raw->flash_offset / c->sector_size];
123162306a36Sopenharmony_ci
123262306a36Sopenharmony_ci				if (jeb == c->gcblock) {
123362306a36Sopenharmony_ci					jffs2_dbg(1, "Expanding down to cover frag (0x%x-0x%x) in gcblock at %08x\n",
123462306a36Sopenharmony_ci						  frag->ofs,
123562306a36Sopenharmony_ci						  frag->ofs + frag->size,
123662306a36Sopenharmony_ci						  ref_offset(raw));
123762306a36Sopenharmony_ci					start = frag->ofs;
123862306a36Sopenharmony_ci					break;
123962306a36Sopenharmony_ci				}
124062306a36Sopenharmony_ci				if (!ISDIRTY(jeb->dirty_size + jeb->wasted_size)) {
124162306a36Sopenharmony_ci					jffs2_dbg(1, "Not expanding down to cover frag (0x%x-0x%x) in clean block %08x\n",
124262306a36Sopenharmony_ci						  frag->ofs,
124362306a36Sopenharmony_ci						  frag->ofs + frag->size,
124462306a36Sopenharmony_ci						  jeb->offset);
124562306a36Sopenharmony_ci					break;
124662306a36Sopenharmony_ci				}
124762306a36Sopenharmony_ci
124862306a36Sopenharmony_ci				jffs2_dbg(1, "Expanding down to cover frag (0x%x-0x%x) in dirty block %08x\n",
124962306a36Sopenharmony_ci					  frag->ofs,
125062306a36Sopenharmony_ci					  frag->ofs + frag->size,
125162306a36Sopenharmony_ci					  jeb->offset);
125262306a36Sopenharmony_ci				start = frag->ofs;
125362306a36Sopenharmony_ci				break;
125462306a36Sopenharmony_ci			}
125562306a36Sopenharmony_ci		}
125662306a36Sopenharmony_ci
125762306a36Sopenharmony_ci		/* ... then up */
125862306a36Sopenharmony_ci
125962306a36Sopenharmony_ci		/* Find last frag which is actually part of the node we're to GC. */
126062306a36Sopenharmony_ci		frag = jffs2_lookup_node_frag(&f->fragtree, end-1);
126162306a36Sopenharmony_ci
126262306a36Sopenharmony_ci		while((frag = frag_next(frag)) && frag->ofs+frag->size <= max) {
126362306a36Sopenharmony_ci
126462306a36Sopenharmony_ci			/* If the previous frag doesn't even reach the beginning, there's lots
126562306a36Sopenharmony_ci			   of fragmentation. Just merge. */
126662306a36Sopenharmony_ci			if (frag->ofs+frag->size < max) {
126762306a36Sopenharmony_ci				jffs2_dbg(1, "Expanding up to cover partial frag (0x%x-0x%x)\n",
126862306a36Sopenharmony_ci					  frag->ofs, frag->ofs+frag->size);
126962306a36Sopenharmony_ci				end = frag->ofs + frag->size;
127062306a36Sopenharmony_ci				continue;
127162306a36Sopenharmony_ci			}
127262306a36Sopenharmony_ci
127362306a36Sopenharmony_ci			if (!frag->node || !frag->node->raw) {
127462306a36Sopenharmony_ci				jffs2_dbg(1, "Last frag in page is hole (0x%x-0x%x). Not expanding up.\n",
127562306a36Sopenharmony_ci					  frag->ofs, frag->ofs+frag->size);
127662306a36Sopenharmony_ci				break;
127762306a36Sopenharmony_ci			} else {
127862306a36Sopenharmony_ci
127962306a36Sopenharmony_ci				/* OK, it's a frag which extends to the beginning of the page. Does it live
128062306a36Sopenharmony_ci				   in a block which is still considered clean? If so, don't obsolete it.
128162306a36Sopenharmony_ci				   If not, cover it anyway. */
128262306a36Sopenharmony_ci
128362306a36Sopenharmony_ci				struct jffs2_raw_node_ref *raw = frag->node->raw;
128462306a36Sopenharmony_ci				struct jffs2_eraseblock *jeb;
128562306a36Sopenharmony_ci
128662306a36Sopenharmony_ci				jeb = &c->blocks[raw->flash_offset / c->sector_size];
128762306a36Sopenharmony_ci
128862306a36Sopenharmony_ci				if (jeb == c->gcblock) {
128962306a36Sopenharmony_ci					jffs2_dbg(1, "Expanding up to cover frag (0x%x-0x%x) in gcblock at %08x\n",
129062306a36Sopenharmony_ci						  frag->ofs,
129162306a36Sopenharmony_ci						  frag->ofs + frag->size,
129262306a36Sopenharmony_ci						  ref_offset(raw));
129362306a36Sopenharmony_ci					end = frag->ofs + frag->size;
129462306a36Sopenharmony_ci					break;
129562306a36Sopenharmony_ci				}
129662306a36Sopenharmony_ci				if (!ISDIRTY(jeb->dirty_size + jeb->wasted_size)) {
129762306a36Sopenharmony_ci					jffs2_dbg(1, "Not expanding up to cover frag (0x%x-0x%x) in clean block %08x\n",
129862306a36Sopenharmony_ci						  frag->ofs,
129962306a36Sopenharmony_ci						  frag->ofs + frag->size,
130062306a36Sopenharmony_ci						  jeb->offset);
130162306a36Sopenharmony_ci					break;
130262306a36Sopenharmony_ci				}
130362306a36Sopenharmony_ci
130462306a36Sopenharmony_ci				jffs2_dbg(1, "Expanding up to cover frag (0x%x-0x%x) in dirty block %08x\n",
130562306a36Sopenharmony_ci					  frag->ofs,
130662306a36Sopenharmony_ci					  frag->ofs + frag->size,
130762306a36Sopenharmony_ci					  jeb->offset);
130862306a36Sopenharmony_ci				end = frag->ofs + frag->size;
130962306a36Sopenharmony_ci				break;
131062306a36Sopenharmony_ci			}
131162306a36Sopenharmony_ci		}
131262306a36Sopenharmony_ci		jffs2_dbg(1, "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n",
131362306a36Sopenharmony_ci			  orig_start, orig_end, start, end);
131462306a36Sopenharmony_ci
131562306a36Sopenharmony_ci		D1(BUG_ON(end > frag_last(&f->fragtree)->ofs + frag_last(&f->fragtree)->size));
131662306a36Sopenharmony_ci		BUG_ON(end < orig_end);
131762306a36Sopenharmony_ci		BUG_ON(start > orig_start);
131862306a36Sopenharmony_ci	}
131962306a36Sopenharmony_ci
132062306a36Sopenharmony_ci	/* The rules state that we must obtain the page lock *before* f->sem, so
132162306a36Sopenharmony_ci	 * drop f->sem temporarily. Since we also hold c->alloc_sem, nothing's
132262306a36Sopenharmony_ci	 * actually going to *change* so we're safe; we only allow reading.
132362306a36Sopenharmony_ci	 *
132462306a36Sopenharmony_ci	 * It is important to note that jffs2_write_begin() will ensure that its
132562306a36Sopenharmony_ci	 * page is marked Uptodate before allocating space. That means that if we
132662306a36Sopenharmony_ci	 * end up here trying to GC the *same* page that jffs2_write_begin() is
132762306a36Sopenharmony_ci	 * trying to write out, read_cache_page() will not deadlock. */
132862306a36Sopenharmony_ci	mutex_unlock(&f->sem);
132962306a36Sopenharmony_ci	page = read_cache_page(inode->i_mapping, start >> PAGE_SHIFT,
133062306a36Sopenharmony_ci			       __jffs2_read_folio, NULL);
133162306a36Sopenharmony_ci	if (IS_ERR(page)) {
133262306a36Sopenharmony_ci		pr_warn("read_cache_page() returned error: %ld\n",
133362306a36Sopenharmony_ci			PTR_ERR(page));
133462306a36Sopenharmony_ci		mutex_lock(&f->sem);
133562306a36Sopenharmony_ci		return PTR_ERR(page);
133662306a36Sopenharmony_ci	}
133762306a36Sopenharmony_ci
133862306a36Sopenharmony_ci	pg_ptr = kmap(page);
133962306a36Sopenharmony_ci	mutex_lock(&f->sem);
134062306a36Sopenharmony_ci
134162306a36Sopenharmony_ci	offset = start;
134262306a36Sopenharmony_ci	while(offset < orig_end) {
134362306a36Sopenharmony_ci		uint32_t datalen;
134462306a36Sopenharmony_ci		uint32_t cdatalen;
134562306a36Sopenharmony_ci		uint16_t comprtype = JFFS2_COMPR_NONE;
134662306a36Sopenharmony_ci
134762306a36Sopenharmony_ci		ret = jffs2_reserve_space_gc(c, sizeof(ri) + JFFS2_MIN_DATA_LEN,
134862306a36Sopenharmony_ci					&alloclen, JFFS2_SUMMARY_INODE_SIZE);
134962306a36Sopenharmony_ci
135062306a36Sopenharmony_ci		if (ret) {
135162306a36Sopenharmony_ci			pr_warn("jffs2_reserve_space_gc of %zd bytes for garbage_collect_dnode failed: %d\n",
135262306a36Sopenharmony_ci				sizeof(ri) + JFFS2_MIN_DATA_LEN, ret);
135362306a36Sopenharmony_ci			break;
135462306a36Sopenharmony_ci		}
135562306a36Sopenharmony_ci		cdatalen = min_t(uint32_t, alloclen - sizeof(ri), end - offset);
135662306a36Sopenharmony_ci		datalen = end - offset;
135762306a36Sopenharmony_ci
135862306a36Sopenharmony_ci		writebuf = pg_ptr + (offset & (PAGE_SIZE -1));
135962306a36Sopenharmony_ci
136062306a36Sopenharmony_ci		comprtype = jffs2_compress(c, f, writebuf, &comprbuf, &datalen, &cdatalen);
136162306a36Sopenharmony_ci
136262306a36Sopenharmony_ci		ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
136362306a36Sopenharmony_ci		ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
136462306a36Sopenharmony_ci		ri.totlen = cpu_to_je32(sizeof(ri) + cdatalen);
136562306a36Sopenharmony_ci		ri.hdr_crc = cpu_to_je32(crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4));
136662306a36Sopenharmony_ci
136762306a36Sopenharmony_ci		ri.ino = cpu_to_je32(f->inocache->ino);
136862306a36Sopenharmony_ci		ri.version = cpu_to_je32(++f->highest_version);
136962306a36Sopenharmony_ci		ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f));
137062306a36Sopenharmony_ci		ri.uid = cpu_to_je16(JFFS2_F_I_UID(f));
137162306a36Sopenharmony_ci		ri.gid = cpu_to_je16(JFFS2_F_I_GID(f));
137262306a36Sopenharmony_ci		ri.isize = cpu_to_je32(JFFS2_F_I_SIZE(f));
137362306a36Sopenharmony_ci		ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f));
137462306a36Sopenharmony_ci		ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f));
137562306a36Sopenharmony_ci		ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f));
137662306a36Sopenharmony_ci		ri.offset = cpu_to_je32(offset);
137762306a36Sopenharmony_ci		ri.csize = cpu_to_je32(cdatalen);
137862306a36Sopenharmony_ci		ri.dsize = cpu_to_je32(datalen);
137962306a36Sopenharmony_ci		ri.compr = comprtype & 0xff;
138062306a36Sopenharmony_ci		ri.usercompr = (comprtype >> 8) & 0xff;
138162306a36Sopenharmony_ci		ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
138262306a36Sopenharmony_ci		ri.data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen));
138362306a36Sopenharmony_ci
138462306a36Sopenharmony_ci		new_fn = jffs2_write_dnode(c, f, &ri, comprbuf, cdatalen, ALLOC_GC);
138562306a36Sopenharmony_ci
138662306a36Sopenharmony_ci		jffs2_free_comprbuf(comprbuf, writebuf);
138762306a36Sopenharmony_ci
138862306a36Sopenharmony_ci		if (IS_ERR(new_fn)) {
138962306a36Sopenharmony_ci			pr_warn("Error writing new dnode: %ld\n",
139062306a36Sopenharmony_ci				PTR_ERR(new_fn));
139162306a36Sopenharmony_ci			ret = PTR_ERR(new_fn);
139262306a36Sopenharmony_ci			break;
139362306a36Sopenharmony_ci		}
139462306a36Sopenharmony_ci		ret = jffs2_add_full_dnode_to_inode(c, f, new_fn);
139562306a36Sopenharmony_ci		offset += datalen;
139662306a36Sopenharmony_ci		if (f->metadata) {
139762306a36Sopenharmony_ci			jffs2_mark_node_obsolete(c, f->metadata->raw);
139862306a36Sopenharmony_ci			jffs2_free_full_dnode(f->metadata);
139962306a36Sopenharmony_ci			f->metadata = NULL;
140062306a36Sopenharmony_ci		}
140162306a36Sopenharmony_ci	}
140262306a36Sopenharmony_ci
140362306a36Sopenharmony_ci	kunmap(page);
140462306a36Sopenharmony_ci	put_page(page);
140562306a36Sopenharmony_ci	return ret;
140662306a36Sopenharmony_ci}
1407