diff options
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r-- | fs/btrfs/ioctl.c | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 0401397b5c92..e79ff6b90cb7 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -1472,6 +1472,7 @@ static noinline int btrfs_ioctl_resize(struct file *file, | |||
1472 | struct btrfs_trans_handle *trans; | 1472 | struct btrfs_trans_handle *trans; |
1473 | struct btrfs_device *device = NULL; | 1473 | struct btrfs_device *device = NULL; |
1474 | char *sizestr; | 1474 | char *sizestr; |
1475 | char *retptr; | ||
1475 | char *devstr = NULL; | 1476 | char *devstr = NULL; |
1476 | int ret = 0; | 1477 | int ret = 0; |
1477 | int mod = 0; | 1478 | int mod = 0; |
@@ -1539,8 +1540,8 @@ static noinline int btrfs_ioctl_resize(struct file *file, | |||
1539 | mod = 1; | 1540 | mod = 1; |
1540 | sizestr++; | 1541 | sizestr++; |
1541 | } | 1542 | } |
1542 | new_size = memparse(sizestr, NULL); | 1543 | new_size = memparse(sizestr, &retptr); |
1543 | if (new_size == 0) { | 1544 | if (*retptr != '\0' || new_size == 0) { |
1544 | ret = -EINVAL; | 1545 | ret = -EINVAL; |
1545 | goto out_free; | 1546 | goto out_free; |
1546 | } | 1547 | } |
@@ -3140,8 +3141,9 @@ process_slot: | |||
3140 | new_key.offset + datal, | 3141 | new_key.offset + datal, |
3141 | 1); | 3142 | 1); |
3142 | if (ret) { | 3143 | if (ret) { |
3143 | btrfs_abort_transaction(trans, root, | 3144 | if (ret != -EINVAL) |
3144 | ret); | 3145 | btrfs_abort_transaction(trans, |
3146 | root, ret); | ||
3145 | btrfs_end_transaction(trans, root); | 3147 | btrfs_end_transaction(trans, root); |
3146 | goto out; | 3148 | goto out; |
3147 | } | 3149 | } |
@@ -3538,6 +3540,11 @@ static long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) | |||
3538 | up_read(&info->groups_sem); | 3540 | up_read(&info->groups_sem); |
3539 | } | 3541 | } |
3540 | 3542 | ||
3543 | /* | ||
3544 | * Global block reserve, exported as a space_info | ||
3545 | */ | ||
3546 | slot_count++; | ||
3547 | |||
3541 | /* space_slots == 0 means they are asking for a count */ | 3548 | /* space_slots == 0 means they are asking for a count */ |
3542 | if (space_args.space_slots == 0) { | 3549 | if (space_args.space_slots == 0) { |
3543 | space_args.total_spaces = slot_count; | 3550 | space_args.total_spaces = slot_count; |
@@ -3596,6 +3603,21 @@ static long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg) | |||
3596 | up_read(&info->groups_sem); | 3603 | up_read(&info->groups_sem); |
3597 | } | 3604 | } |
3598 | 3605 | ||
3606 | /* | ||
3607 | * Add global block reserve | ||
3608 | */ | ||
3609 | if (slot_count) { | ||
3610 | struct btrfs_block_rsv *block_rsv = &root->fs_info->global_block_rsv; | ||
3611 | |||
3612 | spin_lock(&block_rsv->lock); | ||
3613 | space.total_bytes = block_rsv->size; | ||
3614 | space.used_bytes = block_rsv->size - block_rsv->reserved; | ||
3615 | spin_unlock(&block_rsv->lock); | ||
3616 | space.flags = BTRFS_SPACE_INFO_GLOBAL_RSV; | ||
3617 | memcpy(dest, &space, sizeof(space)); | ||
3618 | space_args.total_spaces++; | ||
3619 | } | ||
3620 | |||
3599 | user_dest = (struct btrfs_ioctl_space_info __user *) | 3621 | user_dest = (struct btrfs_ioctl_space_info __user *) |
3600 | (arg + sizeof(struct btrfs_ioctl_space_args)); | 3622 | (arg + sizeof(struct btrfs_ioctl_space_args)); |
3601 | 3623 | ||
@@ -4531,9 +4553,8 @@ static long btrfs_ioctl_set_received_subvol_32(struct file *file, | |||
4531 | } | 4553 | } |
4532 | 4554 | ||
4533 | args64 = kmalloc(sizeof(*args64), GFP_NOFS); | 4555 | args64 = kmalloc(sizeof(*args64), GFP_NOFS); |
4534 | if (IS_ERR(args64)) { | 4556 | if (!args64) { |
4535 | ret = PTR_ERR(args64); | 4557 | ret = -ENOMEM; |
4536 | args64 = NULL; | ||
4537 | goto out; | 4558 | goto out; |
4538 | } | 4559 | } |
4539 | 4560 | ||