diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2013-07-12 06:34:42 -0400 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2013-07-12 06:34:42 -0400 |
| commit | f2006e27396f55276f24434f56e208d86e7f9908 (patch) | |
| tree | 71896db916d33888b4286f80117d3cac0da40e6d /fs/btrfs/ioctl.c | |
| parent | e399eb56a6110e13f97e644658648602e2b08de7 (diff) | |
| parent | 9903883f1dd6e86f286b7bfa6e4b423f98c1cd9e (diff) | |
Merge branch 'linus' into timers/urgent
Get upstream changes so we can apply fixes against them
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'fs/btrfs/ioctl.c')
| -rw-r--r-- | fs/btrfs/ioctl.c | 82 |
1 files changed, 52 insertions, 30 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 0f81d67cdc8d..238a05545ee2 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
| @@ -555,6 +555,12 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, | |||
| 555 | if (!root->ref_cows) | 555 | if (!root->ref_cows) |
| 556 | return -EINVAL; | 556 | return -EINVAL; |
| 557 | 557 | ||
| 558 | ret = btrfs_start_delalloc_inodes(root, 0); | ||
| 559 | if (ret) | ||
| 560 | return ret; | ||
| 561 | |||
| 562 | btrfs_wait_ordered_extents(root, 0); | ||
| 563 | |||
| 558 | pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS); | 564 | pending_snapshot = kzalloc(sizeof(*pending_snapshot), GFP_NOFS); |
| 559 | if (!pending_snapshot) | 565 | if (!pending_snapshot) |
| 560 | return -ENOMEM; | 566 | return -ENOMEM; |
| @@ -2354,14 +2360,6 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg) | |||
| 2354 | if (ret) | 2360 | if (ret) |
| 2355 | return ret; | 2361 | return ret; |
| 2356 | 2362 | ||
| 2357 | if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running, | ||
| 2358 | 1)) { | ||
| 2359 | pr_info("btrfs: dev add/delete/balance/replace/resize operation in progress\n"); | ||
| 2360 | mnt_drop_write_file(file); | ||
| 2361 | return -EINVAL; | ||
| 2362 | } | ||
| 2363 | |||
| 2364 | mutex_lock(&root->fs_info->volume_mutex); | ||
| 2365 | vol_args = memdup_user(arg, sizeof(*vol_args)); | 2363 | vol_args = memdup_user(arg, sizeof(*vol_args)); |
| 2366 | if (IS_ERR(vol_args)) { | 2364 | if (IS_ERR(vol_args)) { |
| 2367 | ret = PTR_ERR(vol_args); | 2365 | ret = PTR_ERR(vol_args); |
| @@ -2369,12 +2367,20 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg) | |||
| 2369 | } | 2367 | } |
| 2370 | 2368 | ||
| 2371 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; | 2369 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; |
| 2372 | ret = btrfs_rm_device(root, vol_args->name); | ||
| 2373 | 2370 | ||
| 2374 | kfree(vol_args); | 2371 | if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running, |
| 2375 | out: | 2372 | 1)) { |
| 2373 | ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS; | ||
| 2374 | goto out; | ||
| 2375 | } | ||
| 2376 | |||
| 2377 | mutex_lock(&root->fs_info->volume_mutex); | ||
| 2378 | ret = btrfs_rm_device(root, vol_args->name); | ||
| 2376 | mutex_unlock(&root->fs_info->volume_mutex); | 2379 | mutex_unlock(&root->fs_info->volume_mutex); |
| 2377 | atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0); | 2380 | atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0); |
| 2381 | |||
| 2382 | out: | ||
| 2383 | kfree(vol_args); | ||
| 2378 | mnt_drop_write_file(file); | 2384 | mnt_drop_write_file(file); |
| 2379 | return ret; | 2385 | return ret; |
| 2380 | } | 2386 | } |
| @@ -2480,6 +2486,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
| 2480 | int ret; | 2486 | int ret; |
| 2481 | u64 len = olen; | 2487 | u64 len = olen; |
| 2482 | u64 bs = root->fs_info->sb->s_blocksize; | 2488 | u64 bs = root->fs_info->sb->s_blocksize; |
| 2489 | int same_inode = 0; | ||
| 2483 | 2490 | ||
| 2484 | /* | 2491 | /* |
| 2485 | * TODO: | 2492 | * TODO: |
| @@ -2516,7 +2523,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
| 2516 | 2523 | ||
| 2517 | ret = -EINVAL; | 2524 | ret = -EINVAL; |
| 2518 | if (src == inode) | 2525 | if (src == inode) |
| 2519 | goto out_fput; | 2526 | same_inode = 1; |
| 2520 | 2527 | ||
| 2521 | /* the src must be open for reading */ | 2528 | /* the src must be open for reading */ |
| 2522 | if (!(src_file.file->f_mode & FMODE_READ)) | 2529 | if (!(src_file.file->f_mode & FMODE_READ)) |
| @@ -2547,12 +2554,16 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
| 2547 | } | 2554 | } |
| 2548 | path->reada = 2; | 2555 | path->reada = 2; |
| 2549 | 2556 | ||
| 2550 | if (inode < src) { | 2557 | if (!same_inode) { |
| 2551 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); | 2558 | if (inode < src) { |
| 2552 | mutex_lock_nested(&src->i_mutex, I_MUTEX_CHILD); | 2559 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_PARENT); |
| 2560 | mutex_lock_nested(&src->i_mutex, I_MUTEX_CHILD); | ||
| 2561 | } else { | ||
| 2562 | mutex_lock_nested(&src->i_mutex, I_MUTEX_PARENT); | ||
| 2563 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD); | ||
| 2564 | } | ||
| 2553 | } else { | 2565 | } else { |
| 2554 | mutex_lock_nested(&src->i_mutex, I_MUTEX_PARENT); | 2566 | mutex_lock(&src->i_mutex); |
| 2555 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD); | ||
| 2556 | } | 2567 | } |
| 2557 | 2568 | ||
| 2558 | /* determine range to clone */ | 2569 | /* determine range to clone */ |
| @@ -2570,6 +2581,12 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
| 2570 | !IS_ALIGNED(destoff, bs)) | 2581 | !IS_ALIGNED(destoff, bs)) |
| 2571 | goto out_unlock; | 2582 | goto out_unlock; |
| 2572 | 2583 | ||
| 2584 | /* verify if ranges are overlapped within the same file */ | ||
| 2585 | if (same_inode) { | ||
| 2586 | if (destoff + len > off && destoff < off + len) | ||
| 2587 | goto out_unlock; | ||
| 2588 | } | ||
| 2589 | |||
| 2573 | if (destoff > inode->i_size) { | 2590 | if (destoff > inode->i_size) { |
| 2574 | ret = btrfs_cont_expand(inode, inode->i_size, destoff); | 2591 | ret = btrfs_cont_expand(inode, inode->i_size, destoff); |
| 2575 | if (ret) | 2592 | if (ret) |
| @@ -2846,7 +2863,8 @@ out: | |||
| 2846 | unlock_extent(&BTRFS_I(src)->io_tree, off, off + len - 1); | 2863 | unlock_extent(&BTRFS_I(src)->io_tree, off, off + len - 1); |
| 2847 | out_unlock: | 2864 | out_unlock: |
| 2848 | mutex_unlock(&src->i_mutex); | 2865 | mutex_unlock(&src->i_mutex); |
| 2849 | mutex_unlock(&inode->i_mutex); | 2866 | if (!same_inode) |
| 2867 | mutex_unlock(&inode->i_mutex); | ||
| 2850 | vfree(buf); | 2868 | vfree(buf); |
| 2851 | btrfs_free_path(path); | 2869 | btrfs_free_path(path); |
| 2852 | out_fput: | 2870 | out_fput: |
| @@ -2951,11 +2969,6 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp) | |||
| 2951 | goto out; | 2969 | goto out; |
| 2952 | } | 2970 | } |
| 2953 | 2971 | ||
| 2954 | if (btrfs_root_refs(&new_root->root_item) == 0) { | ||
| 2955 | ret = -ENOENT; | ||
| 2956 | goto out; | ||
| 2957 | } | ||
| 2958 | |||
| 2959 | path = btrfs_alloc_path(); | 2972 | path = btrfs_alloc_path(); |
| 2960 | if (!path) { | 2973 | if (!path) { |
| 2961 | ret = -ENOMEM; | 2974 | ret = -ENOMEM; |
| @@ -3719,9 +3732,6 @@ static long btrfs_ioctl_quota_ctl(struct file *file, void __user *arg) | |||
| 3719 | break; | 3732 | break; |
| 3720 | } | 3733 | } |
| 3721 | 3734 | ||
| 3722 | if (copy_to_user(arg, sa, sizeof(*sa))) | ||
| 3723 | ret = -EFAULT; | ||
| 3724 | |||
| 3725 | err = btrfs_commit_transaction(trans, root->fs_info->tree_root); | 3735 | err = btrfs_commit_transaction(trans, root->fs_info->tree_root); |
| 3726 | if (err && !ret) | 3736 | if (err && !ret) |
| 3727 | ret = err; | 3737 | ret = err; |
| @@ -3881,7 +3891,7 @@ drop_write: | |||
| 3881 | 3891 | ||
| 3882 | static long btrfs_ioctl_quota_rescan(struct file *file, void __user *arg) | 3892 | static long btrfs_ioctl_quota_rescan(struct file *file, void __user *arg) |
| 3883 | { | 3893 | { |
| 3884 | struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; | 3894 | struct btrfs_root *root = BTRFS_I(file_inode(file))->root; |
| 3885 | struct btrfs_ioctl_quota_rescan_args *qsa; | 3895 | struct btrfs_ioctl_quota_rescan_args *qsa; |
| 3886 | int ret; | 3896 | int ret; |
| 3887 | 3897 | ||
| @@ -3914,7 +3924,7 @@ drop_write: | |||
| 3914 | 3924 | ||
| 3915 | static long btrfs_ioctl_quota_rescan_status(struct file *file, void __user *arg) | 3925 | static long btrfs_ioctl_quota_rescan_status(struct file *file, void __user *arg) |
| 3916 | { | 3926 | { |
| 3917 | struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; | 3927 | struct btrfs_root *root = BTRFS_I(file_inode(file))->root; |
| 3918 | struct btrfs_ioctl_quota_rescan_args *qsa; | 3928 | struct btrfs_ioctl_quota_rescan_args *qsa; |
| 3919 | int ret = 0; | 3929 | int ret = 0; |
| 3920 | 3930 | ||
| @@ -3937,6 +3947,16 @@ static long btrfs_ioctl_quota_rescan_status(struct file *file, void __user *arg) | |||
| 3937 | return ret; | 3947 | return ret; |
| 3938 | } | 3948 | } |
| 3939 | 3949 | ||
| 3950 | static long btrfs_ioctl_quota_rescan_wait(struct file *file, void __user *arg) | ||
| 3951 | { | ||
| 3952 | struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; | ||
| 3953 | |||
| 3954 | if (!capable(CAP_SYS_ADMIN)) | ||
| 3955 | return -EPERM; | ||
| 3956 | |||
| 3957 | return btrfs_qgroup_wait_for_completion(root->fs_info); | ||
| 3958 | } | ||
| 3959 | |||
| 3940 | static long btrfs_ioctl_set_received_subvol(struct file *file, | 3960 | static long btrfs_ioctl_set_received_subvol(struct file *file, |
| 3941 | void __user *arg) | 3961 | void __user *arg) |
| 3942 | { | 3962 | { |
| @@ -4020,7 +4040,7 @@ out: | |||
| 4020 | 4040 | ||
| 4021 | static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) | 4041 | static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) |
| 4022 | { | 4042 | { |
| 4023 | struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; | 4043 | struct btrfs_root *root = BTRFS_I(file_inode(file))->root; |
| 4024 | const char *label = root->fs_info->super_copy->label; | 4044 | const char *label = root->fs_info->super_copy->label; |
| 4025 | size_t len = strnlen(label, BTRFS_LABEL_SIZE); | 4045 | size_t len = strnlen(label, BTRFS_LABEL_SIZE); |
| 4026 | int ret; | 4046 | int ret; |
| @@ -4039,7 +4059,7 @@ static int btrfs_ioctl_get_fslabel(struct file *file, void __user *arg) | |||
| 4039 | 4059 | ||
| 4040 | static int btrfs_ioctl_set_fslabel(struct file *file, void __user *arg) | 4060 | static int btrfs_ioctl_set_fslabel(struct file *file, void __user *arg) |
| 4041 | { | 4061 | { |
| 4042 | struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; | 4062 | struct btrfs_root *root = BTRFS_I(file_inode(file))->root; |
| 4043 | struct btrfs_super_block *super_block = root->fs_info->super_copy; | 4063 | struct btrfs_super_block *super_block = root->fs_info->super_copy; |
| 4044 | struct btrfs_trans_handle *trans; | 4064 | struct btrfs_trans_handle *trans; |
| 4045 | char label[BTRFS_LABEL_SIZE]; | 4065 | char label[BTRFS_LABEL_SIZE]; |
| @@ -4179,6 +4199,8 @@ long btrfs_ioctl(struct file *file, unsigned int | |||
| 4179 | return btrfs_ioctl_quota_rescan(file, argp); | 4199 | return btrfs_ioctl_quota_rescan(file, argp); |
| 4180 | case BTRFS_IOC_QUOTA_RESCAN_STATUS: | 4200 | case BTRFS_IOC_QUOTA_RESCAN_STATUS: |
| 4181 | return btrfs_ioctl_quota_rescan_status(file, argp); | 4201 | return btrfs_ioctl_quota_rescan_status(file, argp); |
| 4202 | case BTRFS_IOC_QUOTA_RESCAN_WAIT: | ||
| 4203 | return btrfs_ioctl_quota_rescan_wait(file, argp); | ||
| 4182 | case BTRFS_IOC_DEV_REPLACE: | 4204 | case BTRFS_IOC_DEV_REPLACE: |
| 4183 | return btrfs_ioctl_dev_replace(root, argp); | 4205 | return btrfs_ioctl_dev_replace(root, argp); |
| 4184 | case BTRFS_IOC_GET_FSLABEL: | 4206 | case BTRFS_IOC_GET_FSLABEL: |
