File 2fcab8795c7c493845bfa277d44bc443802000b8.patch of Package zfs08x

From 2fcab8795c7c493845bfa277d44bc443802000b8 Mon Sep 17 00:00:00 2001
From: Brian Behlendorf <behlendorf1@llnl.gov>
Date: Fri, 28 Feb 2020 08:58:39 -0800
Subject: [PATCH] Linux 5.5 compat: blkg_tryget()

Commit https://github.com/torvalds/linux/commit/9e8d42a0f accidentally
converted the static inline function blkg_tryget() to GPL-only for
kernels built with CONFIG_PREEMPT_RCU=y and CONFIG_BLK_CGROUP=y.

Resolve the build issue by providing our own equivalent functionality
when needed which uses rcu_read_lock_sched() internally as before.

Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #9745
Closes #10072
---
 config/kernel-blkg-tryget.m4 | 37 ++++++++++++++++++++++++++++++++++++
 config/kernel.m4             |  2 ++
 module/zfs/vdev_disk.c       | 32 ++++++++++++++++++++++++++++++-
 3 files changed, 70 insertions(+), 1 deletion(-)
 create mode 100644 config/kernel-blkg-tryget.m4

diff --git a/config/kernel-blkg-tryget.m4 b/config/kernel-blkg-tryget.m4
new file mode 100644
index 00000000000..fb831ca3b3e
--- /dev/null
+++ b/config/kernel-blkg-tryget.m4
@@ -0,0 +1,37 @@
+dnl #
+dnl # Linux 5.5 API,
+dnl #
+dnl # The Linux 5.5 kernel updated percpu_ref_tryget() which is inlined by
+dnl # blkg_tryget() to use rcu_read_lock() instead of rcu_read_lock_sched().
+dnl # As a side effect the function was converted to GPL-only.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKG_TRYGET], [
+	ZFS_LINUX_TEST_SRC([blkg_tryget], [
+		#include <linux/blk-cgroup.h>
+		#include <linux/bio.h>
+		#include <linux/fs.h>
+	],[
+		struct blkcg_gq blkg __attribute__ ((unused));
+		bool rc __attribute__ ((unused));
+		rc = blkg_tryget(&blkg);
+	], [], [$ZFS_META_LICENSE])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_BLKG_TRYGET], [
+	AC_MSG_CHECKING([whether blkg_tryget() is available])
+	ZFS_LINUX_TEST_RESULT([blkg_tryget], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_BLKG_TRYGET, 1, [blkg_tryget() is available])
+
+		AC_MSG_CHECKING([whether blkg_tryget() is GPL-only])
+		ZFS_LINUX_TEST_RESULT([blkg_tryget_license], [
+			AC_MSG_RESULT(no)
+		],[
+			AC_MSG_RESULT(yes)
+			AC_DEFINE(HAVE_BLKG_TRYGET_GPL_ONLY, 1,
+			    [blkg_tryget() GPL-only])
+		])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
diff --git a/config/kernel.m4 b/config/kernel.m4
index dce619729d4..bea6f9b1bbf 100644
--- a/config/kernel.m4
+++ b/config/kernel.m4
@@ -70,6 +70,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
 	ZFS_AC_KERNEL_SRC_BIO_BI_STATUS
 	ZFS_AC_KERNEL_SRC_BIO_RW_BARRIER
 	ZFS_AC_KERNEL_SRC_BIO_RW_DISCARD
+	ZFS_AC_KERNEL_SRC_BLKG_TRYGET
 	ZFS_AC_KERNEL_SRC_BLK_QUEUE_BDI
 	ZFS_AC_KERNEL_SRC_BLK_QUEUE_DISCARD
 	ZFS_AC_KERNEL_SRC_BLK_QUEUE_SECURE_ERASE
@@ -186,6 +187,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
 	ZFS_AC_KERNEL_BIO_BI_STATUS
 	ZFS_AC_KERNEL_BIO_RW_BARRIER
 	ZFS_AC_KERNEL_BIO_RW_DISCARD
+	ZFS_AC_KERNEL_BLKG_TRYGET
 	ZFS_AC_KERNEL_BLK_QUEUE_BDI
 	ZFS_AC_KERNEL_BLK_QUEUE_DISCARD
 	ZFS_AC_KERNEL_BLK_QUEUE_SECURE_ERASE
diff --git a/module/zfs/vdev_disk.c b/module/zfs/vdev_disk.c
index 661f0f1b727..8544bb8ffb6 100644
--- a/module/zfs/vdev_disk.c
+++ b/module/zfs/vdev_disk.c
@@ -473,6 +473,36 @@ vdev_submit_bio_impl(struct bio *bio)
 
 #ifdef HAVE_BIO_SET_DEV
 #if defined(CONFIG_BLK_CGROUP) && defined(HAVE_BIO_SET_DEV_GPL_ONLY)
+/*
+ * The Linux 5.5 kernel updated percpu_ref_tryget() which is inlined by
+ * blkg_tryget() to use rcu_read_lock() instead of rcu_read_lock_sched().
+ * As a side effect the function was converted to GPL-only.  Define our
+ * own version when needed which uses rcu_read_lock_sched().
+ */
+#if defined(HAVE_BLKG_TRYGET_GPL_ONLY)
+static inline bool
+vdev_blkg_tryget(struct blkcg_gq *blkg)
+{
+	struct percpu_ref *ref = &blkg->refcnt;
+	unsigned long __percpu *count;
+	bool rc;
+
+	rcu_read_lock_sched();
+
+	if (__ref_is_percpu(ref, &count)) {
+		this_cpu_inc(*count);
+		rc = true;
+	} else {
+		rc = atomic_long_inc_not_zero(&ref->count);
+	}
+
+	rcu_read_unlock_sched();
+
+	return (rc);
+}
+#elif defined(HAVE_BLKG_TRYGET)
+#define	vdev_blkg_tryget(bg)	blkg_tryget(bg)
+#endif
 /*
  * The Linux 5.0 kernel updated the bio_set_dev() macro so it calls the
  * GPL-only bio_associate_blkg() symbol thus inadvertently converting
@@ -487,7 +517,7 @@ vdev_bio_associate_blkg(struct bio *bio)
 	ASSERT3P(q, !=, NULL);
 	ASSERT3P(bio->bi_blkg, ==, NULL);
 
-	if (q->root_blkg && blkg_tryget(q->root_blkg))
+	if (q->root_blkg && vdev_blkg_tryget(q->root_blkg))
 		bio->bi_blkg = q->root_blkg;
 }
 #define	bio_associate_blkg vdev_bio_associate_blkg