diff options
author | Josef Bacik <jbacik@fusionio.com> | 2013-08-12 15:36:44 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2013-09-01 08:05:02 -0400 |
commit | 175a2b871f46272a2aedce5fb3222a72568b84c3 (patch) | |
tree | 17a101c9ff84cec0f2bbf184f44bd4f6858e92f3 | |
parent | a05254143cd183b18002cbba7759a1e4629aa762 (diff) |
Btrfs: don't allow a subvol to be deleted if it is the default subovl
Eric pointed out that btrfs will happily allow you to delete the default subvol.
This is a problem obviously since the next time you go to mount the file system
it will freak out because it can't find the root. Fix this by adding a check to
see if our default subvol points to the subvol we are trying to delete, and if
it does not allowing it to happen. Thanks,
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
-rw-r--r-- | fs/btrfs/ioctl.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 022d8364e072..317a984fe3c9 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -1726,13 +1726,28 @@ out: | |||
1726 | static noinline int may_destroy_subvol(struct btrfs_root *root) | 1726 | static noinline int may_destroy_subvol(struct btrfs_root *root) |
1727 | { | 1727 | { |
1728 | struct btrfs_path *path; | 1728 | struct btrfs_path *path; |
1729 | struct btrfs_dir_item *di; | ||
1729 | struct btrfs_key key; | 1730 | struct btrfs_key key; |
1731 | u64 dir_id; | ||
1730 | int ret; | 1732 | int ret; |
1731 | 1733 | ||
1732 | path = btrfs_alloc_path(); | 1734 | path = btrfs_alloc_path(); |
1733 | if (!path) | 1735 | if (!path) |
1734 | return -ENOMEM; | 1736 | return -ENOMEM; |
1735 | 1737 | ||
1738 | /* Make sure this root isn't set as the default subvol */ | ||
1739 | dir_id = btrfs_super_root_dir(root->fs_info->super_copy); | ||
1740 | di = btrfs_lookup_dir_item(NULL, root->fs_info->tree_root, path, | ||
1741 | dir_id, "default", 7, 0); | ||
1742 | if (di && !IS_ERR(di)) { | ||
1743 | btrfs_dir_item_key_to_cpu(path->nodes[0], di, &key); | ||
1744 | if (key.objectid == root->root_key.objectid) { | ||
1745 | ret = -ENOTEMPTY; | ||
1746 | goto out; | ||
1747 | } | ||
1748 | btrfs_release_path(path); | ||
1749 | } | ||
1750 | |||
1736 | key.objectid = root->root_key.objectid; | 1751 | key.objectid = root->root_key.objectid; |
1737 | key.type = BTRFS_ROOT_REF_KEY; | 1752 | key.type = BTRFS_ROOT_REF_KEY; |
1738 | key.offset = (u64)-1; | 1753 | key.offset = (u64)-1; |