diff options
author | Filipe Manana <fdmanana@suse.com> | 2016-01-05 11:24:05 -0500 |
---|---|---|
committer | Filipe Manana <fdmanana@suse.com> | 2016-01-06 17:52:38 -0500 |
commit | 271dba4521aed0c37c063548f876b49f5cd64b2e (patch) | |
tree | 016938b3f9e791e8381d6a14b16583c14eaf9ef1 /fs/btrfs/inode.c | |
parent | 9269d12b2d57d9e3d13036bb750762d1110d425c (diff) |
Btrfs: fix transaction handle leak on failure to create hard link
If we failed to create a hard link we were not always releasing the
the transaction handle we got before, resulting in a memory leak and
preventing any other tasks from being able to commit the current
transaction.
Fix this by always releasing our transaction handle.
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: Liu Bo <bo.li.liu@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 5dbc07a7c220..018c2a6108f2 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -6488,7 +6488,7 @@ out_unlock_inode: | |||
6488 | static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | 6488 | static int btrfs_link(struct dentry *old_dentry, struct inode *dir, |
6489 | struct dentry *dentry) | 6489 | struct dentry *dentry) |
6490 | { | 6490 | { |
6491 | struct btrfs_trans_handle *trans; | 6491 | struct btrfs_trans_handle *trans = NULL; |
6492 | struct btrfs_root *root = BTRFS_I(dir)->root; | 6492 | struct btrfs_root *root = BTRFS_I(dir)->root; |
6493 | struct inode *inode = d_inode(old_dentry); | 6493 | struct inode *inode = d_inode(old_dentry); |
6494 | u64 index; | 6494 | u64 index; |
@@ -6514,6 +6514,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
6514 | trans = btrfs_start_transaction(root, 5); | 6514 | trans = btrfs_start_transaction(root, 5); |
6515 | if (IS_ERR(trans)) { | 6515 | if (IS_ERR(trans)) { |
6516 | err = PTR_ERR(trans); | 6516 | err = PTR_ERR(trans); |
6517 | trans = NULL; | ||
6517 | goto fail; | 6518 | goto fail; |
6518 | } | 6519 | } |
6519 | 6520 | ||
@@ -6547,9 +6548,10 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
6547 | btrfs_log_new_name(trans, inode, NULL, parent); | 6548 | btrfs_log_new_name(trans, inode, NULL, parent); |
6548 | } | 6549 | } |
6549 | 6550 | ||
6550 | btrfs_end_transaction(trans, root); | ||
6551 | btrfs_balance_delayed_items(root); | 6551 | btrfs_balance_delayed_items(root); |
6552 | fail: | 6552 | fail: |
6553 | if (trans) | ||
6554 | btrfs_end_transaction(trans, root); | ||
6553 | if (drop_inode) { | 6555 | if (drop_inode) { |
6554 | inode_dec_link_count(inode); | 6556 | inode_dec_link_count(inode); |
6555 | iput(inode); | 6557 | iput(inode); |