]>
Commit | Line | Data |
---|---|---|
96c807af SI |
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 |