aboutsummaryrefslogtreecommitdiffstats
path: root/config
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2021-12-01 16:07:12 -0800
committerTony Hutter <[email protected]>2021-12-06 12:22:57 -0800
commit16da688f2518526389e6bff8370684a1a2a1469c (patch)
treefe89dfc258cfb0d2503e21d1a79233e77d4c6cad /config
parente9ee57f682ab17d117f59038e726ba829f46247a (diff)
Linux 5.13 compat: retry zvol_open() when contended
Due to a possible lock inversion the zvol open call path on Linux needs to be able to retry in the case where the spa_namespace_lock cannot be acquired. For Linux 5.12 an older kernel this was accomplished by returning -ERESTARTSYS from zvol_open() to request that blkdev_get() drop the bdev->bd_mutex lock, reaquire it, then call the open callback again. However, as of the 5.13 kernel this behavior was removed. Therefore, for 5.12 and older kernels we preserved the existing retry logic, but for 5.13 and newer kernels we retry internally in zvol_open(). This should always succeed except in the case where a pool's vdev are layed on zvols, in which case it may fail. To handle this case vdev_disk_open() has been updated to retry when opening a device when -ERESTARTSYS is returned. Reviewed-by: Tony Hutter <[email protected]> Reviewed-by: Tony Nguyen <[email protected]> Signed-off-by: Brian Behlendorf <[email protected]> Issue #12301 Closes #12759
Diffstat (limited to 'config')
-rw-r--r--config/kernel-blkdev.m422
1 files changed, 22 insertions, 0 deletions
diff --git a/config/kernel-blkdev.m4 b/config/kernel-blkdev.m4
index 61e66421f..9c60e5dd4 100644
--- a/config/kernel-blkdev.m4
+++ b/config/kernel-blkdev.m4
@@ -294,6 +294,27 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BDEV_WHOLE], [
])
])
+dnl #
+dnl # 5.13 API change
+dnl # blkdev_get_by_path() no longer handles ERESTARTSYS
+dnl #
+dnl # Unfortunately we're forced to rely solely on the kernel version
+dnl # number in order to determine the expected behavior. This was an
+dnl # internal change to blkdev_get_by_dev(), see commit a8ed1a0607.
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_ERESTARTSYS], [
+ AC_MSG_CHECKING([whether blkdev_get_by_path() handles ERESTARTSYS])
+ AS_VERSION_COMPARE([$LINUX_VERSION], [5.13.0], [
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(HAVE_BLKDEV_GET_ERESTARTSYS, 1,
+ [blkdev_get_by_path() handles ERESTARTSYS])
+ ],[
+ AC_MSG_RESULT(no)
+ ],[
+ AC_MSG_RESULT(no)
+ ])
+])
+
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [
ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH
ZFS_AC_KERNEL_SRC_BLKDEV_PUT
@@ -318,4 +339,5 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [
ZFS_AC_KERNEL_BLKDEV_CHECK_DISK_CHANGE
ZFS_AC_KERNEL_BLKDEV_BDEV_CHECK_MEDIA_CHANGE
ZFS_AC_KERNEL_BLKDEV_BDEV_WHOLE
+ ZFS_AC_KERNEL_BLKDEV_GET_ERESTARTSYS
])