From: Yan Zheng Date: Mon, 5 Jan 2009 20:43:42 +0000 (-0500) Subject: Btrfs: avoid orphan inode caused by log replay X-Git-Tag: v2.6.29-rc1~27^2~9^2~3 X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=ec051c0f929afe5c42c24bb07abf577c616c208c;p=linux-2.6-omap-h63xx.git Btrfs: avoid orphan inode caused by log replay drop_one_dir_item does not properly update inode's link count. It can be reproduced by executing following commands: #touch test #sync #rm -f test #dd if=/dev/zero bs=4k count=1 of=test conv=fsync #echo b > /proc/sysrq-trigger This fixes it by adding an BTRFS_ORPHAN_ITEM_KEY for the inode Signed-off-by: Yan Zheng --- diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 33eee256ee8..b1c2921f5be 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -50,6 +50,9 @@ static int __btrfs_log_inode(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct inode *inode, int inode_only); +static int link_to_fixup_dir(struct btrfs_trans_handle *trans, + struct btrfs_root *root, + struct btrfs_path *path, u64 objectid); /* * tree logging is a special write ahead log used to make sure that @@ -638,8 +641,10 @@ static noinline int drop_one_dir_item(struct btrfs_trans_handle *trans, inode = read_one_inode(root, location.objectid); BUG_ON(!inode); - btrfs_inc_nlink(inode); + ret = link_to_fixup_dir(trans, root, path, location.objectid); + BUG_ON(ret); ret = btrfs_unlink_inode(trans, root, dir, inode, name, name_len); + BUG_ON(ret); kfree(name); iput(inode);