|
@@ -6478,7 +6478,7 @@ out_unlock_inode:
|
|
|
static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
|
|
|
struct dentry *dentry)
|
|
|
{
|
|
|
- struct btrfs_trans_handle *trans;
|
|
|
+ struct btrfs_trans_handle *trans = NULL;
|
|
|
struct btrfs_root *root = BTRFS_I(dir)->root;
|
|
|
struct inode *inode = d_inode(old_dentry);
|
|
|
u64 index;
|
|
@@ -6504,6 +6504,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
|
|
|
trans = btrfs_start_transaction(root, 5);
|
|
|
if (IS_ERR(trans)) {
|
|
|
err = PTR_ERR(trans);
|
|
|
+ trans = NULL;
|
|
|
goto fail;
|
|
|
}
|
|
|
|
|
@@ -6537,9 +6538,10 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
|
|
|
btrfs_log_new_name(trans, inode, NULL, parent);
|
|
|
}
|
|
|
|
|
|
- btrfs_end_transaction(trans, root);
|
|
|
btrfs_balance_delayed_items(root);
|
|
|
fail:
|
|
|
+ if (trans)
|
|
|
+ btrfs_end_transaction(trans, root);
|
|
|
if (drop_inode) {
|
|
|
inode_dec_link_count(inode);
|
|
|
iput(inode);
|
|
@@ -9655,9 +9657,11 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
|
|
|
/*
|
|
|
* 2 items for inode item and ref
|
|
|
* 2 items for dir items
|
|
|
+ * 1 item for updating parent inode item
|
|
|
+ * 1 item for the inline extent item
|
|
|
* 1 item for xattr if selinux is on
|
|
|
*/
|
|
|
- trans = btrfs_start_transaction(root, 5);
|
|
|
+ trans = btrfs_start_transaction(root, 7);
|
|
|
if (IS_ERR(trans))
|
|
|
return PTR_ERR(trans);
|
|
|
|
|
@@ -9688,10 +9692,6 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
|
|
|
if (err)
|
|
|
goto out_unlock_inode;
|
|
|
|
|
|
- err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index);
|
|
|
- if (err)
|
|
|
- goto out_unlock_inode;
|
|
|
-
|
|
|
path = btrfs_alloc_path();
|
|
|
if (!path) {
|
|
|
err = -ENOMEM;
|
|
@@ -9728,6 +9728,13 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
|
|
|
inode_set_bytes(inode, name_len);
|
|
|
btrfs_i_size_write(inode, name_len);
|
|
|
err = btrfs_update_inode(trans, root, inode);
|
|
|
+ /*
|
|
|
+ * Last step, add directory indexes for our symlink inode. This is the
|
|
|
+ * last step to avoid extra cleanup of these indexes if an error happens
|
|
|
+ * elsewhere above.
|
|
|
+ */
|
|
|
+ if (!err)
|
|
|
+ err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index);
|
|
|
if (err) {
|
|
|
drop_inode = 1;
|
|
|
goto out_unlock_inode;
|