mtd/fs/jffs2 nodemgmt.c,1.70,1.71

gleixner at infradead.org gleixner at infradead.org
Sat Aug 17 18:32:14 EDT 2002


Update of /home/cvs/mtd/fs/jffs2
In directory phoenix.infradead.org:/tmp/cvs-serv24150

Modified Files:
	nodemgmt.c 
Log Message:
move blocks to dirty_list again, move blocks with a few unused byte to clean list, added check to prevent endless gc, if cleanlist contains a lot of blocks, which have small dirty space

Index: nodemgmt.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/nodemgmt.c,v
retrieving revision 1.70
retrieving revision 1.71
diff -u -r1.70 -r1.71
--- nodemgmt.c	2 Jul 2002 22:48:24 -0000	1.70
+++ nodemgmt.c	17 Aug 2002 22:32:11 -0000	1.71
@@ -67,6 +67,27 @@
 				spin_unlock_bh(&c->erase_completion_lock);
 				return -ENOSPC;
 			}
+			if (c->dirty_size < blocksneeded * c->sector_size) {
+				uint32_t dirty = 0;			
+				struct list_head *this;
+				if (!list_empty(&c->very_dirty_list)) {
+					list_for_each(this, &c->very_dirty_list) {
+						struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
+						dirty += jeb->dirty_size;	
+					}
+				}
+				if (!list_empty(&c->dirty_list)) {
+					list_for_each(this, &c->dirty_list) {
+						struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list);
+						dirty += jeb->dirty_size;	
+					}
+				}
+				if (dirty < c->sector_size) {
+					D1(printk(KERN_DEBUG "Short on space, but dirty size in dirty_lists 0x%08x < sector size 0x%08x, so -ENOSPC\n", dirty, c->sector_size));
+					spin_unlock_bh(&c->erase_completion_lock);
+					return -ENOSPC;
+				}
+			}
 			D1(printk(KERN_DEBUG "Triggering GC pass. nr_free_blocks %d, nr_erasing_blocks %d, free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x, erasing_size 0x%08x, bad_size 0x%08x (total 0x%08x of 0x%08x)\n",
 				  c->nr_free_blocks, c->nr_erasing_blocks, c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size,
 				  c->free_size + c->dirty_size + c->used_size + c->erasing_size + c->bad_size, c->flash_size));
@@ -134,7 +155,11 @@
 		c->free_size -= jeb->free_size;
 		jeb->dirty_size += jeb->free_size;
 		jeb->free_size = 0;
-		if (VERYDIRTY(c, jeb->dirty_size)) {
+		if (!ISDIRTY(c, jeb->used_size)) {
+			D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
+			  jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
+			list_add_tail(&jeb->list, &c->clean_list);
+		} else if (VERYDIRTY(c, jeb->dirty_size)) {
 			D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to very_dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
 			  jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
 			list_add_tail(&jeb->list, &c->very_dirty_list);
@@ -417,7 +442,7 @@
 		D1(printk(KERN_DEBUG "Done OK\n"));
 	} else if (jeb == c->gcblock) {
 		D2(printk(KERN_DEBUG "Not moving gcblock 0x%08x to dirty_list\n", jeb->offset));
-	} else if (jeb->dirty_size == ref->totlen) {
+	} else if (ISDIRTY(c, jeb->used_size) && !ISDIRTY(c, jeb->used_size + ref->totlen)) {
 		D1(printk(KERN_DEBUG "Eraseblock at 0x%08x is freshly dirtied. Removing from clean list...\n", jeb->offset));
 		list_del(&jeb->list);
 		D1(printk(KERN_DEBUG "...and adding to dirty_list\n"));
@@ -428,7 +453,10 @@
 		list_del(&jeb->list);
 		D1(printk(KERN_DEBUG "...and adding to very_dirty_list\n"));
 		list_add_tail(&jeb->list, &c->very_dirty_list);
-	}
+	} else {
+		D1(printk(KERN_DEBUG "Eraseblock at 0x%08x not moved anywhere. (free 0x%08x, dirty 0x%08x, used 0x%08x)\n",
+			  jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size)); 
+	}			  	
 
 	spin_unlock_bh(&c->erase_completion_lock);
 





More information about the linux-mtd-cvs mailing list