aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ioctl.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 56d92549389c..b908960c9746 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2064,6 +2064,8 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
2064 struct btrfs_root *dest = NULL; 2064 struct btrfs_root *dest = NULL;
2065 struct btrfs_ioctl_vol_args *vol_args; 2065 struct btrfs_ioctl_vol_args *vol_args;
2066 struct btrfs_trans_handle *trans; 2066 struct btrfs_trans_handle *trans;
2067 struct btrfs_block_rsv block_rsv;
2068 u64 qgroup_reserved;
2067 int namelen; 2069 int namelen;
2068 int ret; 2070 int ret;
2069 int err = 0; 2071 int err = 0;
@@ -2153,12 +2155,23 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
2153 if (err) 2155 if (err)
2154 goto out_up_write; 2156 goto out_up_write;
2155 2157
2158 btrfs_init_block_rsv(&block_rsv, BTRFS_BLOCK_RSV_TEMP);
2159 /*
2160 * One for dir inode, two for dir entries, two for root
2161 * ref/backref.
2162 */
2163 err = btrfs_subvolume_reserve_metadata(root, &block_rsv,
2164 5, &qgroup_reserved);
2165 if (err)
2166 goto out_up_write;
2167
2156 trans = btrfs_start_transaction(root, 0); 2168 trans = btrfs_start_transaction(root, 0);
2157 if (IS_ERR(trans)) { 2169 if (IS_ERR(trans)) {
2158 err = PTR_ERR(trans); 2170 err = PTR_ERR(trans);
2159 goto out_up_write; 2171 goto out_release;
2160 } 2172 }
2161 trans->block_rsv = &root->fs_info->global_block_rsv; 2173 trans->block_rsv = &block_rsv;
2174 trans->bytes_reserved = block_rsv.size;
2162 2175
2163 ret = btrfs_unlink_subvol(trans, root, dir, 2176 ret = btrfs_unlink_subvol(trans, root, dir,
2164 dest->root_key.objectid, 2177 dest->root_key.objectid,
@@ -2188,10 +2201,14 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
2188 } 2201 }
2189 } 2202 }
2190out_end_trans: 2203out_end_trans:
2204 trans->block_rsv = NULL;
2205 trans->bytes_reserved = 0;
2191 ret = btrfs_end_transaction(trans, root); 2206 ret = btrfs_end_transaction(trans, root);
2192 if (ret && !err) 2207 if (ret && !err)
2193 err = ret; 2208 err = ret;
2194 inode->i_flags |= S_DEAD; 2209 inode->i_flags |= S_DEAD;
2210out_release:
2211 btrfs_subvolume_release_metadata(root, &block_rsv, qgroup_reserved);
2195out_up_write: 2212out_up_write:
2196 up_write(&root->fs_info->subvol_sem); 2213 up_write(&root->fs_info->subvol_sem);
2197out_unlock: 2214out_unlock: