]> git.neil.brown.name Git - LaFS.git/commitdiff
Avoid deadlock between orphan-truncate and cluster-write
authorNeilBrown <neilb@suse.de>
Thu, 10 Jun 2010 05:52:45 +0000 (15:52 +1000)
committerNeilBrown <neilb@suse.de>
Sun, 13 Jun 2010 07:19:59 +0000 (17:19 +1000)
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 <neilb@suse.de>
inode.c

diff --git a/inode.c b/inode.c
index a4ef3aa6b452240edc44d58273d6056e78ea5058..6baf137838db691291526b1cd309a4947a7553a2 100644 (file)
--- 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));