From: NeilBrown Date: Mon, 9 Aug 2010 02:34:47 +0000 (+1000) Subject: Use async erase_block in inode orphan handling X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=df70c3587a136ef444fa92a70a11ca7c850cd29a;p=LaFS.git Use async erase_block in inode orphan handling otherwise we could deadlock. Signed-off-by: NeilBrown --- diff --git a/block.c b/block.c index 0c771e2..d64f25f 100644 --- 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 60bcd84..1a5ad6c 100644 --- 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 554211e..71a40eb 100644 --- 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);