]> git.pld-linux.org Git - packages/zfs.git/blob - kernel-6.5.patch
- up to 2.2.0-rc3
[packages/zfs.git] / kernel-6.5.patch
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  }
This page took 0.784421 seconds and 3 git commands to generate.