[Pkg-zfsonlinux-devel] Bug#1032237: bullseye-pu: zfs-linux/2.0.3-9+deb11u1

Aron Xu aron at debian.org
Thu Mar 2 07:33:46 GMT 2023


Package: release.debian.org
Severity: normal
Tags: bullseye
User: release.debian.org at packages.debian.org
Usertags: pu
X-Debbugs-CC: pkg-zfsonlinux-devel at alioth-lists.debian.net

Dear release team,

I would like to apply a few patches to address some stability issues in the
zfs-linux package in bullseye. All the patches are cherry-picked from upstream

2.0.x and 2.1.x stable branches.

* 0002-Initialize-ZIL-buffers.patch
 zio_crypt.c |    1 +
 1 file changed, 1 insertion(+)
* 0003-Fix-crash-in-zio_done-error-reporting.patch
 zio.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
* 0004-Fix-AVX512BW-Fletcher-code-on-AVX512-but-not-BW-mach.patch
 zfs_fletcher_avx512.c |    8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
* 0005-Fix-zfs_get_data-access-to-files-with-wrong-generati.patch
 cmd/ztest/ztest.c                  |    4 ++--
 include/sys/zil.h                  |    3 ++-
 include/sys/zvol_impl.h            |    4 ++--
 module/os/linux/zfs/zfs_vnops_os.c |   14 +++++++++++++-
 module/zfs/zfs_log.c               |    5 +++++
 module/zfs/zil.c                   |    3 ++-
 module/zfs/zvol.c                  |    3 ++-
 7 files changed, 28 insertions(+), 8 deletions(-)
* 0006-Linux-always-check-or-verify-return-of-igrab.patch
 include/os/linux/zfs/sys/zfs_znode_impl.h |    8 +++++++-
 module/os/linux/zfs/zfs_ctldir.c          |    3 ++-
 module/os/linux/zfs/zfs_vfsops.c          |    6 +++++-
 module/os/linux/zfs/zpl_inode.c           |    3 ++-
 4 files changed, 16 insertions(+), 4 deletions(-)
* 0007-Avoid-deadlock-when-removing-L2ARC-devices-under-I-O.patch
 arc.c |   17 ++++++-----------
 zio.c |    3 ---
 2 files changed, 6 insertions(+), 14 deletions(-)
* 0008-file-reference-counts-can-get-corrupted.patch
 include/sys/fm/util.h               |    5 +++--
 include/sys/zfs_file.h              |    6 ++++--
 include/sys/zfs_ioctl.h             |    2 +-
 include/sys/zfs_onexit.h            |    4 ++--
 lib/libzpool/kernel.c               |   20 +++++++++-----------
 module/os/freebsd/zfs/zfs_file_os.c |   19 ++++++-------------
 module/os/linux/zfs/zfs_file_os.c   |   28 +++++++---------------------
 module/zfs/fm.c                     |   20 ++++++++++++--------
 module/zfs/zfs_ioctl.c              |   71 ++++++++++++++++++++++++++++++++++-------------------------------------
 module/zfs/zfs_onexit.c             |   23 +++++++++++++----------
 10 files changed, 91 insertions(+), 107 deletions(-)
* 0009-libshare-nfs-don-t-leak-nfs_lock_fd-when-lock-fails.patch
 freebsd/nfs.c |   13 +++++++++----
 linux/nfs.c   |   13 +++++++++----
 2 files changed, 18 insertions(+), 8 deletions(-)

