mtd/fs/jffs2 gc.c,1.99,1.100
David Woodhouse
dwmw2 at infradead.org
Wed Jan 22 09:43:54 EST 2003
Update of /home/cvs/mtd/fs/jffs2
In directory phoenix.infradead.org:/tmp/cvs-serv30367
Modified Files:
gc.c
Log Message:
Use jffs2_do_crccheck_inode()
Index: gc.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/gc.c,v
retrieving revision 1.99
retrieving revision 1.100
diff -u -r1.99 -r1.100
--- gc.c 22 Jan 2003 12:07:58 -0000 1.99
+++ gc.c 22 Jan 2003 14:43:51 -0000 1.100
@@ -121,49 +121,78 @@
if (down_interruptible(&c->alloc_sem))
return -EINTR;
- spin_lock(&c->erase_completion_lock);
-
- while (c->unchecked_size) {
- /* We can't start doing GC yet. We haven't finished checking
- the node CRCs etc. Do it now and wait for it. */
+ for (;;) {
struct jffs2_inode_cache *ic;
+ spin_lock(&c->erase_completion_lock);
+ if (!c->unchecked_size)
+ break;
+
+ /* We can't start doing GC yet. We haven't finished checking
+ the node CRCs etc. Do it now. */
+
+ /* checked_ino is protected by the alloc_sem */
if (c->checked_ino > c->highest_ino) {
printk(KERN_CRIT "Checked all inodes but still 0x%x bytes of unchecked space?\n",
c->unchecked_size);
D1(jffs2_dump_block_lists(c));
+ spin_unlock(&c->erase_completion_lock);
BUG();
}
+
+ spin_unlock(&c->erase_completion_lock);
+
spin_lock(&c->inocache_lock);
+
ic = jffs2_get_ino_cache(c, c->checked_ino++);
- spin_unlock(&c->inocache_lock);
- if (!ic)
+
+ if (!ic) {
+ spin_unlock(&c->inocache_lock);
continue;
+ }
+
if (!ic->nlink) {
D1(printk(KERN_DEBUG "Skipping check of ino #%d with nlink zero\n",
ic->ino));
+ spin_unlock(&c->inocache_lock);
continue;
}
- if (ic->state != INO_STATE_UNCHECKED) {
- D1(printk(KERN_DEBUG "Skipping check of ino #%d already in state %d\n",
- ic->ino, ic->state));
+ switch(ic->state) {
+ case INO_STATE_CHECKEDABSENT:
+ case INO_STATE_PRESENT:
+ D1(printk(KERN_DEBUG "Skipping ino #%u already checked\n", ic->ino));
+ spin_unlock(&c->inocache_lock);
continue;
- }
- spin_unlock(&c->erase_completion_lock);
+ case INO_STATE_GC:
+ case INO_STATE_CHECKING:
+ printk(KERN_WARNING "Inode #%u is in state %d during CRC check phase!\n", ic->ino, ic->state);
+ spin_unlock(&c->inocache_lock);
+ BUG();
- D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() triggering inode scan of ino#%d\n", ic->ino));
-
- {
- /* XXX: This wants doing more sensibly -- split the core of jffs2_do_read_inode up */
- struct inode *i = iget(OFNI_BS_2SFFJ(c), ic->ino);
- if (is_bad_inode(i)) {
- printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u\n", ic->ino);
- ret = -EIO;
- }
- iput(i);
+ case INO_STATE_READING:
+ /* We need to wait for it to finish, lest we move on
+ and trigger the BUG() above while we haven't yet
+ finished checking all its nodes */
+ D1(printk(KERN_DEBUG "Waiting for ino #%u to finish reading\n", ic->ino));
+ up(&c->alloc_sem);
+ sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
+ return 0;
+
+ default:
+ BUG();
+
+ case INO_STATE_UNCHECKED:
+ ;
}
+ ic->state = INO_STATE_CHECKING;
+ spin_unlock(&c->inocache_lock);
+
+ D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() triggering inode scan of ino#%d\n", ic->ino));
+ ret = jffs2_do_crccheck_inode(c, ic);
+ if (!ret)
+ jffs2_set_inocache_state(c, ic, INO_STATE_CHECKEDABSENT);
up(&c->alloc_sem);
return ret;
}
More information about the linux-mtd-cvs
mailing list