diff options
author | Miao Xie <miaox@cn.fujitsu.com> | 2012-11-26 03:50:11 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2012-12-16 20:46:11 -0500 |
commit | 905b0dda06a064db08b8a814e968786ff3c4cc19 (patch) | |
tree | 1a5c06529fdeee6c60e366f54c28cd1a2a34ce51 /fs/btrfs | |
parent | b8e95489bf0ddf767e4bd38f537e0adad16ee830 (diff) |
Btrfs: get write access for qgroup operations
We need get write access for qgroup operations, or we will modify the R/O fs.
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/ioctl.c | 73 |
1 files changed, 48 insertions, 25 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 12b18c01b911..657d83ca9dea 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -3558,8 +3558,9 @@ out: | |||
3558 | return ret; | 3558 | return ret; |
3559 | } | 3559 | } |
3560 | 3560 | ||
3561 | static long btrfs_ioctl_quota_ctl(struct btrfs_root *root, void __user *arg) | 3561 | static long btrfs_ioctl_quota_ctl(struct file *file, void __user *arg) |
3562 | { | 3562 | { |
3563 | struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; | ||
3563 | struct btrfs_ioctl_quota_ctl_args *sa; | 3564 | struct btrfs_ioctl_quota_ctl_args *sa; |
3564 | struct btrfs_trans_handle *trans = NULL; | 3565 | struct btrfs_trans_handle *trans = NULL; |
3565 | int ret; | 3566 | int ret; |
@@ -3568,12 +3569,15 @@ static long btrfs_ioctl_quota_ctl(struct btrfs_root *root, void __user *arg) | |||
3568 | if (!capable(CAP_SYS_ADMIN)) | 3569 | if (!capable(CAP_SYS_ADMIN)) |
3569 | return -EPERM; | 3570 | return -EPERM; |
3570 | 3571 | ||
3571 | if (root->fs_info->sb->s_flags & MS_RDONLY) | 3572 | ret = mnt_want_write_file(file); |
3572 | return -EROFS; | 3573 | if (ret) |
3574 | return ret; | ||
3573 | 3575 | ||
3574 | sa = memdup_user(arg, sizeof(*sa)); | 3576 | sa = memdup_user(arg, sizeof(*sa)); |
3575 | if (IS_ERR(sa)) | 3577 | if (IS_ERR(sa)) { |
3576 | return PTR_ERR(sa); | 3578 | ret = PTR_ERR(sa); |
3579 | goto drop_write; | ||
3580 | } | ||
3577 | 3581 | ||
3578 | if (sa->cmd != BTRFS_QUOTA_CTL_RESCAN) { | 3582 | if (sa->cmd != BTRFS_QUOTA_CTL_RESCAN) { |
3579 | trans = btrfs_start_transaction(root, 2); | 3583 | trans = btrfs_start_transaction(root, 2); |
@@ -3606,14 +3610,16 @@ static long btrfs_ioctl_quota_ctl(struct btrfs_root *root, void __user *arg) | |||
3606 | if (err && !ret) | 3610 | if (err && !ret) |
3607 | ret = err; | 3611 | ret = err; |
3608 | } | 3612 | } |
3609 | |||
3610 | out: | 3613 | out: |
3611 | kfree(sa); | 3614 | kfree(sa); |
3615 | drop_write: | ||
3616 | mnt_drop_write_file(file); | ||
3612 | return ret; | 3617 | return ret; |
3613 | } | 3618 | } |
3614 | 3619 | ||
3615 | static long btrfs_ioctl_qgroup_assign(struct btrfs_root *root, void __user *arg) | 3620 | static long btrfs_ioctl_qgroup_assign(struct file *file, void __user *arg) |
3616 | { | 3621 | { |
3622 | struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; | ||
3617 | struct btrfs_ioctl_qgroup_assign_args *sa; | 3623 | struct btrfs_ioctl_qgroup_assign_args *sa; |
3618 | struct btrfs_trans_handle *trans; | 3624 | struct btrfs_trans_handle *trans; |
3619 | int ret; | 3625 | int ret; |
@@ -3622,12 +3628,15 @@ static long btrfs_ioctl_qgroup_assign(struct btrfs_root *root, void __user *arg) | |||
3622 | if (!capable(CAP_SYS_ADMIN)) | 3628 | if (!capable(CAP_SYS_ADMIN)) |
3623 | return -EPERM; | 3629 | return -EPERM; |
3624 | 3630 | ||
3625 | if (root->fs_info->sb->s_flags & MS_RDONLY) | 3631 | ret = mnt_want_write_file(file); |
3626 | return -EROFS; | 3632 | if (ret) |
3633 | return ret; | ||
3627 | 3634 | ||
3628 | sa = memdup_user(arg, sizeof(*sa)); | 3635 | sa = memdup_user(arg, sizeof(*sa)); |
3629 | if (IS_ERR(sa)) | 3636 | if (IS_ERR(sa)) { |
3630 | return PTR_ERR(sa); | 3637 | ret = PTR_ERR(sa); |
3638 | goto drop_write; | ||
3639 | } | ||
3631 | 3640 | ||
3632 | trans = btrfs_join_transaction(root); | 3641 | trans = btrfs_join_transaction(root); |
3633 | if (IS_ERR(trans)) { | 3642 | if (IS_ERR(trans)) { |
@@ -3650,11 +3659,14 @@ static long btrfs_ioctl_qgroup_assign(struct btrfs_root *root, void __user *arg) | |||
3650 | 3659 | ||
3651 | out: | 3660 | out: |
3652 | kfree(sa); | 3661 | kfree(sa); |
3662 | drop_write: | ||
3663 | mnt_drop_write_file(file); | ||
3653 | return ret; | 3664 | return ret; |
3654 | } | 3665 | } |
3655 | 3666 | ||
3656 | static long btrfs_ioctl_qgroup_create(struct btrfs_root *root, void __user *arg) | 3667 | static long btrfs_ioctl_qgroup_create(struct file *file, void __user *arg) |
3657 | { | 3668 | { |
3669 | struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; | ||
3658 | struct btrfs_ioctl_qgroup_create_args *sa; | 3670 | struct btrfs_ioctl_qgroup_create_args *sa; |
3659 | struct btrfs_trans_handle *trans; | 3671 | struct btrfs_trans_handle *trans; |
3660 | int ret; | 3672 | int ret; |
@@ -3663,12 +3675,15 @@ static long btrfs_ioctl_qgroup_create(struct btrfs_root *root, void __user *arg) | |||
3663 | if (!capable(CAP_SYS_ADMIN)) | 3675 | if (!capable(CAP_SYS_ADMIN)) |
3664 | return -EPERM; | 3676 | return -EPERM; |
3665 | 3677 | ||
3666 | if (root->fs_info->sb->s_flags & MS_RDONLY) | 3678 | ret = mnt_want_write_file(file); |
3667 | return -EROFS; | 3679 | if (ret) |
3680 | return ret; | ||
3668 | 3681 | ||
3669 | sa = memdup_user(arg, sizeof(*sa)); | 3682 | sa = memdup_user(arg, sizeof(*sa)); |
3670 | if (IS_ERR(sa)) | 3683 | if (IS_ERR(sa)) { |
3671 | return PTR_ERR(sa); | 3684 | ret = PTR_ERR(sa); |
3685 | goto drop_write; | ||
3686 | } | ||
3672 | 3687 | ||
3673 | trans = btrfs_join_transaction(root); | 3688 | trans = btrfs_join_transaction(root); |
3674 | if (IS_ERR(trans)) { | 3689 | if (IS_ERR(trans)) { |
@@ -3690,11 +3705,14 @@ static long btrfs_ioctl_qgroup_create(struct btrfs_root *root, void __user *arg) | |||
3690 | 3705 | ||
3691 | out: | 3706 | out: |
3692 | kfree(sa); | 3707 | kfree(sa); |
3708 | drop_write: | ||
3709 | mnt_drop_write_file(file); | ||
3693 | return ret; | 3710 | return ret; |
3694 | } | 3711 | } |
3695 | 3712 | ||
3696 | static long btrfs_ioctl_qgroup_limit(struct btrfs_root *root, void __user *arg) | 3713 | static long btrfs_ioctl_qgroup_limit(struct file *file, void __user *arg) |
3697 | { | 3714 | { |
3715 | struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; | ||
3698 | struct btrfs_ioctl_qgroup_limit_args *sa; | 3716 | struct btrfs_ioctl_qgroup_limit_args *sa; |
3699 | struct btrfs_trans_handle *trans; | 3717 | struct btrfs_trans_handle *trans; |
3700 | int ret; | 3718 | int ret; |
@@ -3704,12 +3722,15 @@ static long btrfs_ioctl_qgroup_limit(struct btrfs_root *root, void __user *arg) | |||
3704 | if (!capable(CAP_SYS_ADMIN)) | 3722 | if (!capable(CAP_SYS_ADMIN)) |
3705 | return -EPERM; | 3723 | return -EPERM; |
3706 | 3724 | ||
3707 | if (root->fs_info->sb->s_flags & MS_RDONLY) | 3725 | ret = mnt_want_write_file(file); |
3708 | return -EROFS; | 3726 | if (ret) |
3727 | return ret; | ||
3709 | 3728 | ||
3710 | sa = memdup_user(arg, sizeof(*sa)); | 3729 | sa = memdup_user(arg, sizeof(*sa)); |
3711 | if (IS_ERR(sa)) | 3730 | if (IS_ERR(sa)) { |
3712 | return PTR_ERR(sa); | 3731 | ret = PTR_ERR(sa); |
3732 | goto drop_write; | ||
3733 | } | ||
3713 | 3734 | ||
3714 | trans = btrfs_join_transaction(root); | 3735 | trans = btrfs_join_transaction(root); |
3715 | if (IS_ERR(trans)) { | 3736 | if (IS_ERR(trans)) { |
@@ -3732,6 +3753,8 @@ static long btrfs_ioctl_qgroup_limit(struct btrfs_root *root, void __user *arg) | |||
3732 | 3753 | ||
3733 | out: | 3754 | out: |
3734 | kfree(sa); | 3755 | kfree(sa); |
3756 | drop_write: | ||
3757 | mnt_drop_write_file(file); | ||
3735 | return ret; | 3758 | return ret; |
3736 | } | 3759 | } |
3737 | 3760 | ||
@@ -3907,13 +3930,13 @@ long btrfs_ioctl(struct file *file, unsigned int | |||
3907 | case BTRFS_IOC_GET_DEV_STATS: | 3930 | case BTRFS_IOC_GET_DEV_STATS: |
3908 | return btrfs_ioctl_get_dev_stats(root, argp); | 3931 | return btrfs_ioctl_get_dev_stats(root, argp); |
3909 | case BTRFS_IOC_QUOTA_CTL: | 3932 | case BTRFS_IOC_QUOTA_CTL: |
3910 | return btrfs_ioctl_quota_ctl(root, argp); | 3933 | return btrfs_ioctl_quota_ctl(file, argp); |
3911 | case BTRFS_IOC_QGROUP_ASSIGN: | 3934 | case BTRFS_IOC_QGROUP_ASSIGN: |
3912 | return btrfs_ioctl_qgroup_assign(root, argp); | 3935 | return btrfs_ioctl_qgroup_assign(file, argp); |
3913 | case BTRFS_IOC_QGROUP_CREATE: | 3936 | case BTRFS_IOC_QGROUP_CREATE: |
3914 | return btrfs_ioctl_qgroup_create(root, argp); | 3937 | return btrfs_ioctl_qgroup_create(file, argp); |
3915 | case BTRFS_IOC_QGROUP_LIMIT: | 3938 | case BTRFS_IOC_QGROUP_LIMIT: |
3916 | return btrfs_ioctl_qgroup_limit(root, argp); | 3939 | return btrfs_ioctl_qgroup_limit(file, argp); |
3917 | case BTRFS_IOC_DEV_REPLACE: | 3940 | case BTRFS_IOC_DEV_REPLACE: |
3918 | return btrfs_ioctl_dev_replace(root, argp); | 3941 | return btrfs_ioctl_dev_replace(root, argp); |
3919 | } | 3942 | } |