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