ioctl.c (ee5db7e47faccd07a8a17f73afb30345f8331e61) ioctl.c (5542aa2fa7f6cddb03c4ac3135e390adffda98ca)
1/*
2 * Copyright (C) 2007 Oracle. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License v2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,

--- 1005 unchanged lines hidden (view full) ---

1014 struct extent_map *next;
1015 bool ret = true;
1016
1017 /* this is the last extent */
1018 if (em->start + em->len >= i_size_read(inode))
1019 return false;
1020
1021 next = defrag_lookup_extent(inode, em->start + em->len);
1/*
2 * Copyright (C) 2007 Oracle. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License v2 as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,

--- 1005 unchanged lines hidden (view full) ---

1014 struct extent_map *next;
1015 bool ret = true;
1016
1017 /* this is the last extent */
1018 if (em->start + em->len >= i_size_read(inode))
1019 return false;
1020
1021 next = defrag_lookup_extent(inode, em->start + em->len);
1022 if (!next || next->block_start >= EXTENT_MAP_LAST_BYTE ||
1023 (em->block_start + em->block_len == next->block_start))
1022 if (!next || next->block_start >= EXTENT_MAP_LAST_BYTE)
1024 ret = false;
1023 ret = false;
1024 else if ((em->block_start + em->block_len == next->block_start) &&
1025 (em->block_len > 128 * 1024 && next->block_len > 128 * 1024))
1026 ret = false;
1025
1026 free_extent_map(next);
1027 return ret;
1028}
1029
1030static int should_defrag_range(struct inode *inode, u64 start, int thresh,
1031 u64 *last_len, u64 *skip, u64 *defrag_end,
1032 int compress)

--- 17 unchanged lines hidden (view full) ---

1050
1051 /* this will cover holes, and inline extents */
1052 if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
1053 ret = 0;
1054 goto out;
1055 }
1056
1057 next_mergeable = defrag_check_next_extent(inode, em);
1027
1028 free_extent_map(next);
1029 return ret;
1030}
1031
1032static int should_defrag_range(struct inode *inode, u64 start, int thresh,
1033 u64 *last_len, u64 *skip, u64 *defrag_end,
1034 int compress)

--- 17 unchanged lines hidden (view full) ---

1052
1053 /* this will cover holes, and inline extents */
1054 if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
1055 ret = 0;
1056 goto out;
1057 }
1058
1059 next_mergeable = defrag_check_next_extent(inode, em);
1058
1059 /*
1060 * we hit a real extent, if it is big or the next extent is not a
1061 * real extent, don't bother defragging it
1062 */
1063 if (!compress && (*last_len == 0 || *last_len >= thresh) &&
1064 (em->len >= thresh || !next_mergeable))
1065 ret = 0;
1066out:

--- 630 unchanged lines hidden (view full) ---