Regards,
Aron
-------------- next part --------------
diff -Nru zfs-linux-2.0.3/debian/changelog zfs-linux-2.0.3/debian/changelog
--- zfs-linux-2.0.3/debian/changelog	2021-07-01 13:44:20.000000000 +0800
+++ zfs-linux-2.0.3/debian/changelog	2023-03-02 00:15:02.000000000 +0800
@@ -1,3 +1,9 @@
+zfs-linux (2.0.3-9+deb11u1) bullseye; urgency=medium
+
+  * cherry-pick upstream fixes for stability issues
+
+ -- Aron Xu <aron at debian.org>  Thu, 02 Mar 2023 00:15:02 +0800
+
 zfs-linux (2.0.3-9) unstable; urgency=medium
 
   * Cherry-pick "Remove iov_iter_advance() for iter_write" (Closes: #989373)
diff -Nru zfs-linux-2.0.3/debian/patches/0002-Initialize-ZIL-buffers.patch zfs-linux-2.0.3/debian/patches/0002-Initialize-ZIL-buffers.patch
--- zfs-linux-2.0.3/debian/patches/0002-Initialize-ZIL-buffers.patch	1970-01-01 08:00:00.000000000 +0800
+++ zfs-linux-2.0.3/debian/patches/0002-Initialize-ZIL-buffers.patch	2023-02-27 15:29:01.000000000 +0800
@@ -0,0 +1,31 @@
+From e219935f10f6f604a3dafb4727715c3741480fd4 Mon Sep 17 00:00:00 2001
+From: Brian Behlendorf <behlendorf1 at llnl.gov>
+Date: Fri, 5 Mar 2021 14:45:13 -0800
+Subject: [PATCH] Initialize ZIL buffers
+
+When populating a ZIL destination buffer ensure it is always
+zeroed before its contents are constructed.
+
+Reviewed-by: Matthew Ahrens <mahrens at delphix.com>
+Reviewed-by: Tom Caputi <caputit1 at tcnj.edu>
+Signed-off-by: Brian Behlendorf <behlendorf1 at llnl.gov>
+Closes #11687
+---
+ module/os/linux/zfs/zio_crypt.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/module/os/linux/zfs/zio_crypt.c b/module/os/linux/zfs/zio_crypt.c
+index 96dabe55a..e2abc0ae2 100644
+--- a/module/os/linux/zfs/zio_crypt.c
++++ b/module/os/linux/zfs/zio_crypt.c
+@@ -1399,6 +1399,7 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
+ 		nr_src = 1;
+ 		nr_dst = 0;
+ 	}
++	bzero(dst, datalen);
+ 
+ 	/* find the start and end record of the log block */
+ 	zilc = (zil_chain_t *)src;
+-- 
+2.30.2
+
diff -Nru zfs-linux-2.0.3/debian/patches/0003-Fix-crash-in-zio_done-error-reporting.patch zfs-linux-2.0.3/debian/patches/0003-Fix-crash-in-zio_done-error-reporting.patch
--- zfs-linux-2.0.3/debian/patches/0003-Fix-crash-in-zio_done-error-reporting.patch	1970-01-01 08:00:00.000000000 +0800
+++ zfs-linux-2.0.3/debian/patches/0003-Fix-crash-in-zio_done-error-reporting.patch	2023-02-27 15:33:33.000000000 +0800
@@ -0,0 +1,49 @@
+From b996523d54c4650fdddf941f80643e76359b61b5 Mon Sep 17 00:00:00 2001
+From: Paul Zuchowski <31706010+PaulZ-98 at users.noreply.github.com>
+Date: Fri, 16 Apr 2021 14:00:53 -0400
+Subject: [PATCH] Fix crash in zio_done error reporting
+
+Fix NULL pointer dereference when reporting
+checksum error for gang block in zio_done.
+
+Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
+Signed-off-by: Paul Zuchowski <pzuchowski at datto.com>
+Closes #11872
+Closes #11896
+---
+ module/zfs/zio.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/module/zfs/zio.c b/module/zfs/zio.c
+index 052fa7ec3..fa1d3635d 100644
+--- a/module/zfs/zio.c
++++ b/module/zfs/zio.c
+@@ -25,6 +25,7 @@
+  * Copyright (c) 2017, Intel Corporation.
+  * Copyright (c) 2019, Klara Inc.
+  * Copyright (c) 2019, Allan Jude
++ * Copyright (c) 2021, Datto, Inc.
+  */
+ 
+ #include <sys/sysmacros.h>
+@@ -4499,7 +4500,7 @@ zio_done(zio_t *zio)
+ 			uint64_t asize = P2ROUNDUP(psize, align);
+ 			abd_t *adata = zio->io_abd;
+ 
+-			if (asize != psize) {
++			if (adata != NULL && asize != psize) {
+ 				adata = abd_alloc(asize, B_TRUE);
+ 				abd_copy(adata, zio->io_abd, psize);
+ 				abd_zero_off(adata, psize, asize - psize);
+@@ -4510,7 +4511,7 @@ zio_done(zio_t *zio)
+ 			zcr->zcr_finish(zcr, adata);
+ 			zfs_ereport_free_checksum(zcr);
+ 
+-			if (asize != psize)
++			if (adata != NULL && asize != psize)
+ 				abd_free(adata);
+ 		}
+ 	}
+-- 
+2.30.2
+
diff -Nru zfs-linux-2.0.3/debian/patches/0004-Fix-AVX512BW-Fletcher-code-on-AVX512-but-not-BW-mach.patch zfs-linux-2.0.3/debian/patches/0004-Fix-AVX512BW-Fletcher-code-on-AVX512-but-not-BW-mach.patch
--- zfs-linux-2.0.3/debian/patches/0004-Fix-AVX512BW-Fletcher-code-on-AVX512-but-not-BW-mach.patch	1970-01-01 08:00:00.000000000 +0800
+++ zfs-linux-2.0.3/debian/patches/0004-Fix-AVX512BW-Fletcher-code-on-AVX512-but-not-BW-mach.patch	2023-02-27 15:35:28.000000000 +0800
@@ -0,0 +1,46 @@
+From 7dc7f3f127d077588e56c921a7ff6281d5c50e89 Mon Sep 17 00:00:00 2001
+From: Romain Dolbeau <romain at dolbeau.org>
+Date: Mon, 26 Apr 2021 21:42:42 +0200
+Subject: [PATCH] Fix AVX512BW Fletcher code on AVX512-but-not-BW machines
+
+Introduce a specific valid function for avx512f+avx512bw (instead
+of checking only for avx512f).
+
+Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
+Reviewed-by: Adam Moss <c at yotes.com>
+Signed-off-by: Romain Dolbeau <romain at dolbeau.org>
+Closes #11937
+Closes #11938
+---
+ module/zcommon/zfs_fletcher_avx512.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/module/zcommon/zfs_fletcher_avx512.c b/module/zcommon/zfs_fletcher_avx512.c
+index 300ec4c1f..963f089b0 100644
+--- a/module/zcommon/zfs_fletcher_avx512.c
++++ b/module/zcommon/zfs_fletcher_avx512.c
+@@ -210,6 +210,12 @@ fletcher_4_avx512bw_byteswap(fletcher_4_ctx_t *ctx, const void *buf,
+ }
+ STACK_FRAME_NON_STANDARD(fletcher_4_avx512bw_byteswap);
+ 
++static boolean_t
++fletcher_4_avx512bw_valid(void)
++{
++	return (fletcher_4_avx512f_valid() && zfs_avx512bw_available());
++}
++
+ const fletcher_4_ops_t fletcher_4_avx512bw_ops = {
+ 	.init_native = fletcher_4_avx512f_init,
+ 	.fini_native = fletcher_4_avx512f_fini,
+@@ -217,7 +223,7 @@ const fletcher_4_ops_t fletcher_4_avx512bw_ops = {
+ 	.init_byteswap = fletcher_4_avx512f_init,
+ 	.fini_byteswap = fletcher_4_avx512f_fini,
+ 	.compute_byteswap = fletcher_4_avx512bw_byteswap,
+-	.valid = fletcher_4_avx512f_valid,
++	.valid = fletcher_4_avx512bw_valid,
+ 	.name = "avx512bw"
+ };
+ #endif
+-- 
+2.30.2
+
diff -Nru zfs-linux-2.0.3/debian/patches/0005-Fix-zfs_get_data-access-to-files-with-wrong-generati.patch zfs-linux-2.0.3/debian/patches/0005-Fix-zfs_get_data-access-to-files-with-wrong-generati.patch
--- zfs-linux-2.0.3/debian/patches/0005-Fix-zfs_get_data-access-to-files-with-wrong-generati.patch	1970-01-01 08:00:00.000000000 +0800
+++ zfs-linux-2.0.3/debian/patches/0005-Fix-zfs_get_data-access-to-files-with-wrong-generati.patch	2023-02-27 15:38:55.000000000 +0800
@@ -0,0 +1,178 @@
+From bfb29284901afacf24269079515163a55a57aebf Mon Sep 17 00:00:00 2001
+From: Chunwei Chen <tuxoko at gmail.com>
+Date: Fri, 19 Mar 2021 22:53:31 -0700
+Subject: [PATCH] Fix zfs_get_data access to files with wrong generation
+
+If TX_WRITE is create on a file, and the file is later deleted and a new
+directory is created on the same object id, it is possible that when
+zil_commit happens, zfs_get_data will be called on the new directory.
+This may result in panic as it tries to do range lock.
+
+This patch fixes this issue by record the generation number during
+zfs_log_write, so zfs_get_data can check if the object is valid.
+
+Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
+Signed-off-by: Chunwei Chen <david.chen at nutanix.com>
+Closes #10593
+Closes #11682
+---
+ cmd/ztest/ztest.c                  |  4 ++--
+ include/sys/zil.h                  |  3 ++-
+ include/sys/zvol_impl.h            |  4 ++--
+ module/os/linux/zfs/zfs_vnops_os.c | 14 +++++++++++++-
+ module/zfs/zfs_log.c               |  5 +++++
+ module/zfs/zil.c                   |  3 ++-
+ module/zfs/zvol.c                  |  3 ++-
+ 7 files changed, 28 insertions(+), 8 deletions(-)
+
+diff --git a/cmd/ztest/ztest.c b/cmd/ztest/ztest.c
+index 484637997..ba22ee8a4 100644
+--- a/cmd/ztest/ztest.c
++++ b/cmd/ztest/ztest.c
+@@ -2163,8 +2163,8 @@ ztest_get_done(zgd_t *zgd, int error)
+ }
+ 
+ static int
+-ztest_get_data(void *arg, lr_write_t *lr, char *buf, struct lwb *lwb,
+-    zio_t *zio)
++ztest_get_data(void *arg, uint64_t arg2, lr_write_t *lr, char *buf,
++    struct lwb *lwb, zio_t *zio)
+ {
+ 	ztest_ds_t *zd = arg;
+ 	objset_t *os = zd->zd_os;
+diff --git a/include/sys/zil.h b/include/sys/zil.h
+index ec89de38d..cefbccb32 100644
+--- a/include/sys/zil.h
++++ b/include/sys/zil.h
+@@ -399,6 +399,7 @@ typedef struct itx {
+ 	void		*itx_callback_data; /* User data for the callback */
+ 	size_t		itx_size;	/* allocated itx structure size */
+ 	uint64_t	itx_oid;	/* object id */
++	uint64_t	itx_gen;	/* gen number for zfs_get_data */
+ 	lr_t		itx_lr;		/* common part of log record */
+ 	/* followed by type-specific part of lr_xx_t and its immediate data */
+ } itx_t;
+@@ -467,7 +468,7 @@ typedef int zil_parse_blk_func_t(zilog_t *zilog, const blkptr_t *bp, void *arg,
+ typedef int zil_parse_lr_func_t(zilog_t *zilog, const lr_t *lr, void *arg,
+     uint64_t txg);
+ typedef int zil_replay_func_t(void *arg1, void *arg2, boolean_t byteswap);
+-typedef int zil_get_data_t(void *arg, lr_write_t *lr, char *dbuf,
++typedef int zil_get_data_t(void *arg, uint64_t arg2, lr_write_t *lr, char *dbuf,
+     struct lwb *lwb, zio_t *zio);
+ 
+ extern int zil_parse(zilog_t *zilog, zil_parse_blk_func_t *parse_blk_func,
+diff --git a/include/sys/zvol_impl.h b/include/sys/zvol_impl.h
+index 5137d2172..89fe59800 100644
+--- a/include/sys/zvol_impl.h
++++ b/include/sys/zvol_impl.h
+@@ -85,8 +85,8 @@ void zvol_log_truncate(zvol_state_t *zv, dmu_tx_t *tx, uint64_t off,
+     uint64_t len, boolean_t sync);
+ void zvol_log_write(zvol_state_t *zv, dmu_tx_t *tx, uint64_t offset,
+     uint64_t size, int sync);
+-int zvol_get_data(void *arg, lr_write_t *lr, char *buf, struct lwb *lwb,
+-    zio_t *zio);
++int zvol_get_data(void *arg, uint64_t arg2, lr_write_t *lr, char *buf,
++    struct lwb *lwb, zio_t *zio);
+ int zvol_init_impl(void);
+ void zvol_fini_impl(void);
+ void zvol_wait_close(zvol_state_t *zv);
+diff --git a/module/os/linux/zfs/zfs_vnops_os.c b/module/os/linux/zfs/zfs_vnops_os.c
+index ce0701763..a48659b28 100644
+--- a/module/os/linux/zfs/zfs_vnops_os.c
++++ b/module/os/linux/zfs/zfs_vnops_os.c
+@@ -521,7 +521,8 @@ static int zil_fault_io = 0;
+  * Get data to generate a TX_WRITE intent log record.
+  */
+ int
+-zfs_get_data(void *arg, lr_write_t *lr, char *buf, struct lwb *lwb, zio_t *zio)
++zfs_get_data(void *arg, uint64_t gen, lr_write_t *lr, char *buf,
++    struct lwb *lwb, zio_t *zio)
+ {
+ 	zfsvfs_t *zfsvfs = arg;
+ 	objset_t *os = zfsvfs->z_os;
+@@ -532,6 +533,7 @@ zfs_get_data(void *arg, lr_write_t *lr, char *buf, struct lwb *lwb, zio_t *zio)
+ 	dmu_buf_t *db;
+ 	zgd_t *zgd;
+ 	int error = 0;
++	uint64_t zp_gen;
+ 
+ 	ASSERT3P(lwb, !=, NULL);
+ 	ASSERT3P(zio, !=, NULL);
+@@ -550,6 +552,16 @@ zfs_get_data(void *arg, lr_write_t *lr, char *buf, struct lwb *lwb, zio_t *zio)
+ 		zfs_zrele_async(zp);
+ 		return (SET_ERROR(ENOENT));
+ 	}
++	/* check if generation number matches */
++	if (sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zfsvfs), &zp_gen,
++	    sizeof (zp_gen)) != 0) {
++		zfs_zrele_async(zp);
++		return (SET_ERROR(EIO));
++	}
++	if (zp_gen != gen) {
++		zfs_zrele_async(zp);
++		return (SET_ERROR(ENOENT));
++	}
+ 
+ 	zgd = kmem_zalloc(sizeof (zgd_t), KM_SLEEP);
+ 	zgd->zgd_lwb = lwb;
+diff --git a/module/zfs/zfs_log.c b/module/zfs/zfs_log.c
+index 4bb529f78..30d5c4821 100644
+--- a/module/zfs/zfs_log.c
++++ b/module/zfs/zfs_log.c
+@@ -540,6 +540,7 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
+ 	uint32_t blocksize = zp->z_blksz;
+ 	itx_wr_state_t write_state;
+ 	uintptr_t fsync_cnt;
++	uint64_t gen = 0;
+ 
+ 	if (zil_replaying(zilog, tx) || zp->z_unlinked ||
+ 	    zfs_xattr_owner_unlinked(zp)) {
+@@ -562,6 +563,9 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
+ 		(void) tsd_set(zfs_fsyncer_key, (void *)(fsync_cnt - 1));
+ 	}
+ 
++	(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(ZTOZSB(zp)), &gen,
++	    sizeof (gen));
++
+ 	while (resid) {
+ 		itx_t *itx;
+ 		lr_write_t *lr;
+@@ -609,6 +613,7 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
+ 		BP_ZERO(&lr->lr_blkptr);
+ 
+ 		itx->itx_private = ZTOZSB(zp);
++		itx->itx_gen = gen;
+ 
+ 		if (!(ioflag & (O_SYNC | O_DSYNC)) && (zp->z_sync_cnt == 0) &&
+ 		    (fsync_cnt == 0))
+diff --git a/module/zfs/zil.c b/module/zfs/zil.c
+index 632fef29b..8e620b409 100644
+--- a/module/zfs/zil.c
++++ b/module/zfs/zil.c
+@@ -1744,7 +1744,8 @@ cont:
+ 			 * completed after "lwb_write_zio" completed.
+ 			 */
+ 			error = zilog->zl_get_data(itx->itx_private,
+-			    lrwb, dbuf, lwb, lwb->lwb_write_zio);
++			    itx->itx_gen, lrwb, dbuf, lwb,
++			    lwb->lwb_write_zio);
+ 
+ 			if (error == EIO) {
+ 				txg_wait_synced(zilog->zl_dmu_pool, txg);
+diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c
+index 44f9832ce..b6609363f 100644
+--- a/module/zfs/zvol.c
++++ b/module/zfs/zvol.c
+@@ -673,7 +673,8 @@ zvol_get_done(zgd_t *zgd, int error)
+  * Get data to generate a TX_WRITE intent log record.
+  */
+ int
+-zvol_get_data(void *arg, lr_write_t *lr, char *buf, struct lwb *lwb, zio_t *zio)
++zvol_get_data(void *arg, uint64_t arg2, lr_write_t *lr, char *buf,
++    struct lwb *lwb, zio_t *zio)
+ {
+ 	zvol_state_t *zv = arg;
+ 	uint64_t offset = lr->lr_offset;
+-- 
+2.30.2
+
diff -Nru zfs-linux-2.0.3/debian/patches/0006-Linux-always-check-or-verify-return-of-igrab.patch zfs-linux-2.0.3/debian/patches/0006-Linux-always-check-or-verify-return-of-igrab.patch
--- zfs-linux-2.0.3/debian/patches/0006-Linux-always-check-or-verify-return-of-igrab.patch	1970-01-01 08:00:00.000000000 +0800
+++ zfs-linux-2.0.3/debian/patches/0006-Linux-always-check-or-verify-return-of-igrab.patch	2023-02-27 15:40:49.000000000 +0800
@@ -0,0 +1,88 @@
+From ac6f3321545a0b82b6b84e7fec6cf62e619d824b Mon Sep 17 00:00:00 2001
+From: "Adam D. Moss" <c at yotes.com>
+Date: Tue, 16 Mar 2021 16:33:34 -0700
+Subject: [PATCH] Linux: always check or verify return of igrab()
+
+zhold() wraps igrab() on Linux, and igrab() may fail when the inode
+is in the process of being deleted.  This means zhold() must only be
+called when a reference exists and therefore it cannot be deleted.
+This is the case for all existing consumers so add a VERIFY and a
+comment explaining this requirement.
+
+Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
+Signed-off-by: Adam Moss <c at yotes.com>
+Closes #11704
+---
+ include/os/linux/zfs/sys/zfs_znode_impl.h | 8 +++++++-
+ module/os/linux/zfs/zfs_ctldir.c          | 3 ++-
+ module/os/linux/zfs/zfs_vfsops.c          | 6 +++++-
+ module/os/linux/zfs/zpl_inode.c           | 3 ++-
+ 4 files changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/include/os/linux/zfs/sys/zfs_znode_impl.h b/include/os/linux/zfs/sys/zfs_znode_impl.h
+index f17b8eb67..79049df69 100644
+--- a/include/os/linux/zfs/sys/zfs_znode_impl.h
++++ b/include/os/linux/zfs/sys/zfs_znode_impl.h
+@@ -73,7 +73,13 @@ extern "C" {
+ #define	zn_has_cached_data(zp)	((zp)->z_is_mapped)
+ #define	zn_rlimit_fsize(zp, uio, td)	(0)
+ 
+-#define	zhold(zp)	igrab(ZTOI((zp)))
++/*
++ * zhold() wraps igrab() on Linux, and igrab() may fail when the
++ * inode is in the process of being deleted.  As zhold() must only be
++ * called when a ref already exists - so the inode cannot be
++ * mid-deletion - we VERIFY() this.
++ */
++#define	zhold(zp)	VERIFY3P(igrab(ZTOI((zp))), !=, NULL)
+ #define	zrele(zp)	iput(ZTOI((zp)))
+ 
+ /* Called on entry to each ZFS inode and vfs operation. */
+diff --git a/module/os/linux/zfs/zfs_ctldir.c b/module/os/linux/zfs/zfs_ctldir.c
+index a1668e46e..d33188f38 100644
+--- a/module/os/linux/zfs/zfs_ctldir.c
++++ b/module/os/linux/zfs/zfs_ctldir.c
+@@ -590,7 +590,8 @@ struct inode *
+ zfsctl_root(znode_t *zp)
+ {
+ 	ASSERT(zfs_has_ctldir(zp));
+-	igrab(ZTOZSB(zp)->z_ctldir);
++	/* Must have an existing ref, so igrab() cannot return NULL */
++	VERIFY3P(igrab(ZTOZSB(zp)->z_ctldir), !=, NULL);
+ 	return (ZTOZSB(zp)->z_ctldir);
+ }
+ 
+diff --git a/module/os/linux/zfs/zfs_vfsops.c b/module/os/linux/zfs/zfs_vfsops.c
+index 165c1218a..44f575d8a 100644
+--- a/module/os/linux/zfs/zfs_vfsops.c
++++ b/module/os/linux/zfs/zfs_vfsops.c
+@@ -1734,7 +1734,11 @@ zfs_vget(struct super_block *sb, struct inode **ipp, fid_t *fidp)
+ 			VERIFY(zfsctl_root_lookup(*ipp, "snapshot", ipp,
+ 			    0, kcred, NULL, NULL) == 0);
+ 		} else {
+-			igrab(*ipp);
++			/*
++			 * Must have an existing ref, so igrab()
++			 * cannot return NULL
++			 */
++			VERIFY3P(igrab(*ipp), !=, NULL);
+ 		}
+ 		ZFS_EXIT(zfsvfs);
+ 		return (0);
+diff --git a/module/os/linux/zfs/zpl_inode.c b/module/os/linux/zfs/zpl_inode.c
+index ab0373ef9..bd1f60516 100644
+--- a/module/os/linux/zfs/zpl_inode.c
++++ b/module/os/linux/zfs/zpl_inode.c
+@@ -639,7 +639,8 @@ zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
+ 
+ 	crhold(cr);
+ 	ip->i_ctime = current_time(ip);
+-	igrab(ip); /* Use ihold() if available */
++	/* Must have an existing ref, so igrab() cannot return NULL */
++	VERIFY3P(igrab(ip), !=, NULL);
+ 
+ 	cookie = spl_fstrans_mark();
+ 	error = -zfs_link(ITOZ(dir), ITOZ(ip), dname(dentry), cr, 0);
+-- 
+2.30.2
+
diff -Nru zfs-linux-2.0.3/debian/patches/0007-Avoid-deadlock-when-removing-L2ARC-devices-under-I-O.patch zfs-linux-2.0.3/debian/patches/0007-Avoid-deadlock-when-removing-L2ARC-devices-under-I-O.patch
--- zfs-linux-2.0.3/debian/patches/0007-Avoid-deadlock-when-removing-L2ARC-devices-under-I-O.patch	1970-01-01 08:00:00.000000000 +0800
+++ zfs-linux-2.0.3/debian/patches/0007-Avoid-deadlock-when-removing-L2ARC-devices-under-I-O.patch	2023-02-27 15:42:41.000000000 +0800
@@ -0,0 +1,76 @@
+From 87d93731e7f60f71238ab3820f18ab1ee13c9ea0 Mon Sep 17 00:00:00 2001
+From: George Amanakis <gamanakis at gmail.com>
+Date: Thu, 17 Jun 2021 03:17:42 +0300
+Subject: [PATCH] Avoid deadlock when removing L2ARC devices under I/O
+
+In case we have I/O and try to remove an L2ARC device a deadlock might
+occur. arc_read()->zio_read()->zfs_blkptr_verify() waits for SCL_VDEV
+to be dropped while holding the hash_lock. However, spa_l2cache_load()
+holds SCL_ALL and waits for the hash_lock in l2arc_evict().
+
+Fix this by moving zfs_blkptr_verify() to the top top arc_read() before
+the hash_lock is taken. Verify the block pointer and return a checksum
+error if damaged rather than halting the system, by using
+BLK_VERIFY_LOG instead of BLK_VERIFY_HALT.
+
+Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
+Reviewed-by: Mark Maybee <mark.maybee at delphix.com>
+Signed-off-by: George Amanakis <gamanakis at gmail.com>
+Closes #12054
+---
+ module/zfs/arc.c | 17 ++++++-----------
+ module/zfs/zio.c |  3 ---
+ 2 files changed, 6 insertions(+), 14 deletions(-)
+
+diff --git a/module/zfs/arc.c b/module/zfs/arc.c
+index b6b0f8587..e70b37d4b 100644
+--- a/module/zfs/arc.c
++++ b/module/zfs/arc.c
+@@ -5835,6 +5835,12 @@ top:
+ 		 * Embedded BP's have no DVA and require no I/O to "read".
+ 		 * Create an anonymous arc buf to back it.
+ 		 */
++		if (!zfs_blkptr_verify(spa, bp, zio_flags &
++		    ZIO_FLAG_CONFIG_WRITER, BLK_VERIFY_LOG)) {
++			rc = SET_ERROR(ECKSUM);
++			goto out;
++		}
++
+ 		hdr = buf_hash_find(guid, bp, &hash_lock);
+ 	}
+ 
+@@ -6003,17 +6009,6 @@ top:
+ 			goto out;
+ 		}
+ 
+-		/*
+-		 * Gracefully handle a damaged logical block size as a
+-		 * checksum error.
+-		 */
+-		if (lsize > spa_maxblocksize(spa)) {
+-			rc = SET_ERROR(ECKSUM);
+-			if (hash_lock != NULL)
+-				mutex_exit(hash_lock);
+-			goto out;
+-		}
+-
+ 		if (hdr == NULL) {
+ 			/*
+ 			 * This block is not in the cache or it has
+diff --git a/module/zfs/zio.c b/module/zfs/zio.c
+index 05bc2d63a..dfc3c71c1 100644
+--- a/module/zfs/zio.c
++++ b/module/zfs/zio.c
+@@ -1106,9 +1106,6 @@ zio_read(zio_t *pio, spa_t *spa, const blkptr_t *bp,
+ {
+ 	zio_t *zio;
+ 
+-	(void) zfs_blkptr_verify(spa, bp, flags & ZIO_FLAG_CONFIG_WRITER,
+-	    BLK_VERIFY_HALT);
+-
+ 	zio = zio_create(pio, spa, BP_PHYSICAL_BIRTH(bp), bp,
+ 	    data, size, size, done, private,
+ 	    ZIO_TYPE_READ, priority, flags, NULL, 0, zb,
+-- 
+2.30.2
+
diff -Nru zfs-linux-2.0.3/debian/patches/0008-file-reference-counts-can-get-corrupted.patch zfs-linux-2.0.3/debian/patches/0008-file-reference-counts-can-get-corrupted.patch
--- zfs-linux-2.0.3/debian/patches/0008-file-reference-counts-can-get-corrupted.patch	1970-01-01 08:00:00.000000000 +0800
+++ zfs-linux-2.0.3/debian/patches/0008-file-reference-counts-can-get-corrupted.patch	2023-02-27 15:43:46.000000000 +0800
@@ -0,0 +1,556 @@
+From 158e1b6d59a47b3329dfb820e7208ed22f963dc5 Mon Sep 17 00:00:00 2001
+From: George Wilson <george.wilson at delphix.com>
+Date: Sat, 10 Jul 2021 20:00:37 -0500
+Subject: [PATCH] file reference counts can get corrupted
+
+Callers of zfs_file_get and zfs_file_put can corrupt the reference
+counts for the file structure resulting in a panic or a soft lockup.
+When zfs send/recv runs, it will add a reference count to the
+open file, and begin to send or recv the stream. If the file descriptor
+is closed, then when dmu_recv_stream() or dmu_send() return we will
+call zfs_file_put to remove the reference we placed on the file
+structure. Unfortunately, because zfs_file_put() uses the file
+descriptor to lookup the file structure, it may end up finding that
+the file descriptor table no longer contains the file struct, thus
+leaking the file structure. Or it might end up finding a file
+descriptor for a different file and blindly updating its reference
+counts. Other failure modes probably exists.
+
+This change reworks the zfs_file_[get|put] interface to not rely
+on the file descriptor but instead pass the zfs_file_t pointer around.
+
+Reviewed-by: Matthew Ahrens <mahrens at delphix.com>
+Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
+Reviewed-by: Mark Maybee <mark.maybee at delphix.com>
+Reviewed-by: Ryan Moeller <ryan at iXsystems.com>
+Co-authored-by: Allan Jude <allan at klarasystems.com>
+Signed-off-by: George Wilson <gwilson at delphix.com>
+External-issue: DLPX-76119
+Closes #12299
+---
+ include/sys/fm/util.h               |  5 +-
+ include/sys/zfs_file.h              |  6 ++-
+ include/sys/zfs_ioctl.h             |  2 +-
+ include/sys/zfs_onexit.h            |  4 +-
+ lib/libzpool/kernel.c               | 20 ++++----
+ module/os/freebsd/zfs/zfs_file_os.c | 19 +++-----
+ module/os/linux/zfs/zfs_file_os.c   | 28 +++---------
+ module/zfs/fm.c                     | 20 ++++----
+ module/zfs/zfs_ioctl.c              | 71 ++++++++++++++---------------
+ module/zfs/zfs_onexit.c             | 23 ++++++----
+ 10 files changed, 91 insertions(+), 107 deletions(-)
+
+diff --git a/include/sys/fm/util.h b/include/sys/fm/util.h
+index ea8c61a8b..8fa82b7b6 100644
+--- a/include/sys/fm/util.h
++++ b/include/sys/fm/util.h
+@@ -31,6 +31,7 @@ extern "C" {
+ #endif
+ 
+ #include <sys/nvpair.h>
++#include <sys/zfs_file.h>
+ 
+ /*
+  * Shared user/kernel definitions for class length, error channel name,
+@@ -96,8 +97,8 @@ extern void fm_nvprint(nvlist_t *);
+ extern void zfs_zevent_post_cb(nvlist_t *nvl, nvlist_t *detector);
+ extern int zfs_zevent_post(nvlist_t *, nvlist_t *, zevent_cb_t *);
+ extern void zfs_zevent_drain_all(int *);
+-extern int zfs_zevent_fd_hold(int, minor_t *, zfs_zevent_t **);
+-extern void zfs_zevent_fd_rele(int);
++extern zfs_file_t *zfs_zevent_fd_hold(int, minor_t *, zfs_zevent_t **);
++extern void zfs_zevent_fd_rele(zfs_file_t *);
+ extern int zfs_zevent_next(zfs_zevent_t *, nvlist_t **, uint64_t *, uint64_t *);
+ extern int zfs_zevent_wait(zfs_zevent_t *);
+ extern int zfs_zevent_seek(zfs_zevent_t *, uint64_t);
+diff --git a/include/sys/zfs_file.h b/include/sys/zfs_file.h
+index d117933a6..02cd1a6f0 100644
+--- a/include/sys/zfs_file.h
++++ b/include/sys/zfs_file.h
+@@ -22,6 +22,8 @@
+ #ifndef	_SYS_ZFS_FILE_H
+ #define	_SYS_ZFS_FILE_H
+ 
++#include <sys/zfs_context.h>
++
+ #ifndef _KERNEL
+ typedef struct zfs_file {
+ 	int f_fd;
+@@ -55,8 +57,8 @@ int zfs_file_fallocate(zfs_file_t *fp, int mode, loff_t offset, loff_t len);
+ loff_t zfs_file_off(zfs_file_t *fp);
+ int zfs_file_unlink(const char *);
+ 
+-int zfs_file_get(int fd, zfs_file_t **fp);
+-void zfs_file_put(int fd);
++zfs_file_t *zfs_file_get(int fd);
++void zfs_file_put(zfs_file_t *fp);
+ void *zfs_file_private(zfs_file_t *fp);
+ 
+ #endif /* _SYS_ZFS_FILE_H */
+diff --git a/include/sys/zfs_ioctl.h b/include/sys/zfs_ioctl.h
+index 8834c5299..1ca3f211b 100644
+--- a/include/sys/zfs_ioctl.h
++++ b/include/sys/zfs_ioctl.h
+@@ -566,7 +566,7 @@ typedef struct zfsdev_state {
+ } zfsdev_state_t;
+ 
+ extern void *zfsdev_get_state(minor_t minor, enum zfsdev_state_type which);
+-extern int zfsdev_getminor(int fd, minor_t *minorp);
++extern int zfsdev_getminor(zfs_file_t *fp, minor_t *minorp);
+ extern minor_t zfsdev_minor_alloc(void);
+ 
+ extern uint_t zfs_fsyncer_key;
+diff --git a/include/sys/zfs_onexit.h b/include/sys/zfs_onexit.h
+index 0fab23ff8..fd3030e3a 100644
+--- a/include/sys/zfs_onexit.h
++++ b/include/sys/zfs_onexit.h
+@@ -51,8 +51,8 @@ extern void zfs_onexit_destroy(zfs_onexit_t *zo);
+ 
+ #endif
+ 
+-extern int zfs_onexit_fd_hold(int fd, minor_t *minorp);
+-extern void zfs_onexit_fd_rele(int fd);
++extern zfs_file_t *zfs_onexit_fd_hold(int fd, minor_t *minorp);
++extern void zfs_onexit_fd_rele(zfs_file_t *);
+ extern int zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data,
+     uint64_t *action_handle);
+ 
+diff --git a/lib/libzpool/kernel.c b/lib/libzpool/kernel.c
+index ca3578993..5abeb6779 100644
+--- a/lib/libzpool/kernel.c
++++ b/lib/libzpool/kernel.c
+@@ -966,16 +966,16 @@ kmem_asprintf(const char *fmt, ...)
+ }
+ 
+ /* ARGSUSED */
+-int
++zfs_file_t *
+ zfs_onexit_fd_hold(int fd, minor_t *minorp)
+ {
+ 	*minorp = 0;
+-	return (0);
++	return (NULL);
+ }
+ 
+ /* ARGSUSED */
+ void
+-zfs_onexit_fd_rele(int fd)
++zfs_onexit_fd_rele(zfs_file_t *fp)
+ {
+ }
+ 
+@@ -1385,28 +1385,26 @@ zfs_file_unlink(const char *path)
+  * Get reference to file pointer
+  *
+  * fd - input file descriptor
+- * fpp - pointer to file pointer
+  *
+- * Returns 0 on success EBADF on failure.
++ * Returns pointer to file struct or NULL.
+  * Unsupported in user space.
+  */
+-int
+-zfs_file_get(int fd, zfs_file_t **fpp)
++zfs_file_t *
++zfs_file_get(int fd)
+ {
+ 	abort();
+ 
+-	return (EOPNOTSUPP);
++	return (NULL);
+ }
+-
+ /*
+  * Drop reference to file pointer
+  *
+- * fd - input file descriptor
++ * fp - pointer to file struct
+  *
+  * Unsupported in user space.
+  */
+ void
+-zfs_file_put(int fd)
++zfs_file_put(zfs_file_t *fp)
+ {
+ 	abort();
+ }
+diff --git a/module/os/freebsd/zfs/zfs_file_os.c b/module/os/freebsd/zfs/zfs_file_os.c
+index bfdc4159a..a8c774a4e 100644
+--- a/module/os/freebsd/zfs/zfs_file_os.c
++++ b/module/os/freebsd/zfs/zfs_file_os.c
+@@ -241,28 +241,21 @@ zfs_file_fsync(zfs_file_t *fp, int flags)
+ 	return (zfs_vop_fsync(fp->f_vnode));
+ }
+ 
+-int
+-zfs_file_get(int fd, zfs_file_t **fpp)
++zfs_file_t *
++zfs_file_get(int fd)
+ {
+ 	struct file *fp;
+ 
+ 	if (fget(curthread, fd, &cap_no_rights, &fp))
+-		return (SET_ERROR(EBADF));
++		return (NULL);
+ 
+-	*fpp = fp;
+-	return (0);
++	return (fp);
+ }
+ 
+ void
+-zfs_file_put(int fd)
++zfs_file_put(zfs_file_t *fp)
+ {
+-	struct file *fp;
+-
+-	/* No CAP_ rights required, as we're only releasing. */
+-	if (fget(curthread, fd, &cap_no_rights, &fp) == 0) {
+-		fdrop(fp, curthread);
+-		fdrop(fp, curthread);
+-	}
++	fdrop(fp, curthread);
+ }
+ 
+ loff_t
+diff --git a/module/os/linux/zfs/zfs_file_os.c b/module/os/linux/zfs/zfs_file_os.c
+index 99c6ffc95..fe522d257 100644
+--- a/module/os/linux/zfs/zfs_file_os.c
++++ b/module/os/linux/zfs/zfs_file_os.c
+@@ -405,36 +405,22 @@ zfs_file_unlink(const char *path)
+  * Get reference to file pointer
+  *
+  * fd - input file descriptor
+- * fpp - pointer to file pointer
+  *
+- * Returns 0 on success EBADF on failure.
++ * Returns pointer to file struct or NULL
+  */
+-int
+-zfs_file_get(int fd, zfs_file_t **fpp)
++zfs_file_t *
++zfs_file_get(int fd)
+ {
+-	zfs_file_t *fp;
+-
+-	fp = fget(fd);
+-	if (fp == NULL)
+-		return (EBADF);
+-
+-	*fpp = fp;
+-
+-	return (0);
++	return (fget(fd));
+ }
+ 
+ /*
+  * Drop reference to file pointer
+  *
+- * fd - input file descriptor
++ * fp - input file struct pointer
+  */
+ void
+-zfs_file_put(int fd)
++zfs_file_put(zfs_file_t *fp)
+ {
+-	struct file *fp;
+-
+-	if ((fp = fget(fd)) != NULL) {
+-		fput(fp);
+-		fput(fp);
+-	}
++	fput(fp);
+ }
+diff --git a/module/zfs/fm.c b/module/zfs/fm.c
+index 6ad4f582e..e868798c8 100644
+--- a/module/zfs/fm.c
++++ b/module/zfs/fm.c
+@@ -586,25 +586,29 @@ zfs_zevent_minor_to_state(minor_t minor, zfs_zevent_t **ze)
+ 	return (0);
+ }
+ 
+-int
++zfs_file_t *
+ zfs_zevent_fd_hold(int fd, minor_t *minorp, zfs_zevent_t **ze)
+ {
+-	int error;
++	zfs_file_t *fp = zfs_file_get(fd);
++	if (fp == NULL)
++		return (NULL);
+ 
+-	error = zfsdev_getminor(fd, minorp);
++	int error = zfsdev_getminor(fp, minorp);
+ 	if (error == 0)
+ 		error = zfs_zevent_minor_to_state(*minorp, ze);
+ 
+-	if (error)
+-		zfs_zevent_fd_rele(fd);
++	if (error) {
++		zfs_zevent_fd_rele(fp);
++		fp = NULL;
++	}
+ 
+-	return (error);
++	return (fp);
+ }
+ 
+ void
+-zfs_zevent_fd_rele(int fd)
++zfs_zevent_fd_rele(zfs_file_t *fp)
+ {
+-	zfs_file_put(fd);
++	zfs_file_put(fp);
+ }
+ 
+ /*
+diff --git a/module/zfs/zfs_ioctl.c b/module/zfs/zfs_ioctl.c
+index 9f670d50a..6f629c984 100644
+--- a/module/zfs/zfs_ioctl.c
++++ b/module/zfs/zfs_ioctl.c
+@@ -4834,8 +4834,8 @@ zfs_ioc_recv_impl(char *tofs, char *tosnap, char *origin, nvlist_t *recvprops,
+ 	*errors = fnvlist_alloc();
+ 	off = 0;
+ 
+-	if ((error = zfs_file_get(input_fd, &input_fp)))
+-		return (error);
++	if ((input_fp = zfs_file_get(input_fd)) == NULL)
++		return (SET_ERROR(EBADF));
+ 
+ 	noff = off = zfs_file_off(input_fp);
+ 	error = dmu_recv_begin(tofs, tosnap, begin_record, force,
+@@ -5115,7 +5115,7 @@ zfs_ioc_recv_impl(char *tofs, char *tosnap, char *origin, nvlist_t *recvprops,
+ 		nvlist_free(inheritprops);
+ 	}
+ out:
+-	zfs_file_put(input_fd);
++	zfs_file_put(input_fp);
+ 	nvlist_free(origrecvd);
+ 	nvlist_free(origprops);
+ 
+@@ -5445,8 +5445,8 @@ zfs_ioc_send(zfs_cmd_t *zc)
+ 		zfs_file_t *fp;
+ 		dmu_send_outparams_t out = {0};
+ 
+-		if ((error = zfs_file_get(zc->zc_cookie, &fp)))
+-			return (error);
++		if ((fp = zfs_file_get(zc->zc_cookie)) == NULL)
++			return (SET_ERROR(EBADF));
+ 
+ 		off = zfs_file_off(fp);
+ 		out.dso_outfunc = dump_bytes;
+@@ -5456,7 +5456,7 @@ zfs_ioc_send(zfs_cmd_t *zc)
+ 		    zc->zc_fromobj, embedok, large_block_ok, compressok,
+ 		    rawok, savedok, zc->zc_cookie, &off, &out);
+ 
+-		zfs_file_put(zc->zc_cookie);
++		zfs_file_put(fp);
+ 	}
+ 	return (error);
+ }
+@@ -6020,25 +6020,24 @@ zfs_ioc_tmp_snapshot(zfs_cmd_t *zc)
+ {
+ 	char *snap_name;
+ 	char *hold_name;
+-	int error;
+ 	minor_t minor;
+ 
+-	error = zfs_onexit_fd_hold(zc->zc_cleanup_fd, &minor);
+-	if (error != 0)
+-		return (error);
++	zfs_file_t *fp = zfs_onexit_fd_hold(zc->zc_cleanup_fd, &minor);
++	if (fp == NULL)
++		return (SET_ERROR(EBADF));
+ 
+ 	snap_name = kmem_asprintf("%s-%016llx", zc->zc_value,
+ 	    (u_longlong_t)ddi_get_lbolt64());
+ 	hold_name = kmem_asprintf("%%%s", zc->zc_value);
+ 
+-	error = dsl_dataset_snapshot_tmp(zc->zc_name, snap_name, minor,
++	int error = dsl_dataset_snapshot_tmp(zc->zc_name, snap_name, minor,
+ 	    hold_name);
+ 	if (error == 0)
+ 		(void) strlcpy(zc->zc_value, snap_name,
+ 		    sizeof (zc->zc_value));
+ 	kmem_strfree(snap_name);
+ 	kmem_strfree(hold_name);
+-	zfs_onexit_fd_rele(zc->zc_cleanup_fd);
++	zfs_onexit_fd_rele(fp);
+ 	return (error);
+ }
+ 
+@@ -6058,13 +6057,13 @@ zfs_ioc_diff(zfs_cmd_t *zc)
+ 	offset_t off;
+ 	int error;
+ 
+-	if ((error = zfs_file_get(zc->zc_cookie, &fp)))
+-		return (error);
++	if ((fp = zfs_file_get(zc->zc_cookie)) == NULL)
++		return (SET_ERROR(EBADF));
+ 
+ 	off = zfs_file_off(fp);
+ 	error = dmu_diff(zc->zc_name, zc->zc_value, fp, &off);
+ 
+-	zfs_file_put(zc->zc_cookie);
++	zfs_file_put(fp);
+ 
+ 	return (error);
+ }
+@@ -6100,6 +6099,7 @@ zfs_ioc_hold(const char *pool, nvlist_t *args, nvlist_t *errlist)
+ 	int cleanup_fd = -1;
+ 	int error;
+ 	minor_t minor = 0;
++	zfs_file_t *fp = NULL;
+ 
+ 	holds = fnvlist_lookup_nvlist(args, "holds");
+ 
+@@ -6117,14 +6117,16 @@ zfs_ioc_hold(const char *pool, nvlist_t *args, nvlist_t *errlist)
+ 	}
+ 
+ 	if (nvlist_lookup_int32(args, "cleanup_fd", &cleanup_fd) == 0) {
+-		error = zfs_onexit_fd_hold(cleanup_fd, &minor);
+-		if (error != 0)
+-			return (SET_ERROR(error));
++		fp = zfs_onexit_fd_hold(cleanup_fd, &minor);
++		if (fp == NULL)
++			return (SET_ERROR(EBADF));
+ 	}
+ 
+ 	error = dsl_dataset_user_hold(holds, minor, errlist);
+-	if (minor != 0)
+-		zfs_onexit_fd_rele(cleanup_fd);
++	if (fp != NULL) {
++		ASSERT3U(minor, !=, 0);
++		zfs_onexit_fd_rele(fp);
++	}
+ 	return (SET_ERROR(error));
+ }
+ 
+@@ -6187,9 +6189,9 @@ zfs_ioc_events_next(zfs_cmd_t *zc)
+ 	uint64_t dropped = 0;
+ 	int error;
+ 
+-	error = zfs_zevent_fd_hold(zc->zc_cleanup_fd, &minor, &ze);
+-	if (error != 0)
+-		return (error);
++	zfs_file_t *fp = zfs_zevent_fd_hold(zc->zc_cleanup_fd, &minor, &ze);
++	if (fp == NULL)
++		return (SET_ERROR(EBADF));
+ 
+ 	do {
+ 		error = zfs_zevent_next(ze, &event,
+@@ -6211,7 +6213,7 @@ zfs_ioc_events_next(zfs_cmd_t *zc)
+ 			break;
+ 	} while (1);
+ 
+-	zfs_zevent_fd_rele(zc->zc_cleanup_fd);
++	zfs_zevent_fd_rele(fp);
+ 
+ 	return (error);
+ }
+@@ -6243,12 +6245,12 @@ zfs_ioc_events_seek(zfs_cmd_t *zc)
+ 	minor_t minor;
+ 	int error;
+ 
+-	error = zfs_zevent_fd_hold(zc->zc_cleanup_fd, &minor, &ze);
+-	if (error != 0)
+-		return (error);
++	zfs_file_t *fp = zfs_zevent_fd_hold(zc->zc_cleanup_fd, &minor, &ze);
++	if (fp == NULL)
++		return (SET_ERROR(EBADF));
+ 
+ 	error = zfs_zevent_seek(ze, zc->zc_guid);
+-	zfs_zevent_fd_rele(zc->zc_cleanup_fd);
++	zfs_zevent_fd_rele(fp);
+ 
+ 	return (error);
+ }
+@@ -6432,8 +6434,8 @@ zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
+ 
+ 	(void) nvlist_lookup_string(innvl, "redactbook", &redactbook);
+ 
+-	if ((error = zfs_file_get(fd, &fp)))
+-		return (error);
++	if ((fp = zfs_file_get(fd)) == NULL)
++		return (SET_ERROR(EBADF));
+ 
+ 	off = zfs_file_off(fp);
+ 
+@@ -6445,7 +6447,7 @@ zfs_ioc_send_new(const char *snapname, nvlist_t *innvl, nvlist_t *outnvl)
+ 	    compressok, rawok, savedok, resumeobj, resumeoff,
+ 	    redactbook, fd, &off, &out);
+ 
+-	zfs_file_put(fd);
++	zfs_file_put(fp);
+ 	return (error);
+ }
+ 
+@@ -7318,17 +7320,12 @@ pool_status_check(const char *name, zfs_ioc_namecheck_t type,
+ }
+ 
+ int
+-zfsdev_getminor(int fd, minor_t *minorp)
++zfsdev_getminor(zfs_file_t *fp, minor_t *minorp)
+ {
+ 	zfsdev_state_t *zs, *fpd;
+-	zfs_file_t *fp;
+-	int rc;
+ 
+ 	ASSERT(!MUTEX_HELD(&zfsdev_state_lock));
+ 
+-	if ((rc = zfs_file_get(fd, &fp)))
+-		return (rc);
+-
+ 	fpd = zfs_file_private(fp);
+ 	if (fpd == NULL)
+ 		return (SET_ERROR(EBADF));
+diff --git a/module/zfs/zfs_onexit.c b/module/zfs/zfs_onexit.c
+index 2a1332e71..7c56dd9c9 100644
+--- a/module/zfs/zfs_onexit.c
++++ b/module/zfs/zfs_onexit.c
+@@ -107,30 +107,33 @@ zfs_onexit_destroy(zfs_onexit_t *zo)
+  * of this function must call zfs_onexit_fd_rele() when they're finished
+  * using the minor number.
+  */
+-int
++zfs_file_t *
+ zfs_onexit_fd_hold(int fd, minor_t *minorp)
+ {
+ 	zfs_onexit_t *zo = NULL;
+-	int error;
+ 
+-	error = zfsdev_getminor(fd, minorp);
++	zfs_file_t *fp = zfs_file_get(fd);
++	if (fp == NULL)
++		return (NULL);
++
++	int error = zfsdev_getminor(fp, minorp);
+ 	if (error) {
+-		zfs_onexit_fd_rele(fd);
+-		return (error);
++		zfs_onexit_fd_rele(fp);
++		return (NULL);
+ 	}
+ 
+ 	zo = zfsdev_get_state(*minorp, ZST_ONEXIT);
+ 	if (zo == NULL) {
+-		zfs_onexit_fd_rele(fd);
+-		return (SET_ERROR(EBADF));
++		zfs_onexit_fd_rele(fp);
++		return (NULL);
+ 	}
+-	return (0);
++	return (fp);
+ }
+ 
+ void
+-zfs_onexit_fd_rele(int fd)
++zfs_onexit_fd_rele(zfs_file_t *fp)
+ {
+-	zfs_file_put(fd);
++	zfs_file_put(fp);
+ }
+ 
+ static int
+-- 
+2.30.2
+
diff -Nru zfs-linux-2.0.3/debian/patches/0009-libshare-nfs-don-t-leak-nfs_lock_fd-when-lock-fails.patch zfs-linux-2.0.3/debian/patches/0009-libshare-nfs-don-t-leak-nfs_lock_fd-when-lock-fails.patch
--- zfs-linux-2.0.3/debian/patches/0009-libshare-nfs-don-t-leak-nfs_lock_fd-when-lock-fails.patch	1970-01-01 08:00:00.000000000 +0800
+++ zfs-linux-2.0.3/debian/patches/0009-libshare-nfs-don-t-leak-nfs_lock_fd-when-lock-fails.patch	2023-02-27 15:55:23.000000000 +0800
@@ -0,0 +1,82 @@
+From 501da8d433f3e9a56c1b61b2f2973e0553cd42f7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= <nabijaczleweli at nabijaczleweli.xyz>
+Date: Sun, 11 Apr 2021 19:27:43 +0200
+Subject: [PATCH] libshare: nfs: don't leak nfs_lock_fd when lock fails
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
+Reviewed-by: George Wilson <gwilson at delphix.com>
+Signed-off-by: Ahelenia Ziemiańska <nabijaczleweli at nabijaczleweli.xyz>
+Closes #11886
+---
+ lib/libshare/os/freebsd/nfs.c | 13 +++++++++----
+ lib/libshare/os/linux/nfs.c   | 13 +++++++++----
+ 2 files changed, 18 insertions(+), 8 deletions(-)
+
+diff --git a/lib/libshare/os/freebsd/nfs.c b/lib/libshare/os/freebsd/nfs.c
+index 5951b9eaf..9cd7dfa95 100644
+--- a/lib/libshare/os/freebsd/nfs.c
++++ b/lib/libshare/os/freebsd/nfs.c
+@@ -65,17 +65,22 @@ static int nfs_lock_fd = -1;
+ static int
+ nfs_exports_lock(void)
+ {
++	int err;
++
+ 	nfs_lock_fd = open(ZFS_EXPORTS_LOCK,
+ 	    O_RDWR | O_CREAT, 0600);
+ 	if (nfs_lock_fd == -1) {
++		err = errno;
+ 		fprintf(stderr, "failed to lock %s: %s\n",
+-		    ZFS_EXPORTS_LOCK, strerror(errno));
+-		return (errno);
++		    ZFS_EXPORTS_LOCK, strerror(err));
++		return (err);
+ 	}
+ 	if (flock(nfs_lock_fd, LOCK_EX) != 0) {
++		err = errno;
+ 		fprintf(stderr, "failed to lock %s: %s\n",
+-		    ZFS_EXPORTS_LOCK, strerror(errno));
+-		return (errno);
++		    ZFS_EXPORTS_LOCK, strerror(err));
++		(void) close(nfs_lock_fd);
++		return (err);
+ 	}
+ 	return (0);
+ }
+diff --git a/lib/libshare/os/linux/nfs.c b/lib/libshare/os/linux/nfs.c
+index 1efa321b7..d5b463b4a 100644
+--- a/lib/libshare/os/linux/nfs.c
++++ b/lib/libshare/os/linux/nfs.c
+@@ -65,17 +65,22 @@ static int nfs_lock_fd = -1;
+ static int
+ nfs_exports_lock(void)
+ {
++	int err;
++
+ 	nfs_lock_fd = open(ZFS_EXPORTS_LOCK,
+ 	    O_RDWR | O_CREAT, 0600);
+ 	if (nfs_lock_fd == -1) {
++		err = errno;
+ 		fprintf(stderr, "failed to lock %s: %s\n",
+-		    ZFS_EXPORTS_LOCK, strerror(errno));
+-		return (errno);
++		    ZFS_EXPORTS_LOCK, strerror(err));
++		return (err);
+ 	}
+ 	if (flock(nfs_lock_fd, LOCK_EX) != 0) {
++		err = errno;
+ 		fprintf(stderr, "failed to lock %s: %s\n",
+-		    ZFS_EXPORTS_LOCK, strerror(errno));
+-		return (errno);
++		    ZFS_EXPORTS_LOCK, strerror(err));
++		(void) close(nfs_lock_fd);
++		return (err);
+ 	}
+ 	return (0);
+ }
+-- 
+2.30.2
+
diff -Nru zfs-linux-2.0.3/debian/patches/0010-Fix-plymouth-passphrase-prompt-with-dracut.patch zfs-linux-2.0.3/debian/patches/0010-Fix-plymouth-passphrase-prompt-with-dracut.patch
--- zfs-linux-2.0.3/debian/patches/0010-Fix-plymouth-passphrase-prompt-with-dracut.patch	1970-01-01 08:00:00.000000000 +0800
+++ zfs-linux-2.0.3/debian/patches/0010-Fix-plymouth-passphrase-prompt-with-dracut.patch	2023-02-27 16:02:46.000000000 +0800
@@ -0,0 +1,39 @@
+From 4ebda5d4d32dd641ded589f336de4ac4964b92fb Mon Sep 17 00:00:00 2001
+From: Michal Vasilek <michal at vasilek.cz>
+Date: Sat, 26 Jun 2021 07:43:25 +0200
+Subject: [PATCH] Fix plymouth passphrase prompt with dracut
+
+plymouth --command splits the command on spaces which means
+that zfs-load-key was getting the filesystem name enclosed
+in single quotes (since 13c59bb76) and failing. This commit
+fixes it by piping the password directly to the command
+similar to how it's done in other scripts (initramfs,
+dracut without plymouth).
+
+Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
+Signed-off-by: Michal Vasilek <michal at vasilek.cz>
+Related-to: #9193
+Related-to: #9202
+Closes #12147
+---
+ contrib/dracut/90zfs/zfs-lib.sh.in | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/contrib/dracut/90zfs/zfs-lib.sh.in b/contrib/dracut/90zfs/zfs-lib.sh.in
+index 10b0b701a..defc0bfc8 100755
+--- a/contrib/dracut/90zfs/zfs-lib.sh.in
++++ b/contrib/dracut/90zfs/zfs-lib.sh.in
+@@ -179,8 +179,8 @@ ask_for_password() {
+         # Prompt for password with plymouth, if installed and running.
+         if plymouth --ping 2>/dev/null; then
+             plymouth ask-for-password \
+-                --prompt "$ply_prompt" --number-of-tries="$ply_tries" \
+-                --command="$ply_cmd"
++                --prompt "$ply_prompt" --number-of-tries="$ply_tries" | \
++                eval "$ply_cmd"
+             ret=$?
+         else
+             if [ "$tty_echo_off" = yes ]; then
+-- 
+2.30.2
+
diff -Nru zfs-linux-2.0.3/debian/patches/series zfs-linux-2.0.3/debian/patches/series
--- zfs-linux-2.0.3/debian/patches/series	2021-07-01 13:42:57.000000000 +0800
+++ zfs-linux-2.0.3/debian/patches/series	2023-02-27 16:13:18.000000000 +0800
@@ -26,3 +26,12 @@
 0037-linux-zvol-avoid-heap-allocation-for-zvol_request_sy.patch
 0038-Don-t-bomb-out-when-using-keylocation-file.patch
 0001-Remove-iov_iter_advance-for-iter_write.patch
+0002-Initialize-ZIL-buffers.patch
+0003-Fix-crash-in-zio_done-error-reporting.patch
+0004-Fix-AVX512BW-Fletcher-code-on-AVX512-but-not-BW-mach.patch
+0005-Fix-zfs_get_data-access-to-files-with-wrong-generati.patch
+0006-Linux-always-check-or-verify-return-of-igrab.patch
+0007-Avoid-deadlock-when-removing-L2ARC-devices-under-I-O.patch
+0008-file-reference-counts-can-get-corrupted.patch
+0009-libshare-nfs-don-t-leak-nfs_lock_fd-when-lock-fails.patch
+0010-Fix-plymouth-passphrase-prompt-with-dracut.patch
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 488 bytes
Desc: not available
URL: <http://alioth-lists.debian.net/pipermail/pkg-zfsonlinux-devel/attachments/20230302/3d1e5e5c/attachment.sig>


More information about the Pkg-zfsonlinux-devel mailing list