]> git.proxmox.com Git - zfsonlinux.git/blob - debian/patches/0016-Add-a-tunable-to-disable-BRT-support.patch
cherry-pick fix for data corruption
[zfsonlinux.git] / debian / patches / 0016-Add-a-tunable-to-disable-BRT-support.patch
1 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2 From: Rich Ercolani <214141+rincebrain@users.noreply.github.com>
3 Date: Thu, 16 Nov 2023 14:35:22 -0500
4 Subject: [PATCH] Add a tunable to disable BRT support.
5
6 Copy the disable parameter that FreeBSD implemented, and extend it to
7 work on Linux as well, until we're sure this is stable.
8
9 Reviewed-by: Alexander Motin <mav@FreeBSD.org>
10 Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
11 Signed-off-by: Rich Ercolani <rincebrain@gmail.com>
12 Closes #15529
13 (cherry picked from commit 87e9e828655c250ce064874ff5df16f870c0a52e)
14 Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
15 ---
16 include/os/freebsd/zfs/sys/zfs_vfsops_os.h | 1 +
17 include/os/linux/zfs/sys/zfs_vfsops_os.h | 2 ++
18 man/man4/zfs.4 | 5 +++++
19 module/os/freebsd/zfs/zfs_vfsops.c | 4 ++++
20 module/os/freebsd/zfs/zfs_vnops_os.c | 5 +++++
21 module/os/linux/zfs/zfs_vnops_os.c | 4 ++++
22 module/os/linux/zfs/zpl_file_range.c | 5 +++++
23 tests/zfs-tests/include/libtest.shlib | 15 +++++++++++++++
24 tests/zfs-tests/include/tunables.cfg | 1 +
25 .../tests/functional/block_cloning/cleanup.ksh | 4 ++++
26 .../tests/functional/block_cloning/setup.ksh | 5 +++++
27 11 files changed, 51 insertions(+)
28
29 diff --git a/include/os/freebsd/zfs/sys/zfs_vfsops_os.h b/include/os/freebsd/zfs/sys/zfs_vfsops_os.h
30 index 24bb03575..56a0ac96a 100644
31 --- a/include/os/freebsd/zfs/sys/zfs_vfsops_os.h
32 +++ b/include/os/freebsd/zfs/sys/zfs_vfsops_os.h
33 @@ -286,6 +286,7 @@ typedef struct zfid_long {
34
35 extern uint_t zfs_fsyncer_key;
36 extern int zfs_super_owner;
37 +extern int zfs_bclone_enabled;
38
39 extern void zfs_init(void);
40 extern void zfs_fini(void);
41 diff --git a/include/os/linux/zfs/sys/zfs_vfsops_os.h b/include/os/linux/zfs/sys/zfs_vfsops_os.h
42 index b4d5db21f..220466550 100644
43 --- a/include/os/linux/zfs/sys/zfs_vfsops_os.h
44 +++ b/include/os/linux/zfs/sys/zfs_vfsops_os.h
45 @@ -45,6 +45,8 @@ extern "C" {
46 typedef struct zfsvfs zfsvfs_t;
47 struct znode;
48
49 +extern int zfs_bclone_enabled;
50 +
51 /*
52 * This structure emulates the vfs_t from other platforms. It's purpose
53 * is to facilitate the handling of mount options and minimize structural
54 diff --git a/man/man4/zfs.4 b/man/man4/zfs.4
55 index cfadd79d8..32f1765a5 100644
56 --- a/man/man4/zfs.4
57 +++ b/man/man4/zfs.4
58 @@ -1137,6 +1137,11 @@ Selecting any option other than
59 results in vector instructions
60 from the respective CPU instruction set being used.
61 .
62 +.It Sy zfs_bclone_enabled Ns = Ns Sy 1 Ns | Ns 0 Pq int
63 +Enable the experimental block cloning feature.
64 +If this setting is 0, then even if feature@block_cloning is enabled,
65 +attempts to clone blocks will act as though the feature is disabled.
66 +.
67 .It Sy zfs_blake3_impl Ns = Ns Sy fastest Pq string
68 Select a BLAKE3 implementation.
69 .Pp
70 diff --git a/module/os/freebsd/zfs/zfs_vfsops.c b/module/os/freebsd/zfs/zfs_vfsops.c
71 index e8b9ada13..09e18de81 100644
72 --- a/module/os/freebsd/zfs/zfs_vfsops.c
73 +++ b/module/os/freebsd/zfs/zfs_vfsops.c
74 @@ -89,6 +89,10 @@ int zfs_debug_level;
75 SYSCTL_INT(_vfs_zfs, OID_AUTO, debug, CTLFLAG_RWTUN, &zfs_debug_level, 0,
76 "Debug level");
77
78 +int zfs_bclone_enabled = 1;
79 +SYSCTL_INT(_vfs_zfs, OID_AUTO, bclone_enabled, CTLFLAG_RWTUN,
80 + &zfs_bclone_enabled, 0, "Enable block cloning");
81 +
82 struct zfs_jailparam {
83 int mount_snapshot;
84 };
85 diff --git a/module/os/freebsd/zfs/zfs_vnops_os.c b/module/os/freebsd/zfs/zfs_vnops_os.c
86 index c498a1328..f672deed3 100644
87 --- a/module/os/freebsd/zfs/zfs_vnops_os.c
88 +++ b/module/os/freebsd/zfs/zfs_vnops_os.c
89 @@ -6243,6 +6243,11 @@ zfs_freebsd_copy_file_range(struct vop_copy_file_range_args *ap)
90 int error;
91 uint64_t len = *ap->a_lenp;
92
93 + if (!zfs_bclone_enabled) {
94 + mp = NULL;
95 + goto bad_write_fallback;
96 + }
97 +
98 /*
99 * TODO: If offset/length is not aligned to recordsize, use
100 * vn_generic_copy_file_range() on this fragment.
101 diff --git a/module/os/linux/zfs/zfs_vnops_os.c b/module/os/linux/zfs/zfs_vnops_os.c
102 index 33baac9db..76fac3a02 100644
103 --- a/module/os/linux/zfs/zfs_vnops_os.c
104 +++ b/module/os/linux/zfs/zfs_vnops_os.c
105 @@ -4229,4 +4229,8 @@ EXPORT_SYMBOL(zfs_map);
106 module_param(zfs_delete_blocks, ulong, 0644);
107 MODULE_PARM_DESC(zfs_delete_blocks, "Delete files larger than N blocks async");
108
109 +/* CSTYLED */
110 +module_param(zfs_bclone_enabled, uint, 0644);
111 +MODULE_PARM_DESC(zfs_bclone_enabled, "Enable block cloning");
112 +
113 #endif
114 diff --git a/module/os/linux/zfs/zpl_file_range.c b/module/os/linux/zfs/zpl_file_range.c
115 index c47fe99da..73476ff40 100644
116 --- a/module/os/linux/zfs/zpl_file_range.c
117 +++ b/module/os/linux/zfs/zpl_file_range.c
118 @@ -31,6 +31,8 @@
119 #include <sys/zfs_vnops.h>
120 #include <sys/zfeature.h>
121
122 +int zfs_bclone_enabled = 1;
123 +
124 /*
125 * Clone part of a file via block cloning.
126 *
127 @@ -50,6 +52,9 @@ __zpl_clone_file_range(struct file *src_file, loff_t src_off,
128 fstrans_cookie_t cookie;
129 int err;
130
131 + if (!zfs_bclone_enabled)
132 + return (-EOPNOTSUPP);
133 +
134 if (!spa_feature_is_enabled(
135 dmu_objset_spa(ITOZSB(dst_i)->z_os), SPA_FEATURE_BLOCK_CLONING))
136 return (-EOPNOTSUPP);
137 diff --git a/tests/zfs-tests/include/libtest.shlib b/tests/zfs-tests/include/libtest.shlib
138 index 844caa17d..d5d7bb6c8 100644
139 --- a/tests/zfs-tests/include/libtest.shlib
140 +++ b/tests/zfs-tests/include/libtest.shlib
141 @@ -3334,6 +3334,21 @@ function set_tunable_impl
142 esac
143 }
144
145 +function save_tunable
146 +{
147 + [[ ! -d $TEST_BASE_DIR ]] && return 1
148 + [[ -e $TEST_BASE_DIR/tunable-$1 ]] && return 2
149 + echo "$(get_tunable """$1""")" > "$TEST_BASE_DIR"/tunable-"$1"
150 +}
151 +
152 +function restore_tunable
153 +{
154 + [[ ! -e $TEST_BASE_DIR/tunable-$1 ]] && return 1
155 + val="$(cat $TEST_BASE_DIR/tunable-"""$1""")"
156 + set_tunable64 "$1" "$val"
157 + rm $TEST_BASE_DIR/tunable-$1
158 +}
159 +
160 #
161 # Get a global system tunable
162 #
163 diff --git a/tests/zfs-tests/include/tunables.cfg b/tests/zfs-tests/include/tunables.cfg
164 index 80e7bcb3b..a0edad14d 100644
165 --- a/tests/zfs-tests/include/tunables.cfg
166 +++ b/tests/zfs-tests/include/tunables.cfg
167 @@ -90,6 +90,7 @@ VOL_INHIBIT_DEV UNSUPPORTED zvol_inhibit_dev
168 VOL_MODE vol.mode zvol_volmode
169 VOL_RECURSIVE vol.recursive UNSUPPORTED
170 VOL_USE_BLK_MQ UNSUPPORTED zvol_use_blk_mq
171 +BCLONE_ENABLED zfs_bclone_enabled zfs_bclone_enabled
172 XATTR_COMPAT xattr_compat zfs_xattr_compat
173 ZEVENT_LEN_MAX zevent.len_max zfs_zevent_len_max
174 ZEVENT_RETAIN_MAX zevent.retain_max zfs_zevent_retain_max
175 diff --git a/tests/zfs-tests/tests/functional/block_cloning/cleanup.ksh b/tests/zfs-tests/tests/functional/block_cloning/cleanup.ksh
176 index 7ac13adb6..b985445a5 100755
177 --- a/tests/zfs-tests/tests/functional/block_cloning/cleanup.ksh
178 +++ b/tests/zfs-tests/tests/functional/block_cloning/cleanup.ksh
179 @@ -31,4 +31,8 @@ verify_runnable "global"
180
181 default_cleanup_noexit
182
183 +if tunable_exists BCLONE_ENABLED ; then
184 + log_must restore_tunable BCLONE_ENABLED
185 +fi
186 +
187 log_pass
188 diff --git a/tests/zfs-tests/tests/functional/block_cloning/setup.ksh b/tests/zfs-tests/tests/functional/block_cloning/setup.ksh
189 index 512f5a064..58441bf8f 100755
190 --- a/tests/zfs-tests/tests/functional/block_cloning/setup.ksh
191 +++ b/tests/zfs-tests/tests/functional/block_cloning/setup.ksh
192 @@ -33,4 +33,9 @@ fi
193
194 verify_runnable "global"
195
196 +if tunable_exists BCLONE_ENABLED ; then
197 + log_must save_tunable BCLONE_ENABLED
198 + log_must set_tunable32 BCLONE_ENABLED 1
199 +fi
200 +
201 log_pass