1697 if (IS_ERR(vol_args))
1698 return PTR_ERR(vol_args);
1699 vol_args->name[BTRFS_SUBVOL_NAME_MAX] = '\0';
1700
1701 if (vol_args->flags &
1702 ~(BTRFS_SUBVOL_CREATE_ASYNC | BTRFS_SUBVOL_RDONLY |
1703 BTRFS_SUBVOL_QGROUP_INHERIT)) {
1704 ret = -EOPNOTSUPP;
1060 /*
1061 * we hit a real extent, if it is big or the next extent is not a
1062 * real extent, don't bother defragging it
1063 */
1064 if (!compress && (*last_len == 0 || *last_len >= thresh) &&
1065 (em->len >= thresh || !next_mergeable))
1066 ret = 0;
1067out:

--- 630 unchanged lines hidden (view full) ---

1698 if (IS_ERR(vol_args))
1699 return PTR_ERR(vol_args);
1700 vol_args->name[BTRFS_SUBVOL_NAME_MAX] = '\0';
1701
1702 if (vol_args->flags &
1703 ~(BTRFS_SUBVOL_CREATE_ASYNC | BTRFS_SUBVOL_RDONLY |
1704 BTRFS_SUBVOL_QGROUP_INHERIT)) {
1705 ret = -EOPNOTSUPP;
1705 goto out;
1706 goto free_args;
1706 }
1707
1708 if (vol_args->flags & BTRFS_SUBVOL_CREATE_ASYNC)
1709 ptr = &transid;
1710 if (vol_args->flags & BTRFS_SUBVOL_RDONLY)
1711 readonly = true;
1712 if (vol_args->flags & BTRFS_SUBVOL_QGROUP_INHERIT) {
1713 if (vol_args->size > PAGE_CACHE_SIZE) {
1714 ret = -EINVAL;
1707 }
1708
1709 if (vol_args->flags & BTRFS_SUBVOL_CREATE_ASYNC)
1710 ptr = &transid;
1711 if (vol_args->flags & BTRFS_SUBVOL_RDONLY)
1712 readonly = true;
1713 if (vol_args->flags & BTRFS_SUBVOL_QGROUP_INHERIT) {
1714 if (vol_args->size > PAGE_CACHE_SIZE) {
1715 ret = -EINVAL;
1715 goto out;
1716 goto free_args;
1716 }
1717 inherit = memdup_user(vol_args->qgroup_inherit, vol_args->size);
1718 if (IS_ERR(inherit)) {
1719 ret = PTR_ERR(inherit);
1717 }
1718 inherit = memdup_user(vol_args->qgroup_inherit, vol_args->size);
1719 if (IS_ERR(inherit)) {
1720 ret = PTR_ERR(inherit);
1720 goto out;
1721 goto free_args;
1721 }
1722 }
1723
1724 ret = btrfs_ioctl_snap_create_transid(file, vol_args->name,
1725 vol_args->fd, subvol, ptr,
1726 readonly, inherit);
1722 }
1723 }
1724
1725 ret = btrfs_ioctl_snap_create_transid(file, vol_args->name,
1726 vol_args->fd, subvol, ptr,
1727 readonly, inherit);
1728 if (ret)
1729 goto free_inherit;
1727
1730
1728 if (ret == 0 && ptr &&
1729 copy_to_user(arg +
1730 offsetof(struct btrfs_ioctl_vol_args_v2,
1731 transid), ptr, sizeof(*ptr)))
1731 if (ptr && copy_to_user(arg +
1732 offsetof(struct btrfs_ioctl_vol_args_v2,
1733 transid),
1734 ptr, sizeof(*ptr)))
1732 ret = -EFAULT;
1735 ret = -EFAULT;
1733out:
1734 kfree(vol_args);
1736
1737free_inherit:
1735 kfree(inherit);
1738 kfree(inherit);
1739free_args:
1740 kfree(vol_args);
1736 return ret;
1737}
1738
1739static noinline int btrfs_ioctl_subvol_getflags(struct file *file,
1740 void __user *arg)
1741{
1742 struct inode *inode = file_inode(file);
1743 struct btrfs_root *root = BTRFS_I(inode)->root;

--- 669 unchanged lines hidden (view full) ---

2413 spin_unlock(&dest->root_item_lock);
2414 btrfs_warn(root->fs_info,
2415 "Attempt to delete subvolume %llu during send",
2416 dest->root_key.objectid);
2417 err = -EPERM;
2418 goto out_dput;
2419 }
2420
1741 return ret;
1742}
1743
1744static noinline int btrfs_ioctl_subvol_getflags(struct file *file,
1745 void __user *arg)
1746{
1747 struct inode *inode = file_inode(file);
1748 struct btrfs_root *root = BTRFS_I(inode)->root;

--- 669 unchanged lines hidden (view full) ---

2418 spin_unlock(&dest->root_item_lock);
2419 btrfs_warn(root->fs_info,
2420 "Attempt to delete subvolume %llu during send",
2421 dest->root_key.objectid);
2422 err = -EPERM;
2423 goto out_dput;
2424 }
2425
2421 err = d_invalidate(dentry);
2422 if (err)
2423 goto out_unlock;
2426 d_invalidate(dentry);
2424
2425 down_write(&root->fs_info->subvol_sem);
2426
2427 err = may_destroy_subvol(dest);
2428 if (err)
2429 goto out_up_write;
2430
2431 btrfs_init_block_rsv(&block_rsv, BTRFS_BLOCK_RSV_TEMP);

--- 68 unchanged lines hidden (view full) ---

