aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFilipe Manana <fdmanana@gmail.com>2014-05-24 22:55:44 -0400
committerChris Mason <clm@fb.com>2014-06-09 20:21:03 -0400
commitc55bfa67e94e22ec0449fe7c55b3ef20fbe13348 (patch)
tree5c56b113d932a22ef584926f7ef9429baa9f3396
parentc125b8bff1d9f6c8c91ce4eb8bd5616058c7d510 (diff)
Btrfs: set dead flag on the right root when destroying snapshot
We were setting the BTRFS_ROOT_SUBVOL_DEAD flag on the root of the parent of our target snapshot, instead of setting it in the target snapshot's root. This is easy to observe by running the following scenario: mkfs.btrfs -f /dev/sdd mount /dev/sdd /mnt btrfs subvolume create /mnt/first_subvol btrfs subvolume snapshot -r /mnt /mnt/mysnap1 btrfs subvolume delete /mnt/first_subvol btrfs subvolume snapshot -r /mnt /mnt/mysnap2 btrfs send -p /mnt/mysnap1 /mnt/mysnap2 -f /tmp/send.data The send command failed because the send ioctl returned -EPERM. A test case for xfstests follows. Signed-off-by: Filipe David Borba Manana <fdmanana@gmail.com> Reviewed-by: David Sterba <dsterba@suse.cz> Signed-off-by: Chris Mason <clm@fb.com>
-rw-r--r--fs/btrfs/ioctl.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 362720a3fea2..38f2169b73a4 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -2312,16 +2312,16 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
2312 * again is not run concurrently. 2312 * again is not run concurrently.
2313 */ 2313 */
2314 spin_lock(&dest->root_item_lock); 2314 spin_lock(&dest->root_item_lock);
2315 root_flags = btrfs_root_flags(&root->root_item); 2315 root_flags = btrfs_root_flags(&dest->root_item);
2316 if (root->send_in_progress == 0) { 2316 if (dest->send_in_progress == 0) {
2317 btrfs_set_root_flags(&root->root_item, 2317 btrfs_set_root_flags(&dest->root_item,
2318 root_flags | BTRFS_ROOT_SUBVOL_DEAD); 2318 root_flags | BTRFS_ROOT_SUBVOL_DEAD);
2319 spin_unlock(&dest->root_item_lock); 2319 spin_unlock(&dest->root_item_lock);
2320 } else { 2320 } else {
2321 spin_unlock(&dest->root_item_lock); 2321 spin_unlock(&dest->root_item_lock);
2322 btrfs_warn(root->fs_info, 2322 btrfs_warn(root->fs_info,
2323 "Attempt to delete subvolume %llu during send", 2323 "Attempt to delete subvolume %llu during send",
2324 root->root_key.objectid); 2324 dest->root_key.objectid);
2325 err = -EPERM; 2325 err = -EPERM;
2326 goto out_dput; 2326 goto out_dput;
2327 } 2327 }
@@ -2416,8 +2416,8 @@ out_up_write:
2416out_unlock: 2416out_unlock:
2417 if (err) { 2417 if (err) {
2418 spin_lock(&dest->root_item_lock); 2418 spin_lock(&dest->root_item_lock);
2419 root_flags = btrfs_root_flags(&root->root_item); 2419 root_flags = btrfs_root_flags(&dest->root_item);
2420 btrfs_set_root_flags(&root->root_item, 2420 btrfs_set_root_flags(&dest->root_item,
2421 root_flags & ~BTRFS_ROOT_SUBVOL_DEAD); 2421 root_flags & ~BTRFS_ROOT_SUBVOL_DEAD);
2422 spin_unlock(&dest->root_item_lock); 2422 spin_unlock(&dest->root_item_lock);
2423 } 2423 }