mtd/fs/jffs2 nodemgmt.c,1.101,1.102

David Woodhouse dwmw2 at infradead.org
Wed Oct 8 13:21:21 EDT 2003


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

Modified Files:
	nodemgmt.c 
Log Message:
Don't refile blocks from bad_used_list onto dirty lists.
Fix logic error in checking for deletion when maybe returning -ENOSPC


Index: nodemgmt.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/nodemgmt.c,v
retrieving revision 1.101
retrieving revision 1.102
diff -u -r1.101 -r1.102
--- nodemgmt.c	8 Oct 2003 11:47:19 -0000	1.101
+++ nodemgmt.c	8 Oct 2003 17:21:19 -0000	1.102
@@ -74,7 +74,7 @@
 			 */
 			dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size + c->unchecked_size;
 			if (dirty < c->nospc_dirty_size) {
-				if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks < c->resv_blocks_deletion) {
+				if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) {
 					printk(KERN_NOTICE "jffs2_reserve_space(): Low on dirty space to GC, but it's a deletion. Allowing...\n");
 					break;
 				}
@@ -97,7 +97,7 @@
 			 */
 			avail = c->free_size + c->dirty_size + c->erasing_size + c->unchecked_size;
 			if ( (avail / c->sector_size) <= blocksneeded) {
-				if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks < c->resv_blocks_deletion) {
+				if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) {
 					printk(KERN_NOTICE "jffs2_reserve_space(): Low on possibly available space, but it's a deletion. Allowing...\n");
 					break;
 				}
@@ -380,6 +380,20 @@
 	up(&c->alloc_sem);
 }
 
+static inline int on_list(struct list_head *obj, struct list_head *head)
+{
+	struct list_head *this;
+
+	list_for_each(this, head) {
+		if (this == obj) {
+			D1(printk("%p is on list at %p\n", obj, head));
+			return 1;
+
+		}
+	}
+	return 0;
+}
+
 void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref)
 {
 	struct jffs2_eraseblock *jeb;
@@ -428,11 +442,26 @@
 	// Take care, that wasted size is taken into concern
 	if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + ref->totlen)) && jeb != c->nextblock) {
 		D1(printk("Dirtying\n"));
-		addedsize = ref->totlen + jeb->wasted_size;
-		jeb->dirty_size += addedsize;
-		c->dirty_size += addedsize;
-		c->wasted_size -= jeb->wasted_size;
-		jeb->wasted_size = 0;
+		addedsize = ref->totlen;
+		jeb->dirty_size += ref->totlen;
+		c->dirty_size += ref->totlen;
+
+		/* Convert wasted space to dirty, if not a bad block */
+		if (jeb->wasted_size) {
+			if (on_list(&jeb->list, &c->bad_used_list)) {
+				D1(printk(KERN_DEBUG "Leaving block at %08x on the bad_used_list\n",
+					  jeb->offset));
+				addedsize = 0; /* To fool the refiling code later */
+			} else {
+				D1(printk(KERN_DEBUG "Converting %d bytes of wasted space to dirty in block at %08x\n",
+					  jeb->wasted_size, jeb->offset));
+				addedsize += jeb->wasted_size;
+				jeb->dirty_size += jeb->wasted_size;
+				c->dirty_size += jeb->wasted_size;
+				c->wasted_size -= jeb->wasted_size;
+				jeb->wasted_size = 0;
+			}
+		}
 	} else {
 		D1(printk("Wasting\n"));
 		addedsize = 0;
@@ -516,7 +545,7 @@
 		D1(printk(KERN_DEBUG "...and adding to dirty_list\n"));
 		list_add_tail(&jeb->list, &c->dirty_list);
 	} else if (VERYDIRTY(c, jeb->dirty_size) &&
-		   !VERYDIRTY(c, jeb->dirty_size - ref->totlen)) {
+		   !VERYDIRTY(c, jeb->dirty_size - addedsize)) {
 		D1(printk(KERN_DEBUG "Eraseblock at 0x%08x is now very dirty. Removing from dirty list...\n", jeb->offset));
 		list_del(&jeb->list);
 		D1(printk(KERN_DEBUG "...and adding to very_dirty_list\n"));




More information about the linux-mtd-cvs mailing list