2500 ret = btrfs_end_transaction(trans, root);
2501 if (ret && !err)
2502 err = ret;
2503 inode->i_flags |= S_DEAD;
2504out_release:
2505 btrfs_subvolume_release_metadata(root, &block_rsv, qgroup_reserved);
2506out_up_write:
2507 up_write(&root->fs_info->subvol_sem);
2427
2428 down_write(&root->fs_info->subvol_sem);
2429
2430 err = may_destroy_subvol(dest);
2431 if (err)
2432 goto out_up_write;
2433
2434 btrfs_init_block_rsv(&block_rsv, BTRFS_BLOCK_RSV_TEMP);

--- 68 unchanged lines hidden (view full) ---

2503 ret = btrfs_end_transaction(trans, root);
2504 if (ret && !err)
2505 err = ret;
2506 inode->i_flags |= S_DEAD;
2507out_release:
2508 btrfs_subvolume_release_metadata(root, &block_rsv, qgroup_reserved);
2509out_up_write:
2510 up_write(&root->fs_info->subvol_sem);
2508out_unlock:
2509 if (err) {
2510 spin_lock(&dest->root_item_lock);
2511 root_flags = btrfs_root_flags(&dest->root_item);
2512 btrfs_set_root_flags(&dest->root_item,
2513 root_flags & ~BTRFS_ROOT_SUBVOL_DEAD);
2514 spin_unlock(&dest->root_item_lock);
2515 }
2516 mutex_unlock(&inode->i_mutex);

--- 130 unchanged lines hidden (view full) ---

2647
2648 ret = mnt_want_write_file(file);
2649 if (ret)
2650 return ret;
2651
2652 vol_args = memdup_user(arg, sizeof(*vol_args));
2653 if (IS_ERR(vol_args)) {
2654 ret = PTR_ERR(vol_args);
2511 if (err) {
2512 spin_lock(&dest->root_item_lock);
2513 root_flags = btrfs_root_flags(&dest->root_item);
2514 btrfs_set_root_flags(&dest->root_item,
2515 root_flags & ~BTRFS_ROOT_SUBVOL_DEAD);
2516 spin_unlock(&dest->root_item_lock);
2517 }
2518 mutex_unlock(&inode->i_mutex);

--- 130 unchanged lines hidden (view full) ---

2649
2650 ret = mnt_want_write_file(file);
2651 if (ret)
2652 return ret;
2653
2654 vol_args = memdup_user(arg, sizeof(*vol_args));
2655 if (IS_ERR(vol_args)) {
2656 ret = PTR_ERR(vol_args);
2655 goto out;
2657 goto err_drop;
2656 }
2657
2658 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
2659
2660 if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running,
2661 1)) {
2662 ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS;
2663 goto out;
2664 }
2665
2666 mutex_lock(&root->fs_info->volume_mutex);
2667 ret = btrfs_rm_device(root, vol_args->name);
2668 mutex_unlock(&root->fs_info->volume_mutex);
2669 atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0);
2670
2671out:
2672 kfree(vol_args);
2658 }
2659
2660 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
2661
2662 if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running,
2663 1)) {
2664 ret = BTRFS_ERROR_DEV_EXCL_RUN_IN_PROGRESS;
2665 goto out;
2666 }
2667
2668 mutex_lock(&root->fs_info->volume_mutex);
2669 ret = btrfs_rm_device(root, vol_args->name);
2670 mutex_unlock(&root->fs_info->volume_mutex);
2671 atomic_set(&root->fs_info->mutually_exclusive_operation_running, 0);
2672
2673out:
2674 kfree(vol_args);
2675err_drop:
2673 mnt_drop_write_file(file);
2674 return ret;
2675}
2676
2677static long btrfs_ioctl_fs_info(struct btrfs_root *root, void __user *arg)
2678{
2679 struct btrfs_ioctl_fs_info_args *fi_args;
2680 struct btrfs_device *device;

--- 2659 unchanged lines hidden ---
2676 mnt_drop_write_file(file);
2677 return ret;
2678}
2679
2680static long btrfs_ioctl_fs_info(struct btrfs_root *root, void __user *arg)
2681{
2682 struct btrfs_ioctl_fs_info_args *fi_args;
2683 struct btrfs_device *device;

--- 2659 unchanged lines hidden ---