]>
Commit | Line | Data |
---|---|---|
757b8d94 JR |
1 | From 3b8e318b7737fa40daf6abbc06ba31cd6ae8d572 Mon Sep 17 00:00:00 2001 |
2 | From: Coleman Kane <ckane@colemankane.org> | |
3 | Date: Tue, 1 Aug 2023 11:32:38 -0400 | |
4 | Subject: [PATCH] Linux 6.5 compat: use disk_check_media_change when it exists | |
5 | ||
6 | When disk_check_media_change() exists, then define | |
7 | zfs_check_media_change() to simply call disk_check_media_change() on | |
8 | the bd_disk member of its argument. Since disk_check_media_change() | |
9 | is newer than when revalidate_disk was present in bops, we should | |
10 | be able to safely do this via a macro, instead of recreating a new | |
11 | implementation of the inline function that forces revalidation. | |
12 | ||
13 | Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> | |
14 | Reviewed-by: Brian Atkinson <batkinson@lanl.gov> | |
15 | Signed-off-by: Coleman Kane <ckane@colemankane.org> | |
16 | Closes #15101 | |
17 | --- | |
18 | include/os/linux/kernel/linux/blkdev_compat.h | 1 + | |
19 | 1 file changed, 1 insertion(+) | |
20 | ||
21 | diff --git a/include/os/linux/kernel/linux/blkdev_compat.h b/include/os/linux/kernel/linux/blkdev_compat.h | |
22 | index e0f20ba32008..1641dd92a918 100644 | |
23 | --- a/include/os/linux/kernel/linux/blkdev_compat.h | |
24 | +++ b/include/os/linux/kernel/linux/blkdev_compat.h | |
25 | @@ -347,6 +347,7 @@ zfs_check_media_change(struct block_device *bdev) | |
26 | #define vdev_bdev_reread_part(bdev) zfs_check_media_change(bdev) | |
27 | #elif defined(HAVE_DISK_CHECK_MEDIA_CHANGE) | |
28 | #define vdev_bdev_reread_part(bdev) disk_check_media_change(bdev->bd_disk) | |
29 | +#define zfs_check_media_change(bdev) disk_check_media_change(bdev->bd_disk) | |
30 | #else | |
31 | /* | |
32 | * This is encountered if check_disk_change() and bdev_check_media_change() | |
33 | From 43e8f6e37fddc31f23301cb70d466687bd205cd9 Mon Sep 17 00:00:00 2001 | |
34 | From: Coleman Kane <ckane@colemankane.org> | |
35 | Date: Tue, 1 Aug 2023 11:37:20 -0400 | |
36 | Subject: [PATCH] Linux 6.5 compat: blkdev changes | |
37 | ||
38 | Multiple changes to the blkdev API were introduced in Linux 6.5. This | |
39 | includes passing (void* holder) to blkdev_put, adding a new | |
40 | blk_holder_ops* arg to blkdev_get_by_path, adding a new blk_mode_t type | |
41 | that replaces uses of fmode_t, and removing an argument from the release | |
42 | handler on block_device_operations that we weren't using. The open | |
43 | function definition has also changed to take gendisk* and blk_mode_t, so | |
44 | update it accordingly, too. | |
45 | ||
46 | Implement local wrappers for blkdev_get_by_path() and | |
47 | vdev_blkdev_put() so that the in-line calls are cleaner, and place the | |
48 | conditionally-compiled implementation details inside of both of these | |
49 | local wrappers. Both calls are exclusively used within vdev_disk.c, at | |
50 | this time. | |
51 | ||
52 | Add blk_mode_is_open_write() to test FMODE_WRITE / BLK_OPEN_WRITE | |
53 | The wrapper function is now used for testing using the appropriate | |
54 | method for the kernel, whether the open mode is writable or not. | |
55 | ||
56 | Emphasize fmode_t arg in zvol_release is not used | |
57 | ||
58 | Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> | |
59 | Signed-off-by: Coleman Kane <ckane@colemankane.org> | |
60 | Closes #15099 | |
61 | --- | |
62 | config/kernel-blkdev.m4 | 84 ++++++++++++++++++- | |
63 | config/kernel-block-device-operations.m4 | 35 +++++++- | |
64 | include/os/linux/kernel/linux/blkdev_compat.h | 6 ++ | |
65 | module/os/linux/zfs/vdev_disk.c | 65 ++++++++++++-- | |
66 | module/os/linux/zfs/zfs_vnops_os.c | 2 +- | |
67 | module/os/linux/zfs/zpl_ctldir.c | 2 +- | |
68 | module/os/linux/zfs/zvol_os.c | 28 ++++++- | |
69 | 7 files changed, 203 insertions(+), 19 deletions(-) | |
70 | ||
71 | diff --git a/config/kernel-blkdev.m4 b/config/kernel-blkdev.m4 | |
72 | index 887acee670ba..e04a2bd2c3b6 100644 | |
73 | --- a/config/kernel-blkdev.m4 | |
74 | +++ b/config/kernel-blkdev.m4 | |
75 | @@ -16,12 +16,63 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH], [ | |
76 | ]) | |
77 | ]) | |
78 | ||
79 | +dnl # | |
80 | +dnl # 6.5.x API change, | |
81 | +dnl # blkdev_get_by_path() takes 4 args | |
82 | +dnl # | |
83 | +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH_4ARG], [ | |
84 | + ZFS_LINUX_TEST_SRC([blkdev_get_by_path_4arg], [ | |
85 | + #include <linux/fs.h> | |
86 | + #include <linux/blkdev.h> | |
87 | + ], [ | |
88 | + struct block_device *bdev __attribute__ ((unused)) = NULL; | |
89 | + const char *path = "path"; | |
90 | + fmode_t mode = 0; | |
91 | + void *holder = NULL; | |
92 | + struct blk_holder_ops h; | |
93 | + | |
94 | + bdev = blkdev_get_by_path(path, mode, holder, &h); | |
95 | + ]) | |
96 | +]) | |
97 | + | |
98 | AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH], [ | |
99 | - AC_MSG_CHECKING([whether blkdev_get_by_path() exists]) | |
100 | + AC_MSG_CHECKING([whether blkdev_get_by_path() exists and takes 3 args]) | |
101 | ZFS_LINUX_TEST_RESULT([blkdev_get_by_path], [ | |
102 | AC_MSG_RESULT(yes) | |
103 | ], [ | |
104 | - ZFS_LINUX_TEST_ERROR([blkdev_get_by_path()]) | |
105 | + AC_MSG_RESULT(no) | |
106 | + AC_MSG_CHECKING([whether blkdev_get_by_path() exists and takes 4 args]) | |
107 | + ZFS_LINUX_TEST_RESULT([blkdev_get_by_path_4arg], [ | |
108 | + AC_DEFINE(HAVE_BLKDEV_GET_BY_PATH_4ARG, 1, | |
109 | + [blkdev_get_by_path() exists and takes 4 args]) | |
110 | + AC_MSG_RESULT(yes) | |
111 | + ], [ | |
112 | + ZFS_LINUX_TEST_ERROR([blkdev_get_by_path()]) | |
113 | + ]) | |
114 | + ]) | |
115 | +]) | |
116 | + | |
117 | +dnl # | |
118 | +dnl # 6.5.x API change | |
119 | +dnl # blk_mode_t was added as a type to supercede some places where fmode_t | |
120 | +dnl # is used | |
121 | +dnl # | |
122 | +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BLK_MODE_T], [ | |
123 | + ZFS_LINUX_TEST_SRC([blk_mode_t], [ | |
124 | + #include <linux/fs.h> | |
125 | + #include <linux/blkdev.h> | |
126 | + ], [ | |
127 | + blk_mode_t m __attribute((unused)) = (blk_mode_t)0; | |
128 | + ]) | |
129 | +]) | |
130 | + | |
131 | +AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BLK_MODE_T], [ | |
132 | + AC_MSG_CHECKING([whether blk_mode_t is defined]) | |
133 | + ZFS_LINUX_TEST_RESULT([blk_mode_t], [ | |
134 | + AC_MSG_RESULT(yes) | |
135 | + AC_DEFINE(HAVE_BLK_MODE_T, 1, [blk_mode_t is defined]) | |
136 | + ], [ | |
137 | + AC_MSG_RESULT(no) | |
138 | ]) | |
139 | ]) | |
140 | ||
141 | @@ -41,12 +92,35 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_PUT], [ | |
142 | ]) | |
143 | ]) | |
144 | ||
145 | +dnl # | |
146 | +dnl # 6.5.x API change. | |
147 | +dnl # blkdev_put() takes (void* holder) as arg 2 | |
148 | +dnl # | |
149 | +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_PUT_HOLDER], [ | |
150 | + ZFS_LINUX_TEST_SRC([blkdev_put_holder], [ | |
151 | + #include <linux/fs.h> | |
152 | + #include <linux/blkdev.h> | |
153 | + ], [ | |
154 | + struct block_device *bdev = NULL; | |
155 | + void *holder = NULL; | |
156 | + | |
157 | + blkdev_put(bdev, holder); | |
158 | + ]) | |
159 | +]) | |
160 | + | |
161 | AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_PUT], [ | |
162 | AC_MSG_CHECKING([whether blkdev_put() exists]) | |
163 | ZFS_LINUX_TEST_RESULT([blkdev_put], [ | |
164 | AC_MSG_RESULT(yes) | |
165 | ], [ | |
166 | - ZFS_LINUX_TEST_ERROR([blkdev_put()]) | |
167 | + AC_MSG_CHECKING([whether blkdev_put() accepts void* as arg 2]) | |
168 | + ZFS_LINUX_TEST_RESULT([blkdev_put_holder], [ | |
169 | + AC_MSG_RESULT(yes) | |
170 | + AC_DEFINE(HAVE_BLKDEV_PUT_HOLDER, 1, | |
171 | + [blkdev_put() accepts void* as arg 2]) | |
172 | + ], [ | |
173 | + ZFS_LINUX_TEST_ERROR([blkdev_put()]) | |
174 | + ]) | |
175 | ]) | |
176 | ]) | |
177 | ||
178 | @@ -495,7 +569,9 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BLK_STS_RESV_CONFLICT], [ | |
179 | ||
180 | AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [ | |
181 | ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH | |
182 | + ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH_4ARG | |
183 | ZFS_AC_KERNEL_SRC_BLKDEV_PUT | |
184 | + ZFS_AC_KERNEL_SRC_BLKDEV_PUT_HOLDER | |
185 | ZFS_AC_KERNEL_SRC_BLKDEV_REREAD_PART | |
186 | ZFS_AC_KERNEL_SRC_BLKDEV_INVALIDATE_BDEV | |
187 | ZFS_AC_KERNEL_SRC_BLKDEV_LOOKUP_BDEV | |
188 | @@ -510,6 +586,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [ | |
189 | ZFS_AC_KERNEL_SRC_BLKDEV_PART_TO_DEV | |
190 | ZFS_AC_KERNEL_SRC_BLKDEV_DISK_CHECK_MEDIA_CHANGE | |
191 | ZFS_AC_KERNEL_SRC_BLKDEV_BLK_STS_RESV_CONFLICT | |
192 | + ZFS_AC_KERNEL_SRC_BLKDEV_BLK_MODE_T | |
193 | ]) | |
194 | ||
195 | AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [ | |
196 | @@ -530,4 +607,5 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [ | |
197 | ZFS_AC_KERNEL_BLKDEV_PART_TO_DEV | |
198 | ZFS_AC_KERNEL_BLKDEV_DISK_CHECK_MEDIA_CHANGE | |
199 | ZFS_AC_KERNEL_BLKDEV_BLK_STS_RESV_CONFLICT | |
200 | + ZFS_AC_KERNEL_BLKDEV_BLK_MODE_T | |
201 | ]) | |
202 | diff --git a/config/kernel-block-device-operations.m4 b/config/kernel-block-device-operations.m4 | |
203 | index 84e39dc8a2f6..d13c1337b1fb 100644 | |
204 | --- a/config/kernel-block-device-operations.m4 | |
205 | +++ b/config/kernel-block-device-operations.m4 | |
206 | @@ -49,12 +49,42 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [ | |
207 | ], [], []) | |
208 | ]) | |
209 | ||
210 | +dnl # | |
211 | +dnl # 5.9.x API change | |
212 | +dnl # | |
213 | +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG], [ | |
214 | + ZFS_LINUX_TEST_SRC([block_device_operations_release_void_1arg], [ | |
215 | + #include <linux/blkdev.h> | |
216 | + | |
217 | + void blk_release(struct gendisk *g) { | |
218 | + (void) g; | |
219 | + return; | |
220 | + } | |
221 | + | |
222 | + static const struct block_device_operations | |
223 | + bops __attribute__ ((unused)) = { | |
224 | + .open = NULL, | |
225 | + .release = blk_release, | |
226 | + .ioctl = NULL, | |
227 | + .compat_ioctl = NULL, | |
228 | + }; | |
229 | + ], [], []) | |
230 | +]) | |
231 | + | |
232 | AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [ | |
233 | - AC_MSG_CHECKING([whether bops->release() is void]) | |
234 | + AC_MSG_CHECKING([whether bops->release() is void and takes 2 args]) | |
235 | ZFS_LINUX_TEST_RESULT([block_device_operations_release_void], [ | |
236 | AC_MSG_RESULT(yes) | |
237 | ],[ | |
238 | - ZFS_LINUX_TEST_ERROR([bops->release()]) | |
239 | + AC_MSG_RESULT(no) | |
240 | + AC_MSG_CHECKING([whether bops->release() is void and takes 1 arg]) | |
241 | + ZFS_LINUX_TEST_RESULT([block_device_operations_release_void_1arg], [ | |
242 | + AC_MSG_RESULT(yes) | |
243 | + AC_DEFINE([HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG], [1], | |
244 | + [Define if release() in block_device_operations takes 1 arg]) | |
245 | + ],[ | |
246 | + ZFS_LINUX_TEST_ERROR([bops->release()]) | |
247 | + ]) | |
248 | ]) | |
249 | ]) | |
250 | ||
251 | @@ -92,6 +122,7 @@ AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK], [ | |
252 | AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS], [ | |
253 | ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS | |
254 | ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID | |
255 | + ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG | |
256 | ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK | |
257 | ]) | |
258 | ||
259 | diff --git a/include/os/linux/kernel/linux/blkdev_compat.h b/include/os/linux/kernel/linux/blkdev_compat.h | |
260 | index 1641dd92a918..f111e648ccf7 100644 | |
261 | --- a/include/os/linux/kernel/linux/blkdev_compat.h | |
262 | +++ b/include/os/linux/kernel/linux/blkdev_compat.h | |
263 | @@ -398,6 +398,12 @@ vdev_lookup_bdev(const char *path, dev_t *dev) | |
264 | #endif | |
265 | } | |
266 | ||
267 | +#if defined(HAVE_BLK_MODE_T) | |
268 | +#define blk_mode_is_open_write(flag) ((flag) & BLK_OPEN_WRITE) | |
269 | +#else | |
270 | +#define blk_mode_is_open_write(flag) ((flag) & FMODE_WRITE) | |
271 | +#endif | |
272 | + | |
273 | /* | |
274 | * Kernels without bio_set_op_attrs use bi_rw for the bio flags. | |
275 | */ | |
276 | diff --git a/module/os/linux/zfs/vdev_disk.c b/module/os/linux/zfs/vdev_disk.c | |
277 | index 925ee9d9fe9c..48ac55f07034 100644 | |
278 | --- a/module/os/linux/zfs/vdev_disk.c | |
279 | +++ b/module/os/linux/zfs/vdev_disk.c | |
280 | @@ -80,9 +80,22 @@ typedef struct dio_request { | |
281 | ||
282 | static unsigned int zfs_vdev_failfast_mask = 1; | |
283 | ||
284 | +#ifdef HAVE_BLK_MODE_T | |
285 | +static blk_mode_t | |
286 | +#else | |
287 | static fmode_t | |
288 | +#endif | |
289 | vdev_bdev_mode(spa_mode_t spa_mode) | |
290 | { | |
291 | +#ifdef HAVE_BLK_MODE_T | |
292 | + blk_mode_t mode = 0; | |
293 | + | |
294 | + if (spa_mode & SPA_MODE_READ) | |
295 | + mode |= BLK_OPEN_READ; | |
296 | + | |
297 | + if (spa_mode & SPA_MODE_WRITE) | |
298 | + mode |= BLK_OPEN_WRITE; | |
299 | +#else | |
300 | fmode_t mode = 0; | |
301 | ||
302 | if (spa_mode & SPA_MODE_READ) | |
303 | @@ -90,6 +103,7 @@ vdev_bdev_mode(spa_mode_t spa_mode) | |
304 | ||
305 | if (spa_mode & SPA_MODE_WRITE) | |
306 | mode |= FMODE_WRITE; | |
307 | +#endif | |
308 | ||
309 | return (mode); | |
310 | } | |
311 | @@ -197,12 +211,47 @@ vdev_disk_kobj_evt_post(vdev_t *v) | |
312 | } | |
313 | } | |
314 | ||
315 | +#if !defined(HAVE_BLKDEV_GET_BY_PATH_4ARG) | |
316 | +/* | |
317 | + * Define a dummy struct blk_holder_ops for kernel versions | |
318 | + * prior to 6.5. | |
319 | + */ | |
320 | +struct blk_holder_ops {}; | |
321 | +#endif | |
322 | + | |
323 | +static struct block_device * | |
324 | +vdev_blkdev_get_by_path(const char *path, spa_mode_t mode, void *holder, | |
325 | + const struct blk_holder_ops *hops) | |
326 | +{ | |
327 | +#ifdef HAVE_BLKDEV_GET_BY_PATH_4ARG | |
328 | + return (blkdev_get_by_path(path, | |
329 | + vdev_bdev_mode(mode) | BLK_OPEN_EXCL, holder, hops)); | |
330 | +#else | |
331 | + return (blkdev_get_by_path(path, | |
332 | + vdev_bdev_mode(mode) | FMODE_EXCL, holder)); | |
333 | +#endif | |
334 | +} | |
335 | + | |
336 | +static void | |
337 | +vdev_blkdev_put(struct block_device *bdev, spa_mode_t mode, void *holder) | |
338 | +{ | |
339 | +#ifdef HAVE_BLKDEV_PUT_HOLDER | |
340 | + return (blkdev_put(bdev, holder)); | |
341 | +#else | |
342 | + return (blkdev_put(bdev, vdev_bdev_mode(mode) | FMODE_EXCL)); | |
343 | +#endif | |
344 | +} | |
345 | + | |
346 | static int | |
347 | vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize, | |
348 | uint64_t *logical_ashift, uint64_t *physical_ashift) | |
349 | { | |
350 | struct block_device *bdev; | |
351 | +#ifdef HAVE_BLK_MODE_T | |
352 | + blk_mode_t mode = vdev_bdev_mode(spa_mode(v->vdev_spa)); | |
353 | +#else | |
354 | fmode_t mode = vdev_bdev_mode(spa_mode(v->vdev_spa)); | |
355 | +#endif | |
356 | hrtime_t timeout = MSEC2NSEC(zfs_vdev_open_timeout_ms); | |
357 | vdev_disk_t *vd; | |
358 | ||
359 | @@ -252,15 +301,15 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize, | |
360 | reread_part = B_TRUE; | |
361 | } | |
362 | ||
363 | - blkdev_put(bdev, mode | FMODE_EXCL); | |
364 | + vdev_blkdev_put(bdev, mode, zfs_vdev_holder); | |
365 | } | |
366 | ||
367 | if (reread_part) { | |
368 | - bdev = blkdev_get_by_path(disk_name, mode | FMODE_EXCL, | |
369 | - zfs_vdev_holder); | |
370 | + bdev = vdev_blkdev_get_by_path(disk_name, mode, | |
371 | + zfs_vdev_holder, NULL); | |
372 | if (!IS_ERR(bdev)) { | |
373 | int error = vdev_bdev_reread_part(bdev); | |
374 | - blkdev_put(bdev, mode | FMODE_EXCL); | |
375 | + vdev_blkdev_put(bdev, mode, zfs_vdev_holder); | |
376 | if (error == 0) { | |
377 | timeout = MSEC2NSEC( | |
378 | zfs_vdev_open_timeout_ms * 2); | |
379 | @@ -305,8 +354,8 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize, | |
380 | hrtime_t start = gethrtime(); | |
381 | bdev = ERR_PTR(-ENXIO); | |
382 | while (IS_ERR(bdev) && ((gethrtime() - start) < timeout)) { | |
383 | - bdev = blkdev_get_by_path(v->vdev_path, mode | FMODE_EXCL, | |
384 | - zfs_vdev_holder); | |
385 | + bdev = vdev_blkdev_get_by_path(v->vdev_path, mode, | |
386 | + zfs_vdev_holder, NULL); | |
387 | if (unlikely(PTR_ERR(bdev) == -ENOENT)) { | |
388 | /* | |
389 | * There is no point of waiting since device is removed | |
390 | @@ -382,8 +431,8 @@ vdev_disk_close(vdev_t *v) | |
391 | return; | |
392 | ||
393 | if (vd->vd_bdev != NULL) { | |
394 | - blkdev_put(vd->vd_bdev, | |
395 | - vdev_bdev_mode(spa_mode(v->vdev_spa)) | FMODE_EXCL); | |
396 | + vdev_blkdev_put(vd->vd_bdev, spa_mode(v->vdev_spa), | |
397 | + zfs_vdev_holder); | |
398 | } | |
399 | ||
400 | rw_destroy(&vd->vd_lock); | |
401 | diff --git a/module/os/linux/zfs/zfs_vnops_os.c b/module/os/linux/zfs/zfs_vnops_os.c | |
402 | index 234c4d5ef0e0..33baac9db06b 100644 | |
403 | --- a/module/os/linux/zfs/zfs_vnops_os.c | |
404 | +++ b/module/os/linux/zfs/zfs_vnops_os.c | |
405 | @@ -186,7 +186,7 @@ zfs_open(struct inode *ip, int mode, int flag, cred_t *cr) | |
406 | return (error); | |
407 | ||
408 | /* Honor ZFS_APPENDONLY file attribute */ | |
409 | - if ((mode & FMODE_WRITE) && (zp->z_pflags & ZFS_APPENDONLY) && | |
410 | + if (blk_mode_is_open_write(mode) && (zp->z_pflags & ZFS_APPENDONLY) && | |
411 | ((flag & O_APPEND) == 0)) { | |
412 | zfs_exit(zfsvfs, FTAG); | |
413 | return (SET_ERROR(EPERM)); | |
414 | diff --git a/module/os/linux/zfs/zpl_ctldir.c b/module/os/linux/zfs/zpl_ctldir.c | |
415 | index 68a7de78f471..7786444fea35 100644 | |
416 | --- a/module/os/linux/zfs/zpl_ctldir.c | |
417 | +++ b/module/os/linux/zfs/zpl_ctldir.c | |
418 | @@ -42,7 +42,7 @@ | |
419 | static int | |
420 | zpl_common_open(struct inode *ip, struct file *filp) | |
421 | { | |
422 | - if (filp->f_mode & FMODE_WRITE) | |
423 | + if (blk_mode_is_open_write(filp->f_mode)) | |
424 | return (-EACCES); | |
425 | ||
426 | return (generic_file_open(ip, filp)); | |
427 | diff --git a/module/os/linux/zfs/zvol_os.c b/module/os/linux/zfs/zvol_os.c | |
428 | index 38bc8e2c4eeb..7a95b54bdf0d 100644 | |
429 | --- a/module/os/linux/zfs/zvol_os.c | |
430 | +++ b/module/os/linux/zfs/zvol_os.c | |
431 | @@ -671,7 +671,11 @@ zvol_request(struct request_queue *q, struct bio *bio) | |
432 | } | |
433 | ||
434 | static int | |
435 | +#ifdef HAVE_BLK_MODE_T | |
436 | +zvol_open(struct gendisk *disk, blk_mode_t flag) | |
437 | +#else | |
438 | zvol_open(struct block_device *bdev, fmode_t flag) | |
439 | +#endif | |
440 | { | |
441 | zvol_state_t *zv; | |
442 | int error = 0; | |
443 | @@ -686,10 +690,14 @@ zvol_open(struct block_device *bdev, fmode_t flag) | |
444 | /* | |
445 | * Obtain a copy of private_data under the zvol_state_lock to make | |
446 | * sure that either the result of zvol free code path setting | |
447 | - * bdev->bd_disk->private_data to NULL is observed, or zvol_os_free() | |
448 | + * disk->private_data to NULL is observed, or zvol_os_free() | |
449 | * is not called on this zv because of the positive zv_open_count. | |
450 | */ | |
451 | +#ifdef HAVE_BLK_MODE_T | |
452 | + zv = disk->private_data; | |
453 | +#else | |
454 | zv = bdev->bd_disk->private_data; | |
455 | +#endif | |
456 | if (zv == NULL) { | |
457 | rw_exit(&zvol_state_lock); | |
458 | return (SET_ERROR(-ENXIO)); | |
459 | @@ -769,14 +777,15 @@ zvol_open(struct block_device *bdev, fmode_t flag) | |
460 | } | |
461 | } | |
462 | ||
463 | - error = -zvol_first_open(zv, !(flag & FMODE_WRITE)); | |
464 | + error = -zvol_first_open(zv, !(blk_mode_is_open_write(flag))); | |
465 | ||
466 | if (drop_namespace) | |
467 | mutex_exit(&spa_namespace_lock); | |
468 | } | |
469 | ||
470 | if (error == 0) { | |
471 | - if ((flag & FMODE_WRITE) && (zv->zv_flags & ZVOL_RDONLY)) { | |
472 | + if ((blk_mode_is_open_write(flag)) && | |
473 | + (zv->zv_flags & ZVOL_RDONLY)) { | |
474 | if (zv->zv_open_count == 0) | |
475 | zvol_last_close(zv); | |
476 | ||
477 | @@ -791,14 +800,25 @@ zvol_open(struct block_device *bdev, fmode_t flag) | |
478 | rw_exit(&zv->zv_suspend_lock); | |
479 | ||
480 | if (error == 0) | |
481 | +#ifdef HAVE_BLK_MODE_T | |
482 | + disk_check_media_change(disk); | |
483 | +#else | |
484 | zfs_check_media_change(bdev); | |
485 | +#endif | |
486 | ||
487 | return (error); | |
488 | } | |
489 | ||
490 | static void | |
491 | -zvol_release(struct gendisk *disk, fmode_t mode) | |
492 | +#ifdef HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG | |
493 | +zvol_release(struct gendisk *disk) | |
494 | +#else | |
495 | +zvol_release(struct gendisk *disk, fmode_t unused) | |
496 | +#endif | |
497 | { | |
498 | +#if !defined(HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG) | |
499 | + (void) unused; | |
500 | +#endif | |
501 | zvol_state_t *zv; | |
502 | boolean_t drop_suspend = B_TRUE; | |
503 | ||
504 | From e47e9bbe86f2e8fe5da0fc7c3a9014e1f8c132a9 Mon Sep 17 00:00:00 2001 | |
505 | From: Coleman Kane <ckane@colemankane.org> | |
506 | Date: Wed, 2 Aug 2023 17:05:46 -0400 | |
507 | Subject: [PATCH] Linux 6.5 compat: register_sysctl_table removed | |
508 | ||
509 | Additionally, the .child element of ctl_table has been removed in 6.5. | |
510 | This change adds a new test for the pre-6.5 register_sysctl_table() | |
511 | function, and uses the old code in that case. If it isn't found, then | |
512 | the parentage entries in the tables are removed, and the register_sysctl | |
513 | call is provided the paths of "kernel/spl", "kernel/spl/kmem", and | |
514 | "kernel/spl/kstat" directly, to populate each subdirectory over three | |
515 | calls, as is the new API. | |
516 | ||
517 | Reviewed-by: Brian Atkinson <batkinson@lanl.gov> | |
518 | Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> | |
519 | Signed-off-by: Coleman Kane <ckane@colemankane.org> | |
520 | Closes #15138 | |
521 | --- | |
522 | config/kernel-register_sysctl_table.m4 | 27 ++++++++++++++++++++++++++ | |
523 | config/kernel.m4 | 2 ++ | |
524 | module/os/linux/spl/spl-proc.c | 26 ++++++++++++++++++++++--- | |
525 | 3 files changed, 52 insertions(+), 3 deletions(-) | |
526 | create mode 100644 config/kernel-register_sysctl_table.m4 | |
527 | ||
528 | diff --git a/config/kernel-register_sysctl_table.m4 b/config/kernel-register_sysctl_table.m4 | |
529 | new file mode 100644 | |
530 | index 000000000000..a5e934f56d29 | |
531 | --- /dev/null | |
532 | +++ b/config/kernel-register_sysctl_table.m4 | |
533 | @@ -0,0 +1,27 @@ | |
534 | +dnl # | |
535 | +dnl # Linux 6.5 removes register_sysctl_table | |
536 | +dnl # | |
537 | +AC_DEFUN([ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_TABLE], [ | |
538 | + ZFS_LINUX_TEST_SRC([has_register_sysctl_table], [ | |
539 | + #include <linux/sysctl.h> | |
540 | + | |
541 | + static struct ctl_table dummy_table[] = { | |
542 | + {} | |
543 | + }; | |
544 | + | |
545 | + ],[ | |
546 | + struct ctl_table_header *h | |
547 | + __attribute((unused)) = register_sysctl_table(dummy_table); | |
548 | + ]) | |
549 | +]) | |
550 | + | |
551 | +AC_DEFUN([ZFS_AC_KERNEL_REGISTER_SYSCTL_TABLE], [ | |
552 | + AC_MSG_CHECKING([whether register_sysctl_table exists]) | |
553 | + ZFS_LINUX_TEST_RESULT([has_register_sysctl_table], [ | |
554 | + AC_MSG_RESULT([yes]) | |
555 | + AC_DEFINE(HAVE_REGISTER_SYSCTL_TABLE, 1, | |
556 | + [register_sysctl_table exists]) | |
557 | + ],[ | |
558 | + AC_MSG_RESULT([no]) | |
559 | + ]) | |
560 | +]) | |
561 | diff --git a/config/kernel.m4 b/config/kernel.m4 | |
562 | index 1487fa2e7793..28bd361d33ff 100644 | |
563 | --- a/config/kernel.m4 | |
564 | +++ b/config/kernel.m4 | |
565 | @@ -160,6 +160,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [ | |
566 | ZFS_AC_KERNEL_SRC_FILEMAP | |
567 | ZFS_AC_KERNEL_SRC_WRITEPAGE_T | |
568 | ZFS_AC_KERNEL_SRC_RECLAIMED | |
569 | + ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_TABLE | |
570 | case "$host_cpu" in | |
571 | powerpc*) | |
572 | ZFS_AC_KERNEL_SRC_CPU_HAS_FEATURE | |
573 | @@ -299,6 +300,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [ | |
574 | ZFS_AC_KERNEL_FILEMAP | |
575 | ZFS_AC_KERNEL_WRITEPAGE_T | |
576 | ZFS_AC_KERNEL_RECLAIMED | |
577 | + ZFS_AC_KERNEL_REGISTER_SYSCTL_TABLE | |
578 | case "$host_cpu" in | |
579 | powerpc*) | |
580 | ZFS_AC_KERNEL_CPU_HAS_FEATURE | |
581 | diff --git a/module/os/linux/spl/spl-proc.c b/module/os/linux/spl/spl-proc.c | |
582 | index 01f5619e1893..bcc356ae55b6 100644 | |
583 | --- a/module/os/linux/spl/spl-proc.c | |
584 | +++ b/module/os/linux/spl/spl-proc.c | |
585 | @@ -624,6 +624,7 @@ static struct ctl_table spl_table[] = { | |
586 | .mode = 0644, | |
587 | .proc_handler = &proc_dohostid, | |
588 | }, | |
589 | +#ifdef HAVE_REGISTER_SYSCTL_TABLE | |
590 | { | |
591 | .procname = "kmem", | |
592 | .mode = 0555, | |
593 | @@ -634,9 +635,11 @@ static struct ctl_table spl_table[] = { | |
594 | .mode = 0555, | |
595 | .child = spl_kstat_table, | |
596 | }, | |
597 | +#endif | |
598 | {}, | |
599 | }; | |
600 | ||
601 | +#ifdef HAVE_REGISTER_SYSCTL_TABLE | |
602 | static struct ctl_table spl_dir[] = { | |
603 | { | |
604 | .procname = "spl", | |
605 | @@ -648,21 +651,38 @@ static struct ctl_table spl_dir[] = { | |
606 | ||
607 | static struct ctl_table spl_root[] = { | |
608 | { | |
609 | - .procname = "kernel", | |
610 | - .mode = 0555, | |
611 | - .child = spl_dir, | |
612 | + .procname = "kernel", | |
613 | + .mode = 0555, | |
614 | + .child = spl_dir, | |
615 | }, | |
616 | {} | |
617 | }; | |
618 | +#endif | |
619 | ||
620 | int | |
621 | spl_proc_init(void) | |
622 | { | |
623 | int rc = 0; | |
624 | ||
625 | +#ifdef HAVE_REGISTER_SYSCTL_TABLE | |
626 | spl_header = register_sysctl_table(spl_root); | |
627 | if (spl_header == NULL) | |
628 | return (-EUNATCH); | |
629 | +#else | |
630 | + spl_header = register_sysctl("kernel/spl", spl_table); | |
631 | + if (spl_header == NULL) | |
632 | + return (-EUNATCH); | |
633 | + | |
634 | + if (register_sysctl("kernel/spl/kmem", spl_kmem_table) == NULL) { | |
635 | + rc = -EUNATCH; | |
636 | + goto out; | |
637 | + } | |
638 | + | |
639 | + if (register_sysctl("kernel/spl/kstat", spl_kstat_table) == NULL) { | |
640 | + rc = -EUNATCH; | |
641 | + goto out; | |
642 | + } | |
643 | +#endif | |
644 | ||
645 | proc_spl = proc_mkdir("spl", NULL); | |
646 | if (proc_spl == NULL) { | |
647 | From 36261c8238df462b214854ccea1df4f060cf0995 Mon Sep 17 00:00:00 2001 | |
648 | From: Coleman Kane <ckane@colemankane.org> | |
649 | Date: Mon, 7 Aug 2023 18:47:46 -0400 | |
650 | Subject: [PATCH] Linux 6.5 compat: replace generic_file_splice_read with | |
651 | filemap_splice_read | |
652 | ||
653 | The generic_file_splice_read function was removed in Linux 6.5 in favor | |
654 | of filemap_splice_read. Add an autoconf test for filemap_splice_read and | |
655 | use it if it is found as the handler for .splice_read in the | |
656 | file_operations struct. Additionally, ITER_PIPE was removed in 6.5. This | |
657 | change removes the ITER_* macros that OpenZFS doesn't use from being | |
658 | tested in config/kernel-vfs-iov_iter.m4. The removal of ITER_PIPE was | |
659 | causing the test to fail, which also affected the code responsible for | |
660 | setting the .splice_read handler, above. That behavior caused run-time | |
661 | panics on Linux 6.5. | |
662 | ||
663 | Reviewed-by: Brian Atkinson <batkinson@lanl.gov> | |
664 | Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> | |
665 | Signed-off-by: Coleman Kane <ckane@colemankane.org> | |
666 | Closes #15155 | |
667 | --- | |
668 | config/kernel-filemap-splice-read.m4 | 25 +++++++++++++++++++++++++ | |
669 | config/kernel-vfs-iov_iter.m4 | 3 +-- | |
670 | config/kernel.m4 | 2 ++ | |
671 | module/os/linux/zfs/zpl_file.c | 4 ++++ | |
672 | 4 files changed, 32 insertions(+), 2 deletions(-) | |
673 | create mode 100644 config/kernel-filemap-splice-read.m4 | |
674 | ||
675 | diff --git a/config/kernel-filemap-splice-read.m4 b/config/kernel-filemap-splice-read.m4 | |
676 | new file mode 100644 | |
677 | index 000000000000..5199b7373e4d | |
678 | --- /dev/null | |
679 | +++ b/config/kernel-filemap-splice-read.m4 | |
680 | @@ -0,0 +1,25 @@ | |
681 | +AC_DEFUN([ZFS_AC_KERNEL_SRC_FILEMAP_SPLICE_READ], [ | |
682 | + dnl # | |
683 | + dnl # Kernel 6.5 - generic_file_splice_read was removed in favor | |
684 | + dnl # of filemap_splice_read for the .splice_read member of the | |
685 | + dnl # file_operations struct. | |
686 | + dnl # | |
687 | + ZFS_LINUX_TEST_SRC([has_filemap_splice_read], [ | |
688 | + #include <linux/fs.h> | |
689 | + | |
690 | + struct file_operations fops __attribute__((unused)) = { | |
691 | + .splice_read = filemap_splice_read, | |
692 | + }; | |
693 | + ],[]) | |
694 | +]) | |
695 | + | |
696 | +AC_DEFUN([ZFS_AC_KERNEL_FILEMAP_SPLICE_READ], [ | |
697 | + AC_MSG_CHECKING([whether filemap_splice_read() exists]) | |
698 | + ZFS_LINUX_TEST_RESULT([has_filemap_splice_read], [ | |
699 | + AC_MSG_RESULT(yes) | |
700 | + AC_DEFINE(HAVE_FILEMAP_SPLICE_READ, 1, | |
701 | + [filemap_splice_read exists]) | |
702 | + ],[ | |
703 | + AC_MSG_RESULT(no) | |
704 | + ]) | |
705 | +]) | |
706 | diff --git a/config/kernel-vfs-iov_iter.m4 b/config/kernel-vfs-iov_iter.m4 | |
707 | index cc5a7ab0c237..ff560ff3eef0 100644 | |
708 | --- a/config/kernel-vfs-iov_iter.m4 | |
709 | +++ b/config/kernel-vfs-iov_iter.m4 | |
710 | @@ -6,8 +6,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_IOV_ITER], [ | |
711 | #include <linux/fs.h> | |
712 | #include <linux/uio.h> | |
713 | ],[ | |
714 | - int type __attribute__ ((unused)) = | |
715 | - ITER_IOVEC | ITER_KVEC | ITER_BVEC | ITER_PIPE; | |
716 | + int type __attribute__ ((unused)) = ITER_KVEC; | |
717 | ]) | |
718 | ||
719 | ZFS_LINUX_TEST_SRC([iov_iter_advance], [ | |
720 | diff --git a/config/kernel.m4 b/config/kernel.m4 | |
721 | index 28bd361d33ff..309f1819be48 100644 | |
722 | --- a/config/kernel.m4 | |
723 | +++ b/config/kernel.m4 | |
724 | @@ -161,6 +161,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [ | |
725 | ZFS_AC_KERNEL_SRC_WRITEPAGE_T | |
726 | ZFS_AC_KERNEL_SRC_RECLAIMED | |
727 | ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_TABLE | |
728 | + ZFS_AC_KERNEL_SRC_FILEMAP_SPLICE_READ | |
729 | case "$host_cpu" in | |
730 | powerpc*) | |
731 | ZFS_AC_KERNEL_SRC_CPU_HAS_FEATURE | |
732 | @@ -301,6 +302,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [ | |
733 | ZFS_AC_KERNEL_WRITEPAGE_T | |
734 | ZFS_AC_KERNEL_RECLAIMED | |
735 | ZFS_AC_KERNEL_REGISTER_SYSCTL_TABLE | |
736 | + ZFS_AC_KERNEL_FILEMAP_SPLICE_READ | |
737 | case "$host_cpu" in | |
738 | powerpc*) | |
739 | ZFS_AC_KERNEL_CPU_HAS_FEATURE | |
740 | diff --git a/module/os/linux/zfs/zpl_file.c b/module/os/linux/zfs/zpl_file.c | |
741 | index f6af2ebd1163..24cc1064a8fc 100644 | |
742 | --- a/module/os/linux/zfs/zpl_file.c | |
743 | +++ b/module/os/linux/zfs/zpl_file.c | |
744 | @@ -1323,7 +1323,11 @@ const struct file_operations zpl_file_operations = { | |
745 | .read_iter = zpl_iter_read, | |
746 | .write_iter = zpl_iter_write, | |
747 | #ifdef HAVE_VFS_IOV_ITER | |
748 | +#ifdef HAVE_FILEMAP_SPLICE_READ | |
749 | + .splice_read = filemap_splice_read, | |
750 | +#else | |
751 | .splice_read = generic_file_splice_read, | |
752 | +#endif | |
753 | .splice_write = iter_file_splice_write, | |
754 | #endif | |
755 | #else | |
756 | From 8ce2eba9e6a384feef93d77c397f37d17dc588ce Mon Sep 17 00:00:00 2001 | |
757 | From: Coleman Kane <ckane@colemankane.org> | |
758 | Date: Tue, 8 Aug 2023 18:42:32 -0400 | |
759 | Subject: [PATCH] Linux 6.5 compat: Use copy_splice_read instead of | |
760 | filemap_splice_read | |
761 | ||
762 | Using the filemap_splice_read function for the splice_read handler was | |
763 | leading to occasional data corruption under certain circumstances. Favor | |
764 | using copy_splice_read instead, which does not demonstrate the same | |
765 | erroneous behavior under the tested failure cases. | |
766 | ||
767 | Reviewed-by: Brian Atkinson <batkinson@lanl.gov> | |
768 | Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> | |
769 | Signed-off-by: Coleman Kane <ckane@colemankane.org> | |
770 | Closes #15164 | |
771 | --- | |
772 | config/kernel-filemap-splice-read.m4 | 18 +++++++++--------- | |
773 | config/kernel.m4 | 4 ++-- | |
774 | module/os/linux/zfs/zpl_file.c | 4 ++-- | |
775 | 3 files changed, 13 insertions(+), 13 deletions(-) | |
776 | ||
777 | diff --git a/config/kernel-filemap-splice-read.m4 b/config/kernel-filemap-splice-read.m4 | |
778 | index 5199b7373e4d..4c83b31d738a 100644 | |
779 | --- a/config/kernel-filemap-splice-read.m4 | |
780 | +++ b/config/kernel-filemap-splice-read.m4 | |
781 | @@ -1,24 +1,24 @@ | |
782 | -AC_DEFUN([ZFS_AC_KERNEL_SRC_FILEMAP_SPLICE_READ], [ | |
783 | +AC_DEFUN([ZFS_AC_KERNEL_SRC_COPY_SPLICE_READ], [ | |
784 | dnl # | |
785 | dnl # Kernel 6.5 - generic_file_splice_read was removed in favor | |
786 | - dnl # of filemap_splice_read for the .splice_read member of the | |
787 | + dnl # of copy_splice_read for the .splice_read member of the | |
788 | dnl # file_operations struct. | |
789 | dnl # | |
790 | - ZFS_LINUX_TEST_SRC([has_filemap_splice_read], [ | |
791 | + ZFS_LINUX_TEST_SRC([has_copy_splice_read], [ | |
792 | #include <linux/fs.h> | |
793 | ||
794 | struct file_operations fops __attribute__((unused)) = { | |
795 | - .splice_read = filemap_splice_read, | |
796 | + .splice_read = copy_splice_read, | |
797 | }; | |
798 | ],[]) | |
799 | ]) | |
800 | ||
801 | -AC_DEFUN([ZFS_AC_KERNEL_FILEMAP_SPLICE_READ], [ | |
802 | - AC_MSG_CHECKING([whether filemap_splice_read() exists]) | |
803 | - ZFS_LINUX_TEST_RESULT([has_filemap_splice_read], [ | |
804 | +AC_DEFUN([ZFS_AC_KERNEL_COPY_SPLICE_READ], [ | |
805 | + AC_MSG_CHECKING([whether copy_splice_read() exists]) | |
806 | + ZFS_LINUX_TEST_RESULT([has_copy_splice_read], [ | |
807 | AC_MSG_RESULT(yes) | |
808 | - AC_DEFINE(HAVE_FILEMAP_SPLICE_READ, 1, | |
809 | - [filemap_splice_read exists]) | |
810 | + AC_DEFINE(HAVE_COPY_SPLICE_READ, 1, | |
811 | + [copy_splice_read exists]) | |
812 | ],[ | |
813 | AC_MSG_RESULT(no) | |
814 | ]) | |
815 | diff --git a/config/kernel.m4 b/config/kernel.m4 | |
816 | index 309f1819be48..df194ec72207 100644 | |
817 | --- a/config/kernel.m4 | |
818 | +++ b/config/kernel.m4 | |
819 | @@ -161,7 +161,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [ | |
820 | ZFS_AC_KERNEL_SRC_WRITEPAGE_T | |
821 | ZFS_AC_KERNEL_SRC_RECLAIMED | |
822 | ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_TABLE | |
823 | - ZFS_AC_KERNEL_SRC_FILEMAP_SPLICE_READ | |
824 | + ZFS_AC_KERNEL_SRC_COPY_SPLICE_READ | |
825 | case "$host_cpu" in | |
826 | powerpc*) | |
827 | ZFS_AC_KERNEL_SRC_CPU_HAS_FEATURE | |
828 | @@ -302,7 +302,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [ | |
829 | ZFS_AC_KERNEL_WRITEPAGE_T | |
830 | ZFS_AC_KERNEL_RECLAIMED | |
831 | ZFS_AC_KERNEL_REGISTER_SYSCTL_TABLE | |
832 | - ZFS_AC_KERNEL_FILEMAP_SPLICE_READ | |
833 | + ZFS_AC_KERNEL_COPY_SPLICE_READ | |
834 | case "$host_cpu" in | |
835 | powerpc*) | |
836 | ZFS_AC_KERNEL_CPU_HAS_FEATURE | |
837 | diff --git a/module/os/linux/zfs/zpl_file.c b/module/os/linux/zfs/zpl_file.c | |
838 | index 24cc1064a8fc..3caa0fc6c214 100644 | |
839 | --- a/module/os/linux/zfs/zpl_file.c | |
840 | +++ b/module/os/linux/zfs/zpl_file.c | |
841 | @@ -1323,8 +1323,8 @@ const struct file_operations zpl_file_operations = { | |
842 | .read_iter = zpl_iter_read, | |
843 | .write_iter = zpl_iter_write, | |
844 | #ifdef HAVE_VFS_IOV_ITER | |
845 | -#ifdef HAVE_FILEMAP_SPLICE_READ | |
846 | - .splice_read = filemap_splice_read, | |
847 | +#ifdef HAVE_COPY_SPLICE_READ | |
848 | + .splice_read = copy_splice_read, | |
849 | #else | |
850 | .splice_read = generic_file_splice_read, | |
851 | #endif | |
852 | From bcb1159c095f57564914b59f5e7e82170261afb0 Mon Sep 17 00:00:00 2001 | |
853 | From: Andrea Righi <andrea.righi@canonical.com> | |
854 | Date: Sat, 2 Sep 2023 02:21:40 +0200 | |
855 | Subject: [PATCH] Linux 6.5 compat: safe cleanup in spl_proc_fini() | |
856 | ||
857 | If we fail to create a proc entry in spl_proc_init() we may end up | |
858 | calling unregister_sysctl_table() twice: one in the failure path of | |
859 | spl_proc_init() and another time during spl_proc_fini(). | |
860 | ||
861 | Avoid the double call to unregister_sysctl_table() and while at it | |
862 | refactor the code a bit to reduce code duplication. | |
863 | ||
864 | This was accidentally introduced when the spl code was | |
865 | updated for Linux 6.5 compatibility. | |
866 | ||
867 | Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> | |
868 | Reviewed-by: Ameer Hamza <ahamza@ixsystems.com> | |
869 | Signed-off-by: Andrea Righi <andrea.righi@canonical.com> | |
870 | Closes #15234 | |
871 | Closes #15235 | |
872 | --- | |
873 | module/os/linux/spl/spl-proc.c | 36 +++++++++++++++++----------------- | |
874 | 1 file changed, 18 insertions(+), 18 deletions(-) | |
875 | ||
876 | diff --git a/module/os/linux/spl/spl-proc.c b/module/os/linux/spl/spl-proc.c | |
877 | index bcc356ae55b6..5cb5a6dadb05 100644 | |
878 | --- a/module/os/linux/spl/spl-proc.c | |
879 | +++ b/module/os/linux/spl/spl-proc.c | |
880 | @@ -659,6 +659,21 @@ static struct ctl_table spl_root[] = { | |
881 | }; | |
882 | #endif | |
883 | ||
884 | +static void spl_proc_cleanup(void) | |
885 | +{ | |
886 | + remove_proc_entry("kstat", proc_spl); | |
887 | + remove_proc_entry("slab", proc_spl_kmem); | |
888 | + remove_proc_entry("kmem", proc_spl); | |
889 | + remove_proc_entry("taskq-all", proc_spl); | |
890 | + remove_proc_entry("taskq", proc_spl); | |
891 | + remove_proc_entry("spl", NULL); | |
892 | + | |
893 | + if (spl_header) { | |
894 | + unregister_sysctl_table(spl_header); | |
895 | + spl_header = NULL; | |
896 | + } | |
897 | +} | |
898 | + | |
899 | int | |
900 | spl_proc_init(void) | |
901 | { | |
902 | @@ -723,15 +738,8 @@ spl_proc_init(void) | |
903 | goto out; | |
904 | } | |
905 | out: | |
906 | - if (rc) { | |
907 | - remove_proc_entry("kstat", proc_spl); | |
908 | - remove_proc_entry("slab", proc_spl_kmem); | |
909 | - remove_proc_entry("kmem", proc_spl); | |
910 | - remove_proc_entry("taskq-all", proc_spl); | |
911 | - remove_proc_entry("taskq", proc_spl); | |
912 | - remove_proc_entry("spl", NULL); | |
913 | - unregister_sysctl_table(spl_header); | |
914 | - } | |
915 | + if (rc) | |
916 | + spl_proc_cleanup(); | |
917 | ||
918 | return (rc); | |
919 | } | |
920 | @@ -739,13 +747,5 @@ spl_proc_init(void) | |
921 | void | |
922 | spl_proc_fini(void) | |
923 | { | |
924 | - remove_proc_entry("kstat", proc_spl); | |
925 | - remove_proc_entry("slab", proc_spl_kmem); | |
926 | - remove_proc_entry("kmem", proc_spl); | |
927 | - remove_proc_entry("taskq-all", proc_spl); | |
928 | - remove_proc_entry("taskq", proc_spl); | |
929 | - remove_proc_entry("spl", NULL); | |
930 | - | |
931 | - ASSERT(spl_header != NULL); | |
932 | - unregister_sysctl_table(spl_header); | |
933 | + spl_proc_cleanup(); | |
934 | } |