diff options
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r-- | fs/btrfs/ioctl.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 02d224e8c83f..5fdb2abc4fa7 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -1071,12 +1071,15 @@ static noinline int btrfs_ioctl_subvol_setflags(struct file *file, | |||
1071 | if (copy_from_user(&flags, arg, sizeof(flags))) | 1071 | if (copy_from_user(&flags, arg, sizeof(flags))) |
1072 | return -EFAULT; | 1072 | return -EFAULT; |
1073 | 1073 | ||
1074 | if (flags & ~BTRFS_SUBVOL_CREATE_ASYNC) | 1074 | if (flags & BTRFS_SUBVOL_CREATE_ASYNC) |
1075 | return -EINVAL; | 1075 | return -EINVAL; |
1076 | 1076 | ||
1077 | if (flags & ~BTRFS_SUBVOL_RDONLY) | 1077 | if (flags & ~BTRFS_SUBVOL_RDONLY) |
1078 | return -EOPNOTSUPP; | 1078 | return -EOPNOTSUPP; |
1079 | 1079 | ||
1080 | if (!is_owner_or_cap(inode)) | ||
1081 | return -EACCES; | ||
1082 | |||
1080 | down_write(&root->fs_info->subvol_sem); | 1083 | down_write(&root->fs_info->subvol_sem); |
1081 | 1084 | ||
1082 | /* nothing to do */ | 1085 | /* nothing to do */ |
@@ -1097,7 +1100,7 @@ static noinline int btrfs_ioctl_subvol_setflags(struct file *file, | |||
1097 | goto out_reset; | 1100 | goto out_reset; |
1098 | } | 1101 | } |
1099 | 1102 | ||
1100 | ret = btrfs_update_root(trans, root, | 1103 | ret = btrfs_update_root(trans, root->fs_info->tree_root, |
1101 | &root->root_key, &root->root_item); | 1104 | &root->root_key, &root->root_item); |
1102 | 1105 | ||
1103 | btrfs_commit_transaction(trans, root); | 1106 | btrfs_commit_transaction(trans, root); |
@@ -2208,7 +2211,7 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) | |||
2208 | int num_types = 4; | 2211 | int num_types = 4; |
2209 | int alloc_size; | 2212 | int alloc_size; |
2210 | int ret = 0; | 2213 | int ret = 0; |
2211 | int slot_count = 0; | 2214 | u64 slot_count = 0; |
2212 | int i, c; | 2215 | int i, c; |
2213 | 2216 | ||
2214 | if (copy_from_user(&space_args, | 2217 | if (copy_from_user(&space_args, |
@@ -2247,7 +2250,7 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) | |||
2247 | goto out; | 2250 | goto out; |
2248 | } | 2251 | } |
2249 | 2252 | ||
2250 | slot_count = min_t(int, space_args.space_slots, slot_count); | 2253 | slot_count = min_t(u64, space_args.space_slots, slot_count); |
2251 | 2254 | ||
2252 | alloc_size = sizeof(*dest) * slot_count; | 2255 | alloc_size = sizeof(*dest) * slot_count; |
2253 | 2256 | ||
@@ -2267,6 +2270,9 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) | |||
2267 | for (i = 0; i < num_types; i++) { | 2270 | for (i = 0; i < num_types; i++) { |
2268 | struct btrfs_space_info *tmp; | 2271 | struct btrfs_space_info *tmp; |
2269 | 2272 | ||
2273 | if (!slot_count) | ||
2274 | break; | ||
2275 | |||
2270 | info = NULL; | 2276 | info = NULL; |
2271 | rcu_read_lock(); | 2277 | rcu_read_lock(); |
2272 | list_for_each_entry_rcu(tmp, &root->fs_info->space_info, | 2278 | list_for_each_entry_rcu(tmp, &root->fs_info->space_info, |
@@ -2288,7 +2294,10 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) | |||
2288 | memcpy(dest, &space, sizeof(space)); | 2294 | memcpy(dest, &space, sizeof(space)); |
2289 | dest++; | 2295 | dest++; |
2290 | space_args.total_spaces++; | 2296 | space_args.total_spaces++; |
2297 | slot_count--; | ||
2291 | } | 2298 | } |
2299 | if (!slot_count) | ||
2300 | break; | ||
2292 | } | 2301 | } |
2293 | up_read(&info->groups_sem); | 2302 | up_read(&info->groups_sem); |
2294 | } | 2303 | } |