summaryrefslogtreecommitdiff
path: root/sys-fs/zfs-kmod/files/zfs-8.0.4_5.12_compat_bio_max_segs.patch
blob: 33f9a344e2f2dd65bcf349ec0cf99f7c9bd2dad8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
From 77352db228c07ce8ba50478b9029820ca69c6c1b Mon Sep 17 00:00:00 2001
From: Coleman Kane <ckane@colemankane.org>
Date: Sat, 20 Mar 2021 01:33:42 -0400
Subject: [PATCH] Linux 5.12 update: bio_max_segs() replaces BIO_MAX_PAGES

The BIO_MAX_PAGES macro is being retired in favor of a bio_max_segs()
function that implements the typical MIN(x,y) logic used throughout the
kernel for bounding the allocation, and also the new implementation is
intended to be signed-safe (which the former was not).

Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Coleman Kane <ckane@colemankane.org>
Closes #11765
(cherry picked from commit ffd6978ef59cfe2773e984bf03de2f0b93b03f5c)
Signed-off-by: Jonathon Fernyhough <jonathon@m2x.dev>
---
 config/kernel-bio_max_segs.m4   | 23 +++++++++++++++++++++++
 config/kernel.m4                |  2 ++
 module/os/linux/zfs/vdev_disk.c |  5 +++++
 3 files changed, 30 insertions(+)
 create mode 100644 config/kernel-bio_max_segs.m4

diff --git a/config/kernel-bio_max_segs.m4 b/config/kernel-bio_max_segs.m4
new file mode 100644
index 00000000000..a90d75455c1
--- /dev/null
+++ b/config/kernel-bio_max_segs.m4
@@ -0,0 +1,23 @@
+dnl #
+dnl # 5.12 API change removes BIO_MAX_PAGES in favor of bio_max_segs()
+dnl # which will handle the logic of setting the upper-bound to a
+dnl # BIO_MAX_PAGES, internally.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_MAX_SEGS], [
+	ZFS_LINUX_TEST_SRC([bio_max_segs], [
+		#include <linux/bio.h>
+	],[
+		bio_max_segs(1);
+	])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_BIO_MAX_SEGS], [
+	AC_MSG_CHECKING([whether bio_max_segs() exists])
+	ZFS_LINUX_TEST_RESULT([bio_max_segs], [
+		AC_MSG_RESULT(yes)
+
+		AC_DEFINE([HAVE_BIO_MAX_SEGS], 1, [bio_max_segs() is implemented])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
diff --git a/config/kernel.m4 b/config/kernel.m4
index 51c7fb926ec..b8d53490a4a 100644
--- a/config/kernel.m4
+++ b/config/kernel.m4
@@ -127,6 +127,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
 	ZFS_AC_KERNEL_SRC_GENERIC_FILLATTR_USERNS
 	ZFS_AC_KERNEL_SRC_MKNOD
 	ZFS_AC_KERNEL_SRC_SYMLINK
+	ZFS_AC_KERNEL_SRC_BIO_MAX_SEGS
 
 	AC_MSG_CHECKING([for available kernel interfaces])
 	ZFS_LINUX_TEST_COMPILE_ALL([kabi])
@@ -227,6 +228,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
 	ZFS_AC_KERNEL_GENERIC_FILLATTR_USERNS
 	ZFS_AC_KERNEL_MKNOD
 	ZFS_AC_KERNEL_SYMLINK
+	ZFS_AC_KERNEL_BIO_MAX_SEGS
 ])
 
 dnl #
diff --git a/module/os/linux/zfs/vdev_disk.c b/module/os/linux/zfs/vdev_disk.c
index 08c33313407..aaaf4105979 100644
--- a/module/os/linux/zfs/vdev_disk.c
+++ b/module/os/linux/zfs/vdev_disk.c
@@ -593,9 +593,14 @@ __vdev_disk_physio(struct block_device *bdev, zio_t *zio,
 		}
 
 		/* bio_alloc() with __GFP_WAIT never returns NULL */
+#ifdef HAVE_BIO_MAX_SEGS
+		dr->dr_bio[i] = bio_alloc(GFP_NOIO, bio_max_segs(
+		    abd_nr_pages_off(zio->io_abd, bio_size, abd_offset)));
+#else
 		dr->dr_bio[i] = bio_alloc(GFP_NOIO,
 		    MIN(abd_nr_pages_off(zio->io_abd, bio_size, abd_offset),
 		    BIO_MAX_PAGES));
+#endif
 		if (unlikely(dr->dr_bio[i] == NULL)) {
 			vdev_disk_dio_free(dr);
 			return (SET_ERROR(ENOMEM));