Package: release.debian.org Severity: normal Tags: bullseye User: release.debian....@packages.debian.org Usertags: pu X-Debbugs-CC: pkg-zfsonlinux-de...@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
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 <a...@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 <behlendo...@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 <mahr...@delphix.com> +Reviewed-by: Tom Caputi <caput...@tcnj.edu> +Signed-off-by: Brian Behlendorf <behlendo...@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...@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 <behlendo...@llnl.gov> +Signed-off-by: Paul Zuchowski <pzuchow...@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 <rom...@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 <behlendo...@llnl.gov> +Reviewed-by: Adam Moss <c...@yotes.com> +Signed-off-by: Romain Dolbeau <rom...@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 <tux...@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 <behlendo...@llnl.gov> +Signed-off-by: Chunwei Chen <david.c...@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...@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 <behlendo...@llnl.gov> +Signed-off-by: Adam Moss <c...@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 <gamana...@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 <behlendo...@llnl.gov> +Reviewed-by: Mark Maybee <mark.may...@delphix.com> +Signed-off-by: George Amanakis <gamana...@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.wil...@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 <mahr...@delphix.com> +Reviewed-by: Brian Behlendorf <behlendo...@llnl.gov> +Reviewed-by: Mark Maybee <mark.may...@delphix.com> +Reviewed-by: Ryan Moeller <r...@ixsystems.com> +Co-authored-by: Allan Jude <al...@klarasystems.com> +Signed-off-by: George Wilson <gwil...@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?= <nabijaczlew...@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 <behlendo...@llnl.gov> +Reviewed-by: George Wilson <gwil...@delphix.com> +Signed-off-by: Ahelenia ZiemiaĆska <nabijaczlew...@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 <mic...@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 <behlendo...@llnl.gov> +Signed-off-by: Michal Vasilek <mic...@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
signature.asc
Description: PGP signature