From: NeilBrown Date: Thu, 3 Sep 2009 05:28:21 +0000 (+1000) Subject: Fixed to run_orphans. X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=39181daa60a13a6e4aaa830e73672cef56b50c25;p=LaFS.git Fixed to run_orphans. We need to hold a reference to the db, as orphan_release can drop it. And an unclaimed inode block with no mx is always free to be orphan_released. --- diff --git a/orphan.c b/orphan.c index 0f3cf62..b892da2 100644 --- a/orphan.c +++ b/orphan.c @@ -478,27 +478,28 @@ long lafs_run_orphans(struct fs *fs) orphans); list_move(&db->orphans, &done); mx = orphan_mutex(db); - if (!mx || !mutex_trylock(mx)) + if (!mx && !test_bit(B_Claimed, &db->b.flags)) + /* OK not to have a mutex */; + else if (!mx || !mutex_trylock(mx)) continue; + getdref(db, MKREF(run_orphans)); spin_unlock(&fs->lock); - /* The 'orphan_list' reference cannot be dropped - * while we own the mutex, so our reference to db is safe - */ - - switch(LAFSI(db->b.inode)->type) { - case TypeInodeFile: - lafs_inode_handle_orphan(db); - break; - case TypeDir: - lafs_dir_handle_orphan(db); - break; + if (!mx) + lafs_orphan_release(fs, db); + else { + switch(LAFSI(db->b.inode)->type) { + case TypeInodeFile: + lafs_inode_handle_orphan(db); + break; + case TypeDir: + lafs_dir_handle_orphan(db); + break; + } + mutex_unlock(mx); } - mutex_unlock(mx); - /* The block has either been put, or is still on - * 'done'. - */ + putdref(db, MKREF(run_orphans)); spin_lock(&fs->lock); } list_splice(&done, &fs->pending_orphans);