From: NeilBrown Date: Thu, 10 Jun 2010 05:52:45 +0000 (+1000) Subject: Avoid deadlock between orphan-truncate and cluster-write X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=fc0adb2d8351fd9c0e79bf8cf4e96116e7b7d6ca;p=LaFS.git Avoid deadlock between orphan-truncate and cluster-write If, during truncate, we find an index block in writeback, we need to give up on the orphan and return back up to the cleaner thread so that the writeback can be properly handled. Otherwise the cleaner thread is blocked waiting for the cleaner thread to make progress. Signed-off-by: NeilBrown --- diff --git a/inode.c b/inode.c index a4ef3aa..6baf137 100644 --- a/inode.c +++ b/inode.c @@ -578,8 +578,10 @@ void lafs_inode_handle_orphan(struct datablock *b) struct inode *ino = b->my_inode; struct fs *fs = fs_from_inode(ino); u32 trunc_next, next_trunc; + int do_restart; restart: + do_restart = 1; if (!test_bit(I_Trunc, &LAFSI(ino)->iflags)) { if (test_bit(I_Deleting, &LAFSI(ino)->iflags)) { @@ -682,6 +684,7 @@ void lafs_inode_handle_orphan(struct datablock *b) if (test_bit(B_Writeback, &ib2->b.flags)) { lafs_iounlock_block(&ib2->b); putiref(ib2, MKREF(inode_handle_orphan2)); + do_restart = 0; goto out2; } do @@ -715,7 +718,10 @@ void lafs_inode_handle_orphan(struct datablock *b) } out2: putiref(ib, MKREF(inode_handle_orphan)); - goto restart; + if (do_restart) + goto restart; + else + return; } putiref(ib, MKREF(inode_handle_orphan));