From: NeilBrown Date: Sat, 14 Aug 2010 05:16:37 +0000 (+1000) Subject: Change when orphan blocks are refcounted. X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=0b5cc41c58630d28bb04d3986a511093f2646ea0;p=LaFS.git Change when orphan blocks are refcounted. Count when while B_Orphan is set, rather than while on a list. This gives us some freedom to do different things with the list, and ensures that we never lose the flag by the block disappearing. Signed-off-by: NeilBrown --- diff --git a/lafs.h b/lafs.h index 501cc5c..17a8e27 100644 --- a/lafs.h +++ b/lafs.h @@ -662,7 +662,6 @@ int lafs_make_orphan(struct fs *fs, struct datablock *db, struct inode *ino); int lafs_make_orphan_nb(struct fs *fs, struct datablock *db, struct inode *ino); void lafs_orphan_release(struct fs *fs, struct datablock *b, struct inode *ino); long lafs_run_orphans(struct fs *fs); -int lafs_drop_orphan(struct fs *fs, struct datablock *db); void lafs_add_orphan(struct fs *fs, struct datablock *db); void lafs_orphan_forget(struct fs *fs, struct datablock *db); struct datablock *lafs_find_orphan(struct inode *ino); diff --git a/orphan.c b/orphan.c index c0bbf45..246e6ea 100644 --- a/orphan.c +++ b/orphan.c @@ -90,8 +90,8 @@ void lafs_dump_orphans(void) * There are "om->reserved" of these, typically all on the one block. * "orphan" This is a block in the orphan file which holds an orphan * record for some committed orphan. ->orphan_slot points here. - * "orphan_list" This is a block (not in orphan file) which is an orphan, is - * on the ->pending_orphans list and has a record in the orphan file. + * "orphan_flag" This is a block (not in orphan file) which is an orphan, and + * has the B_Orphan flag set. * "orphanx", "orphan_release", "orphan_release2", "orphan_move" * "orphan_fs", "orphan_ino", "orphan_blk" Temporary references */ @@ -169,6 +169,7 @@ static void orphan_commit(struct fs *fs, struct datablock *b, struct datablock * /* Committed to being an orphan now */ b->orphan_slot = om->nextfree++; set_bit(B_Orphan, &b->b.flags); + getdref(b, MKREF(orphan_flag)); lafs_add_orphan(fs, b); dprintk("%p->orphan_slot=%d (%lu,%lu,%lu) %s\n", b, b->orphan_slot, @@ -302,6 +303,7 @@ int lafs_make_orphan_nb(struct fs *fs, struct datablock *db, struct inode *ino) return err; } +static int lafs_drop_orphan(struct fs *fs, struct datablock *db); /* * When any processing of an orphan makes it not an orphan any more * (e.g. link is created for a file, directory block is cleaned) @@ -431,6 +433,7 @@ void lafs_orphan_release(struct fs *fs, struct datablock *b, struct inode *ino) clear_bit(B_Orphan, &b->b.flags); iput(ino); lafs_drop_orphan(fs, b); + putdref(b, MKREF(orphan_flag)); /* Now drop the reservation we just synthesised */ orphan_abort(fs); @@ -574,7 +577,6 @@ int lafs_drop_orphan(struct fs *fs, struct datablock *db) } else { list_del_init(&db->orphans); spin_unlock(&fs->lock); - putdref(db, MKREF(orphan_list)); return 1; } } @@ -589,10 +591,9 @@ void lafs_add_orphan(struct fs *fs, struct datablock *db) */ LAFS_BUG(!test_bit(B_Orphan, &db->b.flags), &db->b); spin_lock(&fs->lock); - if (list_empty(&db->orphans)) { + if (list_empty(&db->orphans)) list_add_tail(&db->orphans, &fs->pending_orphans); - getdref(db, MKREF(orphan_list)); - } + spin_unlock(&fs->lock); lafs_wake_thread(fs); } @@ -603,12 +604,9 @@ void lafs_orphan_forget(struct fs *fs, struct datablock *db) * it just now. When we do, lafs_add_orphan will be called */ LAFS_BUG(!test_bit(B_Orphan, &db->b.flags), &db->b); spin_lock(&fs->lock); - if (!list_empty(&db->orphans)) { + if (!list_empty(&db->orphans)) list_del_init(&db->orphans); - spin_unlock(&fs->lock); - putdref(db, MKREF(orphan_list)); - } else - spin_unlock(&fs->lock); + spin_unlock(&fs->lock); } struct datablock *lafs_find_orphan(struct inode *ino)