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.c68
1 files changed, 21 insertions, 47 deletions
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 47aceb494d1d..8a8e29878c34 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -711,39 +711,6 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir,
711 if (ret) 711 if (ret)
712 goto fail; 712 goto fail;
713 713
714 ret = btrfs_orphan_cleanup(pending_snapshot->snap);
715 if (ret)
716 goto fail;
717
718 /*
719 * If orphan cleanup did remove any orphans, it means the tree was
720 * modified and therefore the commit root is not the same as the
721 * current root anymore. This is a problem, because send uses the
722 * commit root and therefore can see inode items that don't exist
723 * in the current root anymore, and for example make calls to
724 * btrfs_iget, which will do tree lookups based on the current root
725 * and not on the commit root. Those lookups will fail, returning a
726 * -ESTALE error, and making send fail with that error. So make sure
727 * a send does not see any orphans we have just removed, and that it
728 * will see the same inodes regardless of whether a transaction
729 * commit happened before it started (meaning that the commit root
730 * will be the same as the current root) or not.
731 */
732 if (readonly && pending_snapshot->snap->node !=
733 pending_snapshot->snap->commit_root) {
734 trans = btrfs_join_transaction(pending_snapshot->snap);
735 if (IS_ERR(trans) && PTR_ERR(trans) != -ENOENT) {
736 ret = PTR_ERR(trans);
737 goto fail;
738 }
739 if (!IS_ERR(trans)) {
740 ret = btrfs_commit_transaction(trans,
741 pending_snapshot->snap);
742 if (ret)
743 goto fail;
744 }
745 }
746
747 inode = btrfs_lookup_dentry(dentry->d_parent->d_inode, dentry); 714 inode = btrfs_lookup_dentry(dentry->d_parent->d_inode, dentry);
748 if (IS_ERR(inode)) { 715 if (IS_ERR(inode)) {
749 ret = PTR_ERR(inode); 716 ret = PTR_ERR(inode);
@@ -1052,8 +1019,10 @@ static bool defrag_check_next_extent(struct inode *inode, struct extent_map *em)
1052 return false; 1019 return false;
1053 1020
1054 next = defrag_lookup_extent(inode, em->start + em->len); 1021 next = defrag_lookup_extent(inode, em->start + em->len);
1055 if (!next || next->block_start >= EXTENT_MAP_LAST_BYTE || 1022 if (!next || next->block_start >= EXTENT_MAP_LAST_BYTE)
1056 (em->block_start + em->block_len == next->block_start)) 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))
1057 ret = false; 1026 ret = false;
1058 1027
1059 free_extent_map(next); 1028 free_extent_map(next);
@@ -1088,7 +1057,6 @@ static int should_defrag_range(struct inode *inode, u64 start, int thresh,
1088 } 1057 }
1089 1058
1090 next_mergeable = defrag_check_next_extent(inode, em); 1059 next_mergeable = defrag_check_next_extent(inode, em);
1091
1092 /* 1060 /*
1093 * we hit a real extent, if it is big or the next extent is not a 1061 * we hit a real extent, if it is big or the next extent is not a
1094 * real extent, don't bother defragging it 1062 * real extent, don't bother defragging it
@@ -1735,7 +1703,7 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file,
1735 ~(BTRFS_SUBVOL_CREATE_ASYNC | BTRFS_SUBVOL_RDONLY | 1703 ~(BTRFS_SUBVOL_CREATE_ASYNC | BTRFS_SUBVOL_RDONLY |
1736 BTRFS_SUBVOL_QGROUP_INHERIT)) { 1704 BTRFS_SUBVOL_QGROUP_INHERIT)) {
1737 ret = -EOPNOTSUPP; 1705 ret = -EOPNOTSUPP;
1738 goto out; 1706 goto free_args;
1739 } 1707 }
1740 1708
1741 if (vol_args->flags & BTRFS_SUBVOL_CREATE_ASYNC) 1709 if (vol_args->flags & BTRFS_SUBVOL_CREATE_ASYNC)
@@ -1745,27 +1713,31 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file,
1745 if (vol_args->flags & BTRFS_SUBVOL_QGROUP_INHERIT) { 1713 if (vol_args->flags & BTRFS_SUBVOL_QGROUP_INHERIT) {
1746 if (vol_args->size > PAGE_CACHE_SIZE) { 1714 if (vol_args->size > PAGE_CACHE_SIZE) {
1747 ret = -EINVAL; 1715 ret = -EINVAL;
1748 goto out; 1716 goto free_args;
1749 } 1717 }
1750 inherit = memdup_user(vol_args->qgroup_inherit, vol_args->size); 1718 inherit = memdup_user(vol_args->qgroup_inherit, vol_args->size);
1751 if (IS_ERR(inherit)) { 1719 if (IS_ERR(inherit)) {
1752 ret = PTR_ERR(inherit); 1720 ret = PTR_ERR(inherit);
1753 goto out; 1721 goto free_args;
1754 } 1722 }
1755 } 1723 }
1756 1724
1757 ret = btrfs_ioctl_snap_create_transid(file, vol_args->name, 1725 ret = btrfs_ioctl_snap_create_transid(file, vol_args->name,
1758 vol_args->fd, subvol, ptr, 1726 vol_args->fd, subvol, ptr,
1759 readonly, inherit); 1727 readonly, inherit);
1728 if (ret)
1729 goto free_inherit;
1760 1730
1761 if (ret == 0 && ptr && 1731 if (ptr && copy_to_user(arg +
1762 copy_to_user(arg + 1732 offsetof(struct btrfs_ioctl_vol_args_v2,
1763 offsetof(struct btrfs_ioctl_vol_args_v2, 1733 transid),
1764 transid), ptr, sizeof(*ptr))) 1734 ptr, sizeof(*ptr)))
1765 ret = -EFAULT; 1735 ret = -EFAULT;
1766out: 1736
1767 kfree(vol_args); 1737free_inherit:
1768 kfree(inherit); 1738 kfree(inherit);
1739free_args:
1740 kfree(vol_args);
1769 return ret; 1741 return ret;
1770} 1742}
1771 1743
@@ -2685,7 +2657,7 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg)
2685 vol_args = memdup_user(arg, sizeof(*vol_args)); 2657 vol_args = memdup_user(arg, sizeof(*vol_args));
2686 if (IS_ERR(vol_args)) { 2658 if (IS_ERR(vol_args)) {
2687 ret = PTR_ERR(vol_args); 2659 ret = PTR_ERR(vol_args);
2688 goto out; 2660 goto err_drop;
2689 } 2661 }
2690 2662
2691 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; 2663 vol_args->name[BTRFS_PATH_NAME_MAX] = '\0';
@@ -2703,6 +2675,7 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg)
2703 2675
2704out: 2676out:
2705 kfree(vol_args); 2677 kfree(vol_args);
2678err_drop:
2706 mnt_drop_write_file(file); 2679 mnt_drop_write_file(file);
2707 return ret; 2680 return ret;
2708} 2681}
@@ -3527,7 +3500,8 @@ process_slot:
3527 btrfs_mark_buffer_dirty(leaf); 3500 btrfs_mark_buffer_dirty(leaf);
3528 btrfs_release_path(path); 3501 btrfs_release_path(path);
3529 3502
3530 last_dest_end = new_key.offset + datal; 3503 last_dest_end = ALIGN(new_key.offset + datal,
3504 root->sectorsize);
3531 ret = clone_finish_inode_update(trans, inode, 3505 ret = clone_finish_inode_update(trans, inode,
3532 last_dest_end, 3506 last_dest_end,
3533 destoff, olen); 3507 destoff, olen);