diff options
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/ioctl.c | 49 | ||||
-rw-r--r-- | fs/btrfs/super.c | 25 |
2 files changed, 20 insertions, 54 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index db84aa48ab7a..2624b53ea783 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -457,15 +457,9 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg) | |||
457 | if (!capable(CAP_SYS_ADMIN)) | 457 | if (!capable(CAP_SYS_ADMIN)) |
458 | return -EPERM; | 458 | return -EPERM; |
459 | 459 | ||
460 | vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); | 460 | vol_args = memdup_user(arg, sizeof(*vol_args)); |
461 | 461 | if (IS_ERR(vol_args)) | |
462 | if (!vol_args) | 462 | return PTR_ERR(vol_args); |
463 | return -ENOMEM; | ||
464 | |||
465 | if (copy_from_user(vol_args, arg, sizeof(*vol_args))) { | ||
466 | ret = -EFAULT; | ||
467 | goto out; | ||
468 | } | ||
469 | 463 | ||
470 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; | 464 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; |
471 | namelen = strlen(vol_args->name); | 465 | namelen = strlen(vol_args->name); |
@@ -543,7 +537,6 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg) | |||
543 | 537 | ||
544 | out_unlock: | 538 | out_unlock: |
545 | mutex_unlock(&root->fs_info->volume_mutex); | 539 | mutex_unlock(&root->fs_info->volume_mutex); |
546 | out: | ||
547 | kfree(vol_args); | 540 | kfree(vol_args); |
548 | return ret; | 541 | return ret; |
549 | } | 542 | } |
@@ -563,15 +556,9 @@ static noinline int btrfs_ioctl_snap_create(struct file *file, | |||
563 | if (root->fs_info->sb->s_flags & MS_RDONLY) | 556 | if (root->fs_info->sb->s_flags & MS_RDONLY) |
564 | return -EROFS; | 557 | return -EROFS; |
565 | 558 | ||
566 | vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); | 559 | vol_args = memdup_user(arg, sizeof(*vol_args)); |
567 | 560 | if (IS_ERR(vol_args)) | |
568 | if (!vol_args) | 561 | return PTR_ERR(vol_args); |
569 | return -ENOMEM; | ||
570 | |||
571 | if (copy_from_user(vol_args, arg, sizeof(*vol_args))) { | ||
572 | ret = -EFAULT; | ||
573 | goto out; | ||
574 | } | ||
575 | 562 | ||
576 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; | 563 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; |
577 | namelen = strlen(vol_args->name); | 564 | namelen = strlen(vol_args->name); |
@@ -673,19 +660,13 @@ static long btrfs_ioctl_add_dev(struct btrfs_root *root, void __user *arg) | |||
673 | if (!capable(CAP_SYS_ADMIN)) | 660 | if (!capable(CAP_SYS_ADMIN)) |
674 | return -EPERM; | 661 | return -EPERM; |
675 | 662 | ||
676 | vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); | 663 | vol_args = memdup_user(arg, sizeof(*vol_args)); |
664 | if (IS_ERR(vol_args)) | ||
665 | return PTR_ERR(vol_args); | ||
677 | 666 | ||
678 | if (!vol_args) | ||
679 | return -ENOMEM; | ||
680 | |||
681 | if (copy_from_user(vol_args, arg, sizeof(*vol_args))) { | ||
682 | ret = -EFAULT; | ||
683 | goto out; | ||
684 | } | ||
685 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; | 667 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; |
686 | ret = btrfs_init_new_device(root, vol_args->name); | 668 | ret = btrfs_init_new_device(root, vol_args->name); |
687 | 669 | ||
688 | out: | ||
689 | kfree(vol_args); | 670 | kfree(vol_args); |
690 | return ret; | 671 | return ret; |
691 | } | 672 | } |
@@ -701,19 +682,13 @@ static long btrfs_ioctl_rm_dev(struct btrfs_root *root, void __user *arg) | |||
701 | if (root->fs_info->sb->s_flags & MS_RDONLY) | 682 | if (root->fs_info->sb->s_flags & MS_RDONLY) |
702 | return -EROFS; | 683 | return -EROFS; |
703 | 684 | ||
704 | vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); | 685 | vol_args = memdup_user(arg, sizeof(*vol_args)); |
686 | if (IS_ERR(vol_args)) | ||
687 | return PTR_ERR(vol_args); | ||
705 | 688 | ||
706 | if (!vol_args) | ||
707 | return -ENOMEM; | ||
708 | |||
709 | if (copy_from_user(vol_args, arg, sizeof(*vol_args))) { | ||
710 | ret = -EFAULT; | ||
711 | goto out; | ||
712 | } | ||
713 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; | 689 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; |
714 | ret = btrfs_rm_device(root, vol_args->name); | 690 | ret = btrfs_rm_device(root, vol_args->name); |
715 | 691 | ||
716 | out: | ||
717 | kfree(vol_args); | 692 | kfree(vol_args); |
718 | return ret; | 693 | return ret; |
719 | } | 694 | } |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index e99510bfbffd..2ff7cd2db25f 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -502,8 +502,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags, | |||
502 | 502 | ||
503 | if (s->s_root) { | 503 | if (s->s_root) { |
504 | if ((flags ^ s->s_flags) & MS_RDONLY) { | 504 | if ((flags ^ s->s_flags) & MS_RDONLY) { |
505 | up_write(&s->s_umount); | 505 | deactivate_locked_super(s); |
506 | deactivate_super(s); | ||
507 | error = -EBUSY; | 506 | error = -EBUSY; |
508 | goto error_close_devices; | 507 | goto error_close_devices; |
509 | } | 508 | } |
@@ -517,8 +516,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags, | |||
517 | error = btrfs_fill_super(s, fs_devices, data, | 516 | error = btrfs_fill_super(s, fs_devices, data, |
518 | flags & MS_SILENT ? 1 : 0); | 517 | flags & MS_SILENT ? 1 : 0); |
519 | if (error) { | 518 | if (error) { |
520 | up_write(&s->s_umount); | 519 | deactivate_locked_super(s); |
521 | deactivate_super(s); | ||
522 | goto error_free_subvol_name; | 520 | goto error_free_subvol_name; |
523 | } | 521 | } |
524 | 522 | ||
@@ -535,15 +533,13 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags, | |||
535 | mutex_unlock(&s->s_root->d_inode->i_mutex); | 533 | mutex_unlock(&s->s_root->d_inode->i_mutex); |
536 | 534 | ||
537 | if (IS_ERR(root)) { | 535 | if (IS_ERR(root)) { |
538 | up_write(&s->s_umount); | 536 | deactivate_locked_super(s); |
539 | deactivate_super(s); | ||
540 | error = PTR_ERR(root); | 537 | error = PTR_ERR(root); |
541 | goto error_free_subvol_name; | 538 | goto error_free_subvol_name; |
542 | } | 539 | } |
543 | if (!root->d_inode) { | 540 | if (!root->d_inode) { |
544 | dput(root); | 541 | dput(root); |
545 | up_write(&s->s_umount); | 542 | deactivate_locked_super(s); |
546 | deactivate_super(s); | ||
547 | error = -ENXIO; | 543 | error = -ENXIO; |
548 | goto error_free_subvol_name; | 544 | goto error_free_subvol_name; |
549 | } | 545 | } |
@@ -648,14 +644,9 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd, | |||
648 | if (!capable(CAP_SYS_ADMIN)) | 644 | if (!capable(CAP_SYS_ADMIN)) |
649 | return -EPERM; | 645 | return -EPERM; |
650 | 646 | ||
651 | vol = kmalloc(sizeof(*vol), GFP_KERNEL); | 647 | vol = memdup_user((void __user *)arg, sizeof(*vol)); |
652 | if (!vol) | 648 | if (IS_ERR(vol)) |
653 | return -ENOMEM; | 649 | return PTR_ERR(vol); |
654 | |||
655 | if (copy_from_user(vol, (void __user *)arg, sizeof(*vol))) { | ||
656 | ret = -EFAULT; | ||
657 | goto out; | ||
658 | } | ||
659 | 650 | ||
660 | switch (cmd) { | 651 | switch (cmd) { |
661 | case BTRFS_IOC_SCAN_DEV: | 652 | case BTRFS_IOC_SCAN_DEV: |
@@ -663,7 +654,7 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd, | |||
663 | &btrfs_fs_type, &fs_devices); | 654 | &btrfs_fs_type, &fs_devices); |
664 | break; | 655 | break; |
665 | } | 656 | } |
666 | out: | 657 | |
667 | kfree(vol); | 658 | kfree(vol); |
668 | return ret; | 659 | return ret; |
669 | } | 660 | } |