aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2012-11-26 03:50:11 -0500
committerChris Mason <chris.mason@fusionio.com>2012-12-16 20:46:11 -0500
commit905b0dda06a064db08b8a814e968786ff3c4cc19 (patch)
tree1a5c06529fdeee6c60e366f54c28cd1a2a34ce51 /fs/btrfs
parentb8e95489bf0ddf767e4bd38f537e0adad16ee830 (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.c73
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
3561static long btrfs_ioctl_quota_ctl(struct btrfs_root *root, void __user *arg) 3561static 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
3610out: 3613out:
3611 kfree(sa); 3614 kfree(sa);
3615drop_write:
3616 mnt_drop_write_file(file);
3612 return ret; 3617 return ret;
3613} 3618}
3614 3619
3615static long btrfs_ioctl_qgroup_assign(struct btrfs_root *root, void __user *arg) 3620static 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
3651out: 3660out:
3652 kfree(sa); 3661 kfree(sa);
3662drop_write:
3663 mnt_drop_write_file(file);
3653 return ret; 3664 return ret;
3654} 3665}
3655 3666
3656static long btrfs_ioctl_qgroup_create(struct btrfs_root *root, void __user *arg) 3667static 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
3691out: 3706out:
3692 kfree(sa); 3707 kfree(sa);
3708drop_write:
3709 mnt_drop_write_file(file);
3693 return ret; 3710 return ret;
3694} 3711}
3695 3712
3696static long btrfs_ioctl_qgroup_limit(struct btrfs_root *root, void __user *arg) 3713static 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
3733out: 3754out:
3734 kfree(sa); 3755 kfree(sa);
3756drop_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 }