summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorZach Brown <zab@redhat.com>2013-04-02 21:02:16 +0000
committerJosef Bacik <jbacik@fusionio.com>2013-05-06 15:54:36 -0400
commitd4e3991b9945906528c7abb627d759ea43f53bce (patch)
tree8ef759bd9b3348528c29bb0433c57eae921d6ad2 /fs/btrfs/inode.c
parentf63e0cca9174dd8b47380f61565ab7b921d6ac2c (diff)
downloadop-kernel-dev-d4e3991b9945906528c7abb627d759ea43f53bce.zip
op-kernel-dev-d4e3991b9945906528c7abb627d759ea43f53bce.tar.gz
btrfs: abort unlink trans in missed error case
__btrfs_unlink_inode() aborts its transaction when it sees errors after it removes the directory item. But it missed the case where btrfs_del_dir_entries_in_log() returns an error. If this happens then the unlink appears to fail but the items have been removed without updating the directory size. The directory then has leaked bytes in i_size and can never be removed. Adding the missing transaction abort at least makes this failure consistent with the other failure cases. I noticed this while reading the code after someone on irc reported having a directory with i_size but no entries. I tested it by forcing btrfs_del_dir_entries_in_log() to return -ENOMEM. Signed-off-by: Zach Brown <zab@redhat.com> Reviewed-by: Eric Sandeen <sandeen@redhat.com> Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index c41637a..ca405171 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3616,6 +3616,8 @@ static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans,
dir, index);
if (ret == -ENOENT)
ret = 0;
+ else if (ret)
+ btrfs_abort_transaction(trans, root, ret);
err:
btrfs_free_path(path);
if (ret)
OpenPOWER on IntegriCloud