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
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.
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>
18 include/os/linux/kernel/linux/blkdev_compat.h | 1 +
19 1 file changed, 1 insertion(+)
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)
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
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.
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
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.
56 Emphasize fmode_t arg in zvol_release is not used
58 Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
59 Signed-off-by: Coleman Kane <ckane@colemankane.org>
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(-)
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], [
80 +dnl # 6.5.x API change,
81 +dnl # blkdev_get_by_path() takes 4 args
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>
88 + struct block_device *bdev __attribute__ ((unused)) = NULL;
89 + const char *path = "path";
91 + void *holder = NULL;
92 + struct blk_holder_ops h;
94 + bdev = blkdev_get_by_path(path, mode, holder, &h);
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], [
104 - ZFS_LINUX_TEST_ERROR([blkdev_get_by_path()])
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])
112 + ZFS_LINUX_TEST_ERROR([blkdev_get_by_path()])
118 +dnl # 6.5.x API change
119 +dnl # blk_mode_t was added as a type to supercede some places where fmode_t
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>
127 + blk_mode_t m __attribute((unused)) = (blk_mode_t)0;
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], [
135 + AC_DEFINE(HAVE_BLK_MODE_T, 1, [blk_mode_t is defined])
141 @@ -41,12 +92,35 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_PUT], [
146 +dnl # 6.5.x API change.
147 +dnl # blkdev_put() takes (void* holder) as arg 2
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>
154 + struct block_device *bdev = NULL;
155 + void *holder = NULL;
157 + blkdev_put(bdev, holder);
161 AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_PUT], [
162 AC_MSG_CHECKING([whether blkdev_put() exists])
163 ZFS_LINUX_TEST_RESULT([blkdev_put], [
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], [
170 + AC_DEFINE(HAVE_BLKDEV_PUT_HOLDER, 1,
171 + [blkdev_put() accepts void* as arg 2])
173 + ZFS_LINUX_TEST_ERROR([blkdev_put()])
178 @@ -495,7 +569,9 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BLK_STS_RESV_CONFLICT], [
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
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
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], [
211 +dnl # 5.9.x API change
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>
217 + void blk_release(struct gendisk *g) {
222 + static const struct block_device_operations
223 + bops __attribute__ ((unused)) = {
225 + .release = blk_release,
227 + .compat_ioctl = NULL,
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], [
238 - ZFS_LINUX_TEST_ERROR([bops->release()])
240 + AC_MSG_CHECKING([whether bops->release() is void and takes 1 arg])
241 + ZFS_LINUX_TEST_RESULT([block_device_operations_release_void_1arg], [
243 + AC_DEFINE([HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG], [1],
244 + [Define if release() in block_device_operations takes 1 arg])
246 + ZFS_LINUX_TEST_ERROR([bops->release()])
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
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)
267 +#if defined(HAVE_BLK_MODE_T)
268 +#define blk_mode_is_open_write(flag) ((flag) & BLK_OPEN_WRITE)
270 +#define blk_mode_is_open_write(flag) ((flag) & FMODE_WRITE)
274 * Kernels without bio_set_op_attrs use bi_rw for the bio flags.
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 {
282 static unsigned int zfs_vdev_failfast_mask = 1;
284 +#ifdef HAVE_BLK_MODE_T
289 vdev_bdev_mode(spa_mode_t spa_mode)
291 +#ifdef HAVE_BLK_MODE_T
292 + blk_mode_t mode = 0;
294 + if (spa_mode & SPA_MODE_READ)
295 + mode |= BLK_OPEN_READ;
297 + if (spa_mode & SPA_MODE_WRITE)
298 + mode |= BLK_OPEN_WRITE;
302 if (spa_mode & SPA_MODE_READ)
303 @@ -90,6 +103,7 @@ vdev_bdev_mode(spa_mode_t spa_mode)
305 if (spa_mode & SPA_MODE_WRITE)
311 @@ -197,12 +211,47 @@ vdev_disk_kobj_evt_post(vdev_t *v)
315 +#if !defined(HAVE_BLKDEV_GET_BY_PATH_4ARG)
317 + * Define a dummy struct blk_holder_ops for kernel versions
320 +struct blk_holder_ops {};
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)
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));
331 + return (blkdev_get_by_path(path,
332 + vdev_bdev_mode(mode) | FMODE_EXCL, holder));
337 +vdev_blkdev_put(struct block_device *bdev, spa_mode_t mode, void *holder)
339 +#ifdef HAVE_BLKDEV_PUT_HOLDER
340 + return (blkdev_put(bdev, holder));
342 + return (blkdev_put(bdev, vdev_bdev_mode(mode) | FMODE_EXCL));
347 vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize,
348 uint64_t *logical_ashift, uint64_t *physical_ashift)
350 struct block_device *bdev;
351 +#ifdef HAVE_BLK_MODE_T
352 + blk_mode_t mode = vdev_bdev_mode(spa_mode(v->vdev_spa));
354 fmode_t mode = vdev_bdev_mode(spa_mode(v->vdev_spa));
356 hrtime_t timeout = MSEC2NSEC(zfs_vdev_open_timeout_ms);
359 @@ -252,15 +301,15 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize,
360 reread_part = B_TRUE;
363 - blkdev_put(bdev, mode | FMODE_EXCL);
364 + vdev_blkdev_put(bdev, mode, zfs_vdev_holder);
368 - bdev = blkdev_get_by_path(disk_name, mode | FMODE_EXCL,
370 + bdev = vdev_blkdev_get_by_path(disk_name, mode,
371 + zfs_vdev_holder, NULL);
373 int error = vdev_bdev_reread_part(bdev);
374 - blkdev_put(bdev, mode | FMODE_EXCL);
375 + vdev_blkdev_put(bdev, mode, zfs_vdev_holder);
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,
385 + bdev = vdev_blkdev_get_by_path(v->vdev_path, mode,
386 + zfs_vdev_holder, NULL);
387 if (unlikely(PTR_ERR(bdev) == -ENOENT)) {
389 * There is no point of waiting since device is removed
390 @@ -382,8 +431,8 @@ vdev_disk_close(vdev_t *v)
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),
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)
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
420 zpl_common_open(struct inode *ip, struct file *filp)
422 - if (filp->f_mode & FMODE_WRITE)
423 + if (blk_mode_is_open_write(filp->f_mode))
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)
435 +#ifdef HAVE_BLK_MODE_T
436 +zvol_open(struct gendisk *disk, blk_mode_t flag)
438 zvol_open(struct block_device *bdev, fmode_t flag)
443 @@ -686,10 +690,14 @@ zvol_open(struct block_device *bdev, fmode_t flag)
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.
451 +#ifdef HAVE_BLK_MODE_T
452 + zv = disk->private_data;
454 zv = bdev->bd_disk->private_data;
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)
463 - error = -zvol_first_open(zv, !(flag & FMODE_WRITE));
464 + error = -zvol_first_open(zv, !(blk_mode_is_open_write(flag)));
467 mutex_exit(&spa_namespace_lock);
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)
477 @@ -791,14 +800,25 @@ zvol_open(struct block_device *bdev, fmode_t flag)
478 rw_exit(&zv->zv_suspend_lock);
481 +#ifdef HAVE_BLK_MODE_T
482 + disk_check_media_change(disk);
484 zfs_check_media_change(bdev);
491 -zvol_release(struct gendisk *disk, fmode_t mode)
492 +#ifdef HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG
493 +zvol_release(struct gendisk *disk)
495 +zvol_release(struct gendisk *disk, fmode_t unused)
498 +#if !defined(HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG)
502 boolean_t drop_suspend = B_TRUE;
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
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.
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>
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
528 diff --git a/config/kernel-register_sysctl_table.m4 b/config/kernel-register_sysctl_table.m4
530 index 000000000000..a5e934f56d29
532 +++ b/config/kernel-register_sysctl_table.m4
535 +dnl # Linux 6.5 removes register_sysctl_table
537 +AC_DEFUN([ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_TABLE], [
538 + ZFS_LINUX_TEST_SRC([has_register_sysctl_table], [
539 + #include <linux/sysctl.h>
541 + static struct ctl_table dummy_table[] = {
546 + struct ctl_table_header *h
547 + __attribute((unused)) = register_sysctl_table(dummy_table);
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])
558 + AC_MSG_RESULT([no])
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
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
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[] = {
587 .proc_handler = &proc_dohostid,
589 +#ifdef HAVE_REGISTER_SYSCTL_TABLE
593 @@ -634,9 +635,11 @@ static struct ctl_table spl_table[] = {
595 .child = spl_kstat_table,
601 +#ifdef HAVE_REGISTER_SYSCTL_TABLE
602 static struct ctl_table spl_dir[] = {
605 @@ -648,21 +651,38 @@ static struct ctl_table spl_dir[] = {
607 static struct ctl_table spl_root[] = {
609 - .procname = "kernel",
612 + .procname = "kernel",
625 +#ifdef HAVE_REGISTER_SYSCTL_TABLE
626 spl_header = register_sysctl_table(spl_root);
627 if (spl_header == NULL)
630 + spl_header = register_sysctl("kernel/spl", spl_table);
631 + if (spl_header == NULL)
634 + if (register_sysctl("kernel/spl/kmem", spl_kmem_table) == NULL) {
639 + if (register_sysctl("kernel/spl/kstat", spl_kstat_table) == NULL) {
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
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
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>
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
675 diff --git a/config/kernel-filemap-splice-read.m4 b/config/kernel-filemap-splice-read.m4
677 index 000000000000..5199b7373e4d
679 +++ b/config/kernel-filemap-splice-read.m4
681 +AC_DEFUN([ZFS_AC_KERNEL_SRC_FILEMAP_SPLICE_READ], [
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.
687 + ZFS_LINUX_TEST_SRC([has_filemap_splice_read], [
688 + #include <linux/fs.h>
690 + struct file_operations fops __attribute__((unused)) = {
691 + .splice_read = filemap_splice_read,
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], [
700 + AC_DEFINE(HAVE_FILEMAP_SPLICE_READ, 1,
701 + [filemap_splice_read exists])
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>
714 - int type __attribute__ ((unused)) =
715 - ITER_IOVEC | ITER_KVEC | ITER_BVEC | ITER_PIPE;
716 + int type __attribute__ ((unused)) = ITER_KVEC;
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
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
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,
751 .splice_read = generic_file_splice_read,
753 .splice_write = iter_file_splice_write,
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
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.
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>
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(-)
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
782 -AC_DEFUN([ZFS_AC_KERNEL_SRC_FILEMAP_SPLICE_READ], [
783 +AC_DEFUN([ZFS_AC_KERNEL_SRC_COPY_SPLICE_READ], [
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.
790 - ZFS_LINUX_TEST_SRC([has_filemap_splice_read], [
791 + ZFS_LINUX_TEST_SRC([has_copy_splice_read], [
792 #include <linux/fs.h>
794 struct file_operations fops __attribute__((unused)) = {
795 - .splice_read = filemap_splice_read,
796 + .splice_read = copy_splice_read,
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], [
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])
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
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
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,
850 .splice_read = generic_file_splice_read,
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()
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().
861 Avoid the double call to unregister_sysctl_table() and while at it
862 refactor the code a bit to reduce code duplication.
864 This was accidentally introduced when the spl code was
865 updated for Linux 6.5 compatibility.
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>
873 module/os/linux/spl/spl-proc.c | 36 +++++++++++++++++-----------------
874 1 file changed, 18 insertions(+), 18 deletions(-)
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[] = {
884 +static void spl_proc_cleanup(void)
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);
894 + unregister_sysctl_table(spl_header);
902 @@ -723,15 +738,8 @@ spl_proc_init(void)
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);
916 + spl_proc_cleanup();
920 @@ -739,13 +747,5 @@ spl_proc_init(void)
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);
931 - ASSERT(spl_header != NULL);
932 - unregister_sysctl_table(spl_header);
933 + spl_proc_cleanup();