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