diff options
Diffstat (limited to 'fs/btrfs/ioctl.c')
-rw-r--r-- | fs/btrfs/ioctl.c | 198 |
1 files changed, 148 insertions, 50 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 0b8ba717175b..4e700694b741 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -125,10 +125,10 @@ static unsigned int btrfs_flags_to_ioctl(unsigned int flags) | |||
125 | if (flags & BTRFS_INODE_NODATACOW) | 125 | if (flags & BTRFS_INODE_NODATACOW) |
126 | iflags |= FS_NOCOW_FL; | 126 | iflags |= FS_NOCOW_FL; |
127 | 127 | ||
128 | if ((flags & BTRFS_INODE_COMPRESS) && !(flags & BTRFS_INODE_NOCOMPRESS)) | 128 | if (flags & BTRFS_INODE_NOCOMPRESS) |
129 | iflags |= FS_COMPR_FL; | ||
130 | else if (flags & BTRFS_INODE_NOCOMPRESS) | ||
131 | iflags |= FS_NOCOMP_FL; | 129 | iflags |= FS_NOCOMP_FL; |
130 | else if (flags & BTRFS_INODE_COMPRESS) | ||
131 | iflags |= FS_COMPR_FL; | ||
132 | 132 | ||
133 | return iflags; | 133 | return iflags; |
134 | } | 134 | } |
@@ -439,7 +439,7 @@ static noinline int create_subvol(struct inode *dir, | |||
439 | { | 439 | { |
440 | struct btrfs_trans_handle *trans; | 440 | struct btrfs_trans_handle *trans; |
441 | struct btrfs_key key; | 441 | struct btrfs_key key; |
442 | struct btrfs_root_item root_item; | 442 | struct btrfs_root_item *root_item; |
443 | struct btrfs_inode_item *inode_item; | 443 | struct btrfs_inode_item *inode_item; |
444 | struct extent_buffer *leaf; | 444 | struct extent_buffer *leaf; |
445 | struct btrfs_root *root = BTRFS_I(dir)->root; | 445 | struct btrfs_root *root = BTRFS_I(dir)->root; |
@@ -455,16 +455,22 @@ static noinline int create_subvol(struct inode *dir, | |||
455 | u64 qgroup_reserved; | 455 | u64 qgroup_reserved; |
456 | uuid_le new_uuid; | 456 | uuid_le new_uuid; |
457 | 457 | ||
458 | root_item = kzalloc(sizeof(*root_item), GFP_KERNEL); | ||
459 | if (!root_item) | ||
460 | return -ENOMEM; | ||
461 | |||
458 | ret = btrfs_find_free_objectid(root->fs_info->tree_root, &objectid); | 462 | ret = btrfs_find_free_objectid(root->fs_info->tree_root, &objectid); |
459 | if (ret) | 463 | if (ret) |
460 | return ret; | 464 | goto fail_free; |
461 | 465 | ||
462 | /* | 466 | /* |
463 | * Don't create subvolume whose level is not zero. Or qgroup will be | 467 | * Don't create subvolume whose level is not zero. Or qgroup will be |
464 | * screwed up since it assume subvolme qgroup's level to be 0. | 468 | * screwed up since it assume subvolme qgroup's level to be 0. |
465 | */ | 469 | */ |
466 | if (btrfs_qgroup_level(objectid)) | 470 | if (btrfs_qgroup_level(objectid)) { |
467 | return -ENOSPC; | 471 | ret = -ENOSPC; |
472 | goto fail_free; | ||
473 | } | ||
468 | 474 | ||
469 | btrfs_init_block_rsv(&block_rsv, BTRFS_BLOCK_RSV_TEMP); | 475 | btrfs_init_block_rsv(&block_rsv, BTRFS_BLOCK_RSV_TEMP); |
470 | /* | 476 | /* |
@@ -474,14 +480,14 @@ static noinline int create_subvol(struct inode *dir, | |||
474 | ret = btrfs_subvolume_reserve_metadata(root, &block_rsv, | 480 | ret = btrfs_subvolume_reserve_metadata(root, &block_rsv, |
475 | 8, &qgroup_reserved, false); | 481 | 8, &qgroup_reserved, false); |
476 | if (ret) | 482 | if (ret) |
477 | return ret; | 483 | goto fail_free; |
478 | 484 | ||
479 | trans = btrfs_start_transaction(root, 0); | 485 | trans = btrfs_start_transaction(root, 0); |
480 | if (IS_ERR(trans)) { | 486 | if (IS_ERR(trans)) { |
481 | ret = PTR_ERR(trans); | 487 | ret = PTR_ERR(trans); |
482 | btrfs_subvolume_release_metadata(root, &block_rsv, | 488 | btrfs_subvolume_release_metadata(root, &block_rsv, |
483 | qgroup_reserved); | 489 | qgroup_reserved); |
484 | return ret; | 490 | goto fail_free; |
485 | } | 491 | } |
486 | trans->block_rsv = &block_rsv; | 492 | trans->block_rsv = &block_rsv; |
487 | trans->bytes_reserved = block_rsv.size; | 493 | trans->bytes_reserved = block_rsv.size; |
@@ -509,47 +515,45 @@ static noinline int create_subvol(struct inode *dir, | |||
509 | BTRFS_UUID_SIZE); | 515 | BTRFS_UUID_SIZE); |
510 | btrfs_mark_buffer_dirty(leaf); | 516 | btrfs_mark_buffer_dirty(leaf); |
511 | 517 | ||
512 | memset(&root_item, 0, sizeof(root_item)); | 518 | inode_item = &root_item->inode; |
513 | |||
514 | inode_item = &root_item.inode; | ||
515 | btrfs_set_stack_inode_generation(inode_item, 1); | 519 | btrfs_set_stack_inode_generation(inode_item, 1); |
516 | btrfs_set_stack_inode_size(inode_item, 3); | 520 | btrfs_set_stack_inode_size(inode_item, 3); |
517 | btrfs_set_stack_inode_nlink(inode_item, 1); | 521 | btrfs_set_stack_inode_nlink(inode_item, 1); |
518 | btrfs_set_stack_inode_nbytes(inode_item, root->nodesize); | 522 | btrfs_set_stack_inode_nbytes(inode_item, root->nodesize); |
519 | btrfs_set_stack_inode_mode(inode_item, S_IFDIR | 0755); | 523 | btrfs_set_stack_inode_mode(inode_item, S_IFDIR | 0755); |
520 | 524 | ||
521 | btrfs_set_root_flags(&root_item, 0); | 525 | btrfs_set_root_flags(root_item, 0); |
522 | btrfs_set_root_limit(&root_item, 0); | 526 | btrfs_set_root_limit(root_item, 0); |
523 | btrfs_set_stack_inode_flags(inode_item, BTRFS_INODE_ROOT_ITEM_INIT); | 527 | btrfs_set_stack_inode_flags(inode_item, BTRFS_INODE_ROOT_ITEM_INIT); |
524 | 528 | ||
525 | btrfs_set_root_bytenr(&root_item, leaf->start); | 529 | btrfs_set_root_bytenr(root_item, leaf->start); |
526 | btrfs_set_root_generation(&root_item, trans->transid); | 530 | btrfs_set_root_generation(root_item, trans->transid); |
527 | btrfs_set_root_level(&root_item, 0); | 531 | btrfs_set_root_level(root_item, 0); |
528 | btrfs_set_root_refs(&root_item, 1); | 532 | btrfs_set_root_refs(root_item, 1); |
529 | btrfs_set_root_used(&root_item, leaf->len); | 533 | btrfs_set_root_used(root_item, leaf->len); |
530 | btrfs_set_root_last_snapshot(&root_item, 0); | 534 | btrfs_set_root_last_snapshot(root_item, 0); |
531 | 535 | ||
532 | btrfs_set_root_generation_v2(&root_item, | 536 | btrfs_set_root_generation_v2(root_item, |
533 | btrfs_root_generation(&root_item)); | 537 | btrfs_root_generation(root_item)); |
534 | uuid_le_gen(&new_uuid); | 538 | uuid_le_gen(&new_uuid); |
535 | memcpy(root_item.uuid, new_uuid.b, BTRFS_UUID_SIZE); | 539 | memcpy(root_item->uuid, new_uuid.b, BTRFS_UUID_SIZE); |
536 | btrfs_set_stack_timespec_sec(&root_item.otime, cur_time.tv_sec); | 540 | btrfs_set_stack_timespec_sec(&root_item->otime, cur_time.tv_sec); |
537 | btrfs_set_stack_timespec_nsec(&root_item.otime, cur_time.tv_nsec); | 541 | btrfs_set_stack_timespec_nsec(&root_item->otime, cur_time.tv_nsec); |
538 | root_item.ctime = root_item.otime; | 542 | root_item->ctime = root_item->otime; |
539 | btrfs_set_root_ctransid(&root_item, trans->transid); | 543 | btrfs_set_root_ctransid(root_item, trans->transid); |
540 | btrfs_set_root_otransid(&root_item, trans->transid); | 544 | btrfs_set_root_otransid(root_item, trans->transid); |
541 | 545 | ||
542 | btrfs_tree_unlock(leaf); | 546 | btrfs_tree_unlock(leaf); |
543 | free_extent_buffer(leaf); | 547 | free_extent_buffer(leaf); |
544 | leaf = NULL; | 548 | leaf = NULL; |
545 | 549 | ||
546 | btrfs_set_root_dirid(&root_item, new_dirid); | 550 | btrfs_set_root_dirid(root_item, new_dirid); |
547 | 551 | ||
548 | key.objectid = objectid; | 552 | key.objectid = objectid; |
549 | key.offset = 0; | 553 | key.offset = 0; |
550 | key.type = BTRFS_ROOT_ITEM_KEY; | 554 | key.type = BTRFS_ROOT_ITEM_KEY; |
551 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, | 555 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, |
552 | &root_item); | 556 | root_item); |
553 | if (ret) | 557 | if (ret) |
554 | goto fail; | 558 | goto fail; |
555 | 559 | ||
@@ -601,12 +605,13 @@ static noinline int create_subvol(struct inode *dir, | |||
601 | BUG_ON(ret); | 605 | BUG_ON(ret); |
602 | 606 | ||
603 | ret = btrfs_uuid_tree_add(trans, root->fs_info->uuid_root, | 607 | ret = btrfs_uuid_tree_add(trans, root->fs_info->uuid_root, |
604 | root_item.uuid, BTRFS_UUID_KEY_SUBVOL, | 608 | root_item->uuid, BTRFS_UUID_KEY_SUBVOL, |
605 | objectid); | 609 | objectid); |
606 | if (ret) | 610 | if (ret) |
607 | btrfs_abort_transaction(trans, root, ret); | 611 | btrfs_abort_transaction(trans, root, ret); |
608 | 612 | ||
609 | fail: | 613 | fail: |
614 | kfree(root_item); | ||
610 | trans->block_rsv = NULL; | 615 | trans->block_rsv = NULL; |
611 | trans->bytes_reserved = 0; | 616 | trans->bytes_reserved = 0; |
612 | btrfs_subvolume_release_metadata(root, &block_rsv, qgroup_reserved); | 617 | btrfs_subvolume_release_metadata(root, &block_rsv, qgroup_reserved); |
@@ -629,6 +634,10 @@ fail: | |||
629 | d_instantiate(dentry, inode); | 634 | d_instantiate(dentry, inode); |
630 | } | 635 | } |
631 | return ret; | 636 | return ret; |
637 | |||
638 | fail_free: | ||
639 | kfree(root_item); | ||
640 | return ret; | ||
632 | } | 641 | } |
633 | 642 | ||
634 | static void btrfs_wait_for_no_snapshoting_writes(struct btrfs_root *root) | 643 | static void btrfs_wait_for_no_snapshoting_writes(struct btrfs_root *root) |
@@ -681,7 +690,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, | |||
681 | if (ret) | 690 | if (ret) |
682 | goto dec_and_free; | 691 | goto dec_and_free; |
683 | 692 | ||
684 | btrfs_wait_ordered_extents(root, -1); | 693 | btrfs_wait_ordered_extents(root, -1, 0, (u64)-1); |
685 | 694 | ||
686 | btrfs_init_block_rsv(&pending_snapshot->block_rsv, | 695 | btrfs_init_block_rsv(&pending_snapshot->block_rsv, |
687 | BTRFS_BLOCK_RSV_TEMP); | 696 | BTRFS_BLOCK_RSV_TEMP); |
@@ -2671,10 +2680,10 @@ out: | |||
2671 | return ret; | 2680 | return ret; |
2672 | } | 2681 | } |
2673 | 2682 | ||
2674 | static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg) | 2683 | static long btrfs_ioctl_rm_dev_v2(struct file *file, void __user *arg) |
2675 | { | 2684 | { |
2676 | struct btrfs_root *root = BTRFS_I(file_inode(file))->root; | 2685 | struct btrfs_root *root = BTRFS_I(file_inode(file))->root; |
2677 | struct btrfs_ioctl_vol_args *vol_args; | 2686 | struct btrfs_ioctl_vol_args_v2 *vol_args; |
2678 | int ret; | 2687 | int ret; |
2679 | 2688 | ||
2680 | if (!capable(CAP_SYS_ADMIN)) | 2689 | if (!capable(CAP_SYS_ADMIN)) |
@@ -2690,7 +2699,9 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg) | |||
2690 | goto err_drop; | 2699 | goto err_drop; |
2691 | } | 2700 | } |
2692 | 2701 | ||
2693 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; | 2702 | /* Check for compatibility reject unknown flags */ |
2703 | if (vol_args->flags & ~BTRFS_VOL_ARG_V2_FLAGS_SUPPORTED) | ||
2704 | return -EOPNOTSUPP; | ||
2694 | 2705 | ||
2695 | if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running, | 2706 | if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running, |
2696 | 1)) { | 2707 | 1)) { |
@@ -2699,13 +2710,23 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg) | |||
2699 | } | 2710 | } |
2700 | 2711 | ||
2701 | mutex_lock(&root->fs_info->volume_mutex); | 2712 | mutex_lock(&root->fs_info->volume_mutex); |
2702 | ret = btrfs_rm_device(root, vol_args->name); | 2713 | if (vol_args->flags & BTRFS_DEVICE_SPEC_BY_ID) { |
2714 | ret = btrfs_rm_device(root, NULL, vol_args->devid); | ||
2715 | } else { | ||
2716 | vol_args->name[BTRFS_SUBVOL_NAME_MAX] = '\0'; | ||
2717 | ret = btrfs_rm_device(root, vol_args->name, 0); | ||
2718 | } | ||
2703 | mutex_unlock(&root->fs_info->volume_mutex); | 2719 | mutex_unlock(&root->fs_info->volume_mutex); |
2704 | atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0); | 2720 | atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0); |
2705 | 2721 | ||
2706 | if (!ret) | 2722 | if (!ret) { |
2707 | btrfs_info(root->fs_info, "disk deleted %s",vol_args->name); | 2723 | if (vol_args->flags & BTRFS_DEVICE_SPEC_BY_ID) |
2708 | 2724 | btrfs_info(root->fs_info, "device deleted: id %llu", | |
2725 | vol_args->devid); | ||
2726 | else | ||
2727 | btrfs_info(root->fs_info, "device deleted: %s", | ||
2728 | vol_args->name); | ||
2729 | } | ||
2709 | out: | 2730 | out: |
2710 | kfree(vol_args); | 2731 | kfree(vol_args); |
2711 | err_drop: | 2732 | err_drop: |
@@ -2713,6 +2734,47 @@ err_drop: | |||
2713 | return ret; | 2734 | return ret; |
2714 | } | 2735 | } |
2715 | 2736 | ||
2737 | static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg) | ||
2738 | { | ||
2739 | struct btrfs_root *root = BTRFS_I(file_inode(file))->root; | ||
2740 | struct btrfs_ioctl_vol_args *vol_args; | ||
2741 | int ret; | ||
2742 | |||
2743 | if (!capable(CAP_SYS_ADMIN)) | ||
2744 | return -EPERM; | ||
2745 | |||
2746 | ret = mnt_want_write_file(file); | ||
2747 | if (ret) | ||
2748 | return ret; | ||
2749 | |||
2750 | if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running, | ||
2751 | 1)) { | ||
2752 | ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS; | ||
2753 | goto out_drop_write; | ||
2754 | } | ||
2755 | |||
2756 | vol_args = memdup_user(arg, sizeof(*vol_args)); | ||
2757 | if (IS_ERR(vol_args)) { | ||
2758 | ret = PTR_ERR(vol_args); | ||
2759 | goto out; | ||
2760 | } | ||
2761 | |||
2762 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; | ||
2763 | mutex_lock(&root->fs_info->volume_mutex); | ||
2764 | ret = btrfs_rm_device(root, vol_args->name, 0); | ||
2765 | mutex_unlock(&root->fs_info->volume_mutex); | ||
2766 | |||
2767 | if (!ret) | ||
2768 | btrfs_info(root->fs_info, "disk deleted %s",vol_args->name); | ||
2769 | kfree(vol_args); | ||
2770 | out: | ||
2771 | atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0); | ||
2772 | out_drop_write: | ||
2773 | mnt_drop_write_file(file); | ||
2774 | |||
2775 | return ret; | ||
2776 | } | ||
2777 | |||
2716 | static long btrfs_ioctl_fs_info(struct btrfs_root *root, void __user *arg) | 2778 | static long btrfs_ioctl_fs_info(struct btrfs_root *root, void __user *arg) |
2717 | { | 2779 | { |
2718 | struct btrfs_ioctl_fs_info_args *fi_args; | 2780 | struct btrfs_ioctl_fs_info_args *fi_args; |
@@ -3472,13 +3534,16 @@ static int btrfs_clone(struct inode *src, struct inode *inode, | |||
3472 | u64 last_dest_end = destoff; | 3534 | u64 last_dest_end = destoff; |
3473 | 3535 | ||
3474 | ret = -ENOMEM; | 3536 | ret = -ENOMEM; |
3475 | buf = vmalloc(root->nodesize); | 3537 | buf = kmalloc(root->nodesize, GFP_KERNEL | __GFP_NOWARN); |
3476 | if (!buf) | 3538 | if (!buf) { |
3477 | return ret; | 3539 | buf = vmalloc(root->nodesize); |
3540 | if (!buf) | ||
3541 | return ret; | ||
3542 | } | ||
3478 | 3543 | ||
3479 | path = btrfs_alloc_path(); | 3544 | path = btrfs_alloc_path(); |
3480 | if (!path) { | 3545 | if (!path) { |
3481 | vfree(buf); | 3546 | kvfree(buf); |
3482 | return ret; | 3547 | return ret; |
3483 | } | 3548 | } |
3484 | 3549 | ||
@@ -3779,7 +3844,7 @@ process_slot: | |||
3779 | 3844 | ||
3780 | out: | 3845 | out: |
3781 | btrfs_free_path(path); | 3846 | btrfs_free_path(path); |
3782 | vfree(buf); | 3847 | kvfree(buf); |
3783 | return ret; | 3848 | return ret; |
3784 | } | 3849 | } |
3785 | 3850 | ||
@@ -4380,7 +4445,7 @@ static long btrfs_ioctl_dev_replace(struct btrfs_root *root, void __user *arg) | |||
4380 | 1)) { | 4445 | 1)) { |
4381 | ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS; | 4446 | ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS; |
4382 | } else { | 4447 | } else { |
4383 | ret = btrfs_dev_replace_start(root, p); | 4448 | ret = btrfs_dev_replace_by_ioctl(root, p); |
4384 | atomic_set( | 4449 | atomic_set( |
4385 | &root->fs_info->mutually_exclusive_operation_running, | 4450 | &root->fs_info->mutually_exclusive_operation_running, |
4386 | 0); | 4451 | 0); |
@@ -4851,8 +4916,8 @@ static long btrfs_ioctl_qgroup_assign(struct file *file, void __user *arg) | |||
4851 | /* update qgroup status and info */ | 4916 | /* update qgroup status and info */ |
4852 | err = btrfs_run_qgroups(trans, root->fs_info); | 4917 | err = btrfs_run_qgroups(trans, root->fs_info); |
4853 | if (err < 0) | 4918 | if (err < 0) |
4854 | btrfs_std_error(root->fs_info, ret, | 4919 | btrfs_handle_fs_error(root->fs_info, err, |
4855 | "failed to update qgroup status and info\n"); | 4920 | "failed to update qgroup status and info"); |
4856 | err = btrfs_end_transaction(trans, root); | 4921 | err = btrfs_end_transaction(trans, root); |
4857 | if (err && !ret) | 4922 | if (err && !ret) |
4858 | ret = err; | 4923 | ret = err; |
@@ -5398,9 +5463,15 @@ static int btrfs_ioctl_set_features(struct file *file, void __user *arg) | |||
5398 | if (ret) | 5463 | if (ret) |
5399 | return ret; | 5464 | return ret; |
5400 | 5465 | ||
5466 | ret = mnt_want_write_file(file); | ||
5467 | if (ret) | ||
5468 | return ret; | ||
5469 | |||
5401 | trans = btrfs_start_transaction(root, 0); | 5470 | trans = btrfs_start_transaction(root, 0); |
5402 | if (IS_ERR(trans)) | 5471 | if (IS_ERR(trans)) { |
5403 | return PTR_ERR(trans); | 5472 | ret = PTR_ERR(trans); |
5473 | goto out_drop_write; | ||
5474 | } | ||
5404 | 5475 | ||
5405 | spin_lock(&root->fs_info->super_lock); | 5476 | spin_lock(&root->fs_info->super_lock); |
5406 | newflags = btrfs_super_compat_flags(super_block); | 5477 | newflags = btrfs_super_compat_flags(super_block); |
@@ -5419,7 +5490,11 @@ static int btrfs_ioctl_set_features(struct file *file, void __user *arg) | |||
5419 | btrfs_set_super_incompat_flags(super_block, newflags); | 5490 | btrfs_set_super_incompat_flags(super_block, newflags); |
5420 | spin_unlock(&root->fs_info->super_lock); | 5491 | spin_unlock(&root->fs_info->super_lock); |
5421 | 5492 | ||
5422 | return btrfs_commit_transaction(trans, root); | 5493 | ret = btrfs_commit_transaction(trans, root); |
5494 | out_drop_write: | ||
5495 | mnt_drop_write_file(file); | ||
5496 | |||
5497 | return ret; | ||
5423 | } | 5498 | } |
5424 | 5499 | ||
5425 | long btrfs_ioctl(struct file *file, unsigned int | 5500 | long btrfs_ioctl(struct file *file, unsigned int |
@@ -5463,6 +5538,8 @@ long btrfs_ioctl(struct file *file, unsigned int | |||
5463 | return btrfs_ioctl_add_dev(root, argp); | 5538 | return btrfs_ioctl_add_dev(root, argp); |
5464 | case BTRFS_IOC_RM_DEV: | 5539 | case BTRFS_IOC_RM_DEV: |
5465 | return btrfs_ioctl_rm_dev(file, argp); | 5540 | return btrfs_ioctl_rm_dev(file, argp); |
5541 | case BTRFS_IOC_RM_DEV_V2: | ||
5542 | return btrfs_ioctl_rm_dev_v2(file, argp); | ||
5466 | case BTRFS_IOC_FS_INFO: | 5543 | case BTRFS_IOC_FS_INFO: |
5467 | return btrfs_ioctl_fs_info(root, argp); | 5544 | return btrfs_ioctl_fs_info(root, argp); |
5468 | case BTRFS_IOC_DEV_INFO: | 5545 | case BTRFS_IOC_DEV_INFO: |
@@ -5556,3 +5633,24 @@ long btrfs_ioctl(struct file *file, unsigned int | |||
5556 | 5633 | ||
5557 | return -ENOTTY; | 5634 | return -ENOTTY; |
5558 | } | 5635 | } |
5636 | |||
5637 | #ifdef CONFIG_COMPAT | ||
5638 | long btrfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
5639 | { | ||
5640 | switch (cmd) { | ||
5641 | case FS_IOC32_GETFLAGS: | ||
5642 | cmd = FS_IOC_GETFLAGS; | ||
5643 | break; | ||
5644 | case FS_IOC32_SETFLAGS: | ||
5645 | cmd = FS_IOC_SETFLAGS; | ||
5646 | break; | ||
5647 | case FS_IOC32_GETVERSION: | ||
5648 | cmd = FS_IOC_GETVERSION; | ||
5649 | break; | ||
5650 | default: | ||
5651 | return -ENOIOCTLCMD; | ||
5652 | } | ||
5653 | |||
5654 | return btrfs_ioctl(file, cmd, (unsigned long) compat_ptr(arg)); | ||
5655 | } | ||
5656 | #endif | ||