summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColeman Kane <ckane@colemankane.org>2021-03-20 01:33:42 -0400
committerBrian Behlendorf <behlendorf1@llnl.gov>2021-05-20 09:04:27 -0700
commit77352db228c07ce8ba50478b9029820ca69c6c1b (patch)
treeabdcbf1559e2983b78c13b1e91523647d4372f38
parentf315d9a3ff3cc0b81c99dd9be5878a55d2e98d8e (diff)
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>
-rw-r--r--config/kernel-bio_max_segs.m423
-rw-r--r--config/kernel.m42
-rw-r--r--module/os/linux/zfs/vdev_disk.c5
3 files changed, 30 insertions, 0 deletions
diff --git a/config/kernel-bio_max_segs.m4 b/config/kernel-bio_max_segs.m4
new file mode 100644
index 000000000..a90d75455
--- /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 51c7fb926..b8d53490a 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 08c333134..aaaf41059 100644
--- a/module/os/linux/zfs/vdev_disk.c
+++ b/module/os/linux/zfs/vdev_disk.c
@@ -593,9 +593,14 @@ retry:
}
/* 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));