aboutsummarylogtreecommitdiffstats
path: root/fs-allow-cross-vfsmount-reflink-dedupe.patch
blob: d737180dafe2d5b477c202e5bda1ba117eb61c96 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
From 4caa9af06265aef40239847d14b2182f5dd35a44 Mon Sep 17 00:00:00 2001
From: Scott B <arglebargle@arglebargle.dev>
Date: Fri, 18 Feb 2022 16:15:23 -0800
Subject: [PATCH] fs: allow cross-vfsmount reflink/dedupe

Squashed commit of the following:

commit d053c48ab87a8668d5eb27765b9ff10573053091
Author: Josef Bacik <josef@toxicpanda.com>
Date:   Fri Feb 18 09:38:14 2022 -0500

    fs: allow cross-vfsmount reflink/dedupe

    Currently we disallow reflink and dedupe if the two files aren't on the
    same vfsmount.  However we really only need to disallow it if they're
    not on the same super block.  It is very common for btrfs to have a main
    subvolume that is mounted and then different subvolumes mounted at
    different locations.  It's allowed to reflink between these volumes, but
    the vfsmount check disallows this.  Instead fix dedupe to check for the
    same superblock, and simply remove the vfsmount check for reflink as it
    already does the superblock check.

    Reviewed-by: Darrick J. Wong <djwong@kernel.org>
    Reviewed-by: Nikolay Borisov <nborisov@suse.com>
    Reviewed-by: David Sterba <dsterba@suse.com>
    Signed-off-by: Josef Bacik <josef@toxicpanda.com>

commit 8d92b5b06130d1557e200dd64bb901f94ff661ea
Author: Josef Bacik <josef@toxicpanda.com>
Date:   Fri Feb 18 09:38:13 2022 -0500

    btrfs: remove the cross file system checks from remap

    The sb check is already done in do_clone_file_range, and the mnt check
    (which will hopefully go away in a subsequent patch) is done in
    ioctl_file_clone().  Remove the check in our code and put an ASSERT() to
    make sure it doesn't change underneath us.

    Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/reflink.c | 4 +---
 fs/ioctl.c         | 4 ----
 fs/remap_range.c   | 7 +------
 3 files changed, 2 insertions(+), 13 deletions(-)

diff --git a/fs/btrfs/reflink.c b/fs/btrfs/reflink.c
index e0f93b357548..5804f4af2629 100644
--- a/fs/btrfs/reflink.c
+++ b/fs/btrfs/reflink.c
@@ -772,9 +772,7 @@ static int btrfs_remap_file_range_prep(struct file *file_in, loff_t pos_in,
 		if (btrfs_root_readonly(root_out))
 			return -EROFS;
 
-		if (file_in->f_path.mnt != file_out->f_path.mnt ||
-		    inode_in->i_sb != inode_out->i_sb)
-			return -EXDEV;
+		ASSERT(inode_in->i_sb == inode_out->i_sb);
 	}
 
 	/* Don't make the dst file partly checksummed */
diff --git a/fs/ioctl.c b/fs/ioctl.c
index 504e69578112..79550f5f4c45 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -236,9 +236,6 @@ static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
 
 	if (!src_file.file)
 		return -EBADF;
-	ret = -EXDEV;
-	if (src_file.file->f_path.mnt != dst_file->f_path.mnt)
-		goto fdput;
 	cloned = vfs_clone_file_range(src_file.file, off, dst_file, destoff,
 				      olen, 0);
 	if (cloned < 0)
@@ -247,7 +244,6 @@ static long ioctl_file_clone(struct file *dst_file, unsigned long srcfd,
 		ret = -EINVAL;
 	else
 		ret = 0;
-fdput:
 	fdput(src_file);
 	return ret;
 }
diff --git a/fs/remap_range.c b/fs/remap_range.c
index 6d4a9beaa097..264ec4541a6c 100644
--- a/fs/remap_range.c
+++ b/fs/remap_range.c
@@ -368,11 +368,6 @@ loff_t do_clone_file_range(struct file *file_in, loff_t pos_in,
 
 	WARN_ON_ONCE(remap_flags & REMAP_FILE_DEDUP);
 
-	/*
-	 * FICLONE/FICLONERANGE ioctls enforce that src and dest files are on
-	 * the same mount. Practically, they only need to be on the same file
-	 * system.
-	 */
 	if (file_inode(file_in)->i_sb != file_inode(file_out)->i_sb)
 		return -EXDEV;
 
@@ -464,7 +459,7 @@ loff_t vfs_dedupe_file_range_one(struct file *src_file, loff_t src_pos,
 		goto out_drop_write;
 
 	ret = -EXDEV;
-	if (src_file->f_path.mnt != dst_file->f_path.mnt)
+	if (file_inode(src_file)->i_sb != file_inode(dst_file)->i_sb)
 		goto out_drop_write;
 
 	ret = -EISDIR;
-- 
2.35.1