aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r--fs/btrfs/ioctl.c62
1 files changed, 18 insertions, 44 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 7594bec1be10..2624b53ea783 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -437,10 +437,6 @@ out_unlock:
437 return 0; 437 return 0;
438} 438}
439 439
440/*
441 * Called inside transaction, so use GFP_NOFS
442 */
443
444static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg) 440static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg)
445{ 441{
446 u64 new_size; 442 u64 new_size;
@@ -461,15 +457,9 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg)
461 if (!capable(CAP_SYS_ADMIN)) 457 if (!capable(CAP_SYS_ADMIN))
462 return -EPERM; 458 return -EPERM;
463 459
464 vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); 460 vol_args = memdup_user(arg, sizeof(*vol_args));
465 461 if (IS_ERR(vol_args))
466 if (!vol_args) 462 return PTR_ERR(vol_args);
467 return -ENOMEM;
468
469 if (copy_from_user(vol_args, arg, sizeof(*vol_args))) {
470 ret = -EFAULT;
471 goto out;
472 }
473 463
474 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; 464 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
475 namelen = strlen(vol_args->name); 465 namelen = strlen(vol_args->name);
@@ -483,11 +473,13 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg)
483 *devstr = '\0'; 473 *devstr = '\0';
484 devstr = vol_args->name; 474 devstr = vol_args->name;
485 devid = simple_strtoull(devstr, &end, 10); 475 devid = simple_strtoull(devstr, &end, 10);
486 printk(KERN_INFO "resizing devid %llu\n", devid); 476 printk(KERN_INFO "resizing devid %llu\n",
477 (unsigned long long)devid);
487 } 478 }
488 device = btrfs_find_device(root, devid, NULL, NULL); 479 device = btrfs_find_device(root, devid, NULL, NULL);
489 if (!device) { 480 if (!device) {
490 printk(KERN_INFO "resizer unable to find device %llu\n", devid); 481 printk(KERN_INFO "resizer unable to find device %llu\n",
482 (unsigned long long)devid);
491 ret = -EINVAL; 483 ret = -EINVAL;
492 goto out_unlock; 484 goto out_unlock;
493 } 485 }
@@ -545,7 +537,6 @@ static int btrfs_ioctl_resize(struct btrfs_root *root, void __user *arg)
545 537
546out_unlock: 538out_unlock:
547 mutex_unlock(&root->fs_info->volume_mutex); 539 mutex_unlock(&root->fs_info->volume_mutex);
548out:
549 kfree(vol_args); 540 kfree(vol_args);
550 return ret; 541 return ret;
551} 542}
@@ -565,15 +556,9 @@ static noinline int btrfs_ioctl_snap_create(struct file *file,
565 if (root->fs_info->sb->s_flags & MS_RDONLY) 556 if (root->fs_info->sb->s_flags & MS_RDONLY)
566 return -EROFS; 557 return -EROFS;
567 558
568 vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); 559 vol_args = memdup_user(arg, sizeof(*vol_args));
569 560 if (IS_ERR(vol_args))
570 if (!vol_args) 561 return PTR_ERR(vol_args);
571 return -ENOMEM;
572
573 if (copy_from_user(vol_args, arg, sizeof(*vol_args))) {
574 ret = -EFAULT;
575 goto out;
576 }
577 562
578 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; 563 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
579 namelen = strlen(vol_args->name); 564 namelen = strlen(vol_args->name);
@@ -675,19 +660,13 @@ static long btrfs_ioctl_add_dev(struct btrfs_root *root, void __user *arg)
675 if (!capable(CAP_SYS_ADMIN)) 660 if (!capable(CAP_SYS_ADMIN))
676 return -EPERM; 661 return -EPERM;
677 662
678 vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); 663 vol_args = memdup_user(arg, sizeof(*vol_args));
679 664 if (IS_ERR(vol_args))
680 if (!vol_args) 665 return PTR_ERR(vol_args);
681 return -ENOMEM;
682 666
683 if (copy_from_user(vol_args, arg, sizeof(*vol_args))) {
684 ret = -EFAULT;
685 goto out;
686 }
687 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; 667 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
688 ret = btrfs_init_new_device(root, vol_args->name); 668 ret = btrfs_init_new_device(root, vol_args->name);
689 669
690out:
691 kfree(vol_args); 670 kfree(vol_args);
692 return ret; 671 return ret;
693} 672}
@@ -703,19 +682,13 @@ static long btrfs_ioctl_rm_dev(struct btrfs_root *root, void __user *arg)
703 if (root->fs_info->sb->s_flags & MS_RDONLY) 682 if (root->fs_info->sb->s_flags & MS_RDONLY)
704 return -EROFS; 683 return -EROFS;
705 684
706 vol_args = kmalloc(sizeof(*vol_args), GFP_NOFS); 685 vol_args = memdup_user(arg, sizeof(*vol_args));
707 686 if (IS_ERR(vol_args))
708 if (!vol_args) 687 return PTR_ERR(vol_args);
709 return -ENOMEM;
710 688
711 if (copy_from_user(vol_args, arg, sizeof(*vol_args))) {
712 ret = -EFAULT;
713 goto out;
714 }
715 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; 689 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
716 ret = btrfs_rm_device(root, vol_args->name); 690 ret = btrfs_rm_device(root, vol_args->name);
717 691
718out:
719 kfree(vol_args); 692 kfree(vol_args);
720 return ret; 693 return ret;
721} 694}
@@ -830,7 +803,8 @@ static long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
830 BUG_ON(!trans); 803 BUG_ON(!trans);
831 804
832 /* punch hole in destination first */ 805 /* punch hole in destination first */
833 btrfs_drop_extents(trans, root, inode, off, off+len, 0, &hint_byte); 806 btrfs_drop_extents(trans, root, inode, off, off + len,
807 off + len, 0, &hint_byte);
834 808
835 /* clone data */ 809 /* clone data */
836 key.objectid = src->i_ino; 810 key.objectid = src->i_ino;