]> git.neil.brown.name Git - LaFS.git/commitdiff
Use async erase_block in inode orphan handling
authorNeilBrown <neilb@suse.de>
Mon, 9 Aug 2010 02:34:47 +0000 (12:34 +1000)
committerNeilBrown <neilb@suse.de>
Mon, 9 Aug 2010 02:34:47 +0000 (12:34 +1000)
otherwise we could deadlock.

Signed-off-by: NeilBrown <neilb@suse.de>
block.c
inode.c
lafs.h

diff --git a/block.c b/block.c
index 0c771e2ea3c37a69878e7a05ec4b4443aad4fe11..d64f25f730687c2b224bc0e87dc233082e6dd475 100644 (file)
--- a/block.c
+++ b/block.c
@@ -506,13 +506,12 @@ lafs_dirty_dblock(struct datablock *b)
                                                         * a block. */
 }
 
-void
-lafs_erase_dblock(struct datablock *b)
+static void
+erase_dblock_locked(struct datablock *b)
 {
        struct fs *fs = fs_from_inode(b->b.inode);
 
        dprintk("Eraseblock for %s\n", strblk(&b->b));
-       lafs_iolock_written(&b->b);
        if (b->b.physaddr == 0 &&
            b->b.fileaddr == 0 &&
            LAFSI(b->b.inode)->depth == 0) {
@@ -602,6 +601,23 @@ lafs_erase_dblock(struct datablock *b)
        lafs_writeback_done(&b->b);
 }
 
+void
+lafs_erase_dblock(struct datablock *b)
+{
+       lafs_iolock_written(&b->b);
+       erase_dblock_locked(b);
+}
+
+int
+lafs_erase_dblock_async(struct datablock *b)
+{
+       int rv;
+       rv = lafs_iolock_written_async(&b->b);
+       if (rv)
+               erase_dblock_locked(b);
+       return rv;
+}
+
 void
 lafs_dirty_iblock(struct indexblock *b)
 {
diff --git a/inode.c b/inode.c
index 60bcd8493c2be47e7e2b1f94aa9755c2a8b5c322..1a5ad6cee920cfa4039383f2204c6530efd719ff 100644 (file)
--- a/inode.c
+++ b/inode.c
@@ -754,8 +754,8 @@ int lafs_inode_handle_orphan(struct datablock *b)
                               LAFSI(ino)->ablocks +
                               LAFSI(ino)->ciblocks +
                               LAFSI(ino)->piblocks);
-                       lafs_erase_dblock(b);
-                       lafs_orphan_release(fs, b, NULL);
+                       if (lafs_erase_dblock_async(b))
+                               lafs_orphan_release(fs, b, NULL);
                } else if (ino->i_nlink || LAFSI(ino)->type == 0)
                        lafs_orphan_release(fs, b, NULL);
                else
diff --git a/lafs.h b/lafs.h
index 554211ea4c112fe5b8497268478e47d7be5b5f2d..71a40eb10347c627224beeea1f7e520eaf15c39c 100644 (file)
--- a/lafs.h
+++ b/lafs.h
@@ -603,6 +603,7 @@ int lafs_pin_dblock(struct datablock *b, int alloc_type);
 int lafs_reserve_block(struct block *b, int alloc_type);
 void lafs_dirty_dblock(struct datablock *b);
 void lafs_erase_dblock(struct datablock *b);
+int lafs_erase_dblock_async(struct datablock *b);
 void lafs_dirty_iblock(struct indexblock *b);
 void block_drop_addr(struct fs *fs, struct inode *ino, u32 addr);
 void lafs_flush(struct datablock *b);