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