aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2013-02-28 05:05:36 -0500
committerJosef Bacik <jbacik@fusionio.com>2013-02-28 13:33:55 -0500
commitc58aaad2ac46f8dbce9ab7f7a7a3726e332a56ee (patch)
tree6597760ea9f3c39f22f3ebada06b27ee59b8ea34
parentd5c1207017cd8387b4d3224dd7ab6cf5cd7f1c9a (diff)
Btrfs: fix wrong reserved space when deleting a snapshot/subvolume
When deleting a snapshot/subvolume, we need remove root ref/backref, dir entries and update the dir inode, so we must reserve free space for those operations. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Josef Bacik <jbacik@fusionio.com>
-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: