Version in base suite: 2.1.11-1 Base version: zfs-linux_2.1.11-1 Target version: zfs-linux_2.1.11-1+deb12u1 Base file: /srv/ftp-master.debian.org/ftp/pool/contrib/z/zfs-linux/zfs-linux_2.1.11-1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/contrib/z/zfs-linux/zfs-linux_2.1.11-1+deb12u1.dsc changelog | 13 + libzfs4linux.symbols | 4 libzpool5linux.symbols | 4 patches/0013-Fix-Detach-spare-vdev-in-case-if-resilvering-does-no.patch | 91 ++++++++ patches/0020-Fix-NULL-pointer-dereference-when-doing-concurrent-s.patch | 65 ++++++ patches/0021-Revert-initramfs-use-mount.zfs-instead-of-mount.patch | 45 ++++ patches/0022-zil-Don-t-expect-zio_shrink-to-succeed.patch | 31 ++ patches/0027-Linux-Never-sleep-in-kmem_cache_alloc-.-KM_NOSLEEP-1.patch | 48 ++++ patches/0028-dnode_is_dirty-check-dnode-and-its-data-for-dirtines.patch | 93 ++++++++ patches/0029-Zpool-can-start-allocating-from-metaslab-before-TRIM.patch | 104 ++++++++++ patches/0030-libshare-nfs-pass-through-ipv6-addresses-in-bracket.patch | 94 +++++++++ patches/series | 9 12 files changed, 600 insertions(+), 1 deletion(-) diff: /srv/release.debian.org/tmp/Sq2TSgrwkh/zfs-linux-2.1.11/debian/zfs-zed.zfs-zed.init: No such file or directory diff: /srv/release.debian.org/tmp/PxzmgbJbLF/zfs-linux-2.1.11/debian/zfs-zed.zfs-zed.init: No such file or directory diff: /srv/release.debian.org/tmp/Sq2TSgrwkh/zfs-linux-2.1.11/debian/zfsutils-linux.zfs-import.init: No such file or directory diff: /srv/release.debian.org/tmp/PxzmgbJbLF/zfs-linux-2.1.11/debian/zfsutils-linux.zfs-import.init: No such file or directory diff: /srv/release.debian.org/tmp/Sq2TSgrwkh/zfs-linux-2.1.11/debian/zfsutils-linux.zfs-load-key.init: No such file or directory diff: /srv/release.debian.org/tmp/PxzmgbJbLF/zfs-linux-2.1.11/debian/zfsutils-linux.zfs-load-key.init: No such file or directory diff: /srv/release.debian.org/tmp/Sq2TSgrwkh/zfs-linux-2.1.11/debian/zfsutils-linux.zfs-mount.init: No such file or directory diff: /srv/release.debian.org/tmp/PxzmgbJbLF/zfs-linux-2.1.11/debian/zfsutils-linux.zfs-mount.init: No such file or directory diff: /srv/release.debian.org/tmp/Sq2TSgrwkh/zfs-linux-2.1.11/debian/zfsutils-linux.zfs-share.init: No such file or directory diff: /srv/release.debian.org/tmp/PxzmgbJbLF/zfs-linux-2.1.11/debian/zfsutils-linux.zfs-share.init: No such file or directory diff -Nru zfs-linux-2.1.11/debian/changelog zfs-linux-2.1.11/debian/changelog --- zfs-linux-2.1.11/debian/changelog 2023-04-23 09:29:38.000000000 +0000 +++ zfs-linux-2.1.11/debian/changelog 2024-11-02 07:34:23.000000000 +0000 @@ -1,3 +1,14 @@ +zfs-linux (2.1.11-1+deb12u1) bookworm; urgency=medium + + * dch: typo fix + * New symbols for libzfs4linux and libzpool5linux + * d/patches: cherry-pick upstream fixes for stability issues + + fix dnode dirty test (Closes: #1056752, #1063497, CVE-2023-49298) + + fix sharenfx IPv6 address parsing (Closes: CVE-2013-20001) + + and some fixes related to NULL pointer, memory allocation, etc. + + -- Shengqi Chen Sat, 02 Nov 2024 15:34:23 +0800 + zfs-linux (2.1.11-1) unstable; urgency=medium [ Mo Zhou ] @@ -5,7 +16,7 @@ [ Aron Xu ] * New upstream stable point release version 2.1.11 - * Drop patches that are alreay in upstream stable release + * Drop patches that are already in upstream stable release -- Aron Xu Sun, 23 Apr 2023 17:29:38 +0800 diff -Nru zfs-linux-2.1.11/debian/libzfs4linux.symbols zfs-linux-2.1.11/debian/libzfs4linux.symbols --- zfs-linux-2.1.11/debian/libzfs4linux.symbols 2023-04-17 04:44:44.000000000 +0000 +++ zfs-linux-2.1.11/debian/libzfs4linux.symbols 2024-11-02 07:34:23.000000000 +0000 @@ -102,6 +102,7 @@ snapshot_namecheck@Base 2.0 spa_feature_table@Base 0.8.2 unshare_one@Base 2.0 + use_color@Base 2.1.11 zcmd_alloc_dst_nvlist@Base 0.8.2 zcmd_expand_dst_nvlist@Base 0.8.2 zcmd_free_nvlists@Base 0.8.2 @@ -386,6 +387,7 @@ zpool_vdev_path_to_guid@Base 0.8.2 zpool_vdev_remove@Base 0.8.2 zpool_vdev_remove_cancel@Base 0.8.2 + zpool_vdev_remove_wanted@Base 2.1.11 zpool_vdev_split@Base 0.8.2 zpool_wait@Base 2.0 zpool_wait_status@Base 2.0 @@ -678,6 +680,8 @@ zfs_niceraw@Base 2.0 zfs_nicetime@Base 2.0 zfs_resolve_shortname@Base 2.0 + zfs_setproctitle@Base 2.1.11 + zfs_setproctitle_init@Base 2.1.11 zfs_strcmp_pathname@Base 2.0 zfs_strip_partition@Base 2.0 zfs_strip_path@Base 2.0 diff -Nru zfs-linux-2.1.11/debian/libzpool5linux.symbols zfs-linux-2.1.11/debian/libzpool5linux.symbols --- zfs-linux-2.1.11/debian/libzpool5linux.symbols 2023-04-17 07:26:55.000000000 +0000 +++ zfs-linux-2.1.11/debian/libzpool5linux.symbols 2024-11-02 07:34:23.000000000 +0000 @@ -685,6 +685,7 @@ dnode_special_close@Base 0.8.2 dnode_special_open@Base 0.8.2 dnode_stats@Base 0.8.2 + dnode_sums@Base 2.1.11 dnode_sync@Base 0.8.2 dnode_try_claim@Base 0.8.2 dnode_verify@Base 2.0 @@ -2095,6 +2096,7 @@ vdev_checkpoint_sm_object@Base 0.8.2 vdev_children_are_offline@Base 0.8.2 vdev_clear@Base 0.8.2 + vdev_clear_kobj_evt@Base 2.1.11 vdev_clear_resilver_deferred@Base 0.8.3 vdev_clear_stats@Base 0.8.2 vdev_close@Base 0.8.2 @@ -2227,6 +2229,7 @@ vdev_open@Base 0.8.2 vdev_open_children@Base 0.8.2 vdev_open_children_subset@Base 2.1 + vdev_post_kobj_evt@Base 2.1.11 vdev_probe@Base 0.8.2 vdev_propagate_state@Base 0.8.2 vdev_psize_to_asize@Base 0.8.2 @@ -2277,6 +2280,7 @@ vdev_removal_max_span@Base 0.8.2 vdev_remove_child@Base 0.8.2 vdev_remove_parent@Base 0.8.2 + vdev_remove_wanted@Base 2.1.11 vdev_reopen@Base 0.8.2 vdev_replace_in_progress@Base 2.0 vdev_replacing_ops@Base 0.8.2 diff -Nru zfs-linux-2.1.11/debian/patches/0013-Fix-Detach-spare-vdev-in-case-if-resilvering-does-no.patch zfs-linux-2.1.11/debian/patches/0013-Fix-Detach-spare-vdev-in-case-if-resilvering-does-no.patch --- zfs-linux-2.1.11/debian/patches/0013-Fix-Detach-spare-vdev-in-case-if-resilvering-does-no.patch 1970-01-01 00:00:00.000000000 +0000 +++ zfs-linux-2.1.11/debian/patches/0013-Fix-Detach-spare-vdev-in-case-if-resilvering-does-no.patch 2024-11-02 07:34:23.000000000 +0000 @@ -0,0 +1,91 @@ +From a68dfdb88c88fe970343e49b48bfd3bb4cef99d2 Mon Sep 17 00:00:00 2001 +From: Ameer Hamza <106930537+ixhamza@users.noreply.github.com> +Date: Wed, 19 Apr 2023 21:04:32 +0500 +Subject: [PATCH] Fix "Detach spare vdev in case if resilvering does not + happen" +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Spare vdev should detach from the pool when a disk is reinserted. +However, spare detachment depends on the completion of resilvering, +and if resilver does not schedule, the spare vdev keeps attached to +the pool until the next resilvering. When a zfs pool contains +several disks (25+ mirror), resilvering does not always happen when +a disk is reinserted. In this patch, spare vdev is manually detached +from the pool when resilvering does not occur and it has been tested +on both Linux and FreeBSD. + +Reviewed-by: Brian Behlendorf +Reviewed-by: Alexander Motin +Signed-off-by: Ameer Hamza +Closes #14722 +--- + include/sys/spa.h | 1 + + module/zfs/spa.c | 5 +++-- + module/zfs/vdev.c | 12 +++++++++++- + 3 files changed, 15 insertions(+), 3 deletions(-) + +diff --git a/include/sys/spa.h b/include/sys/spa.h +index fedadab45..07e09d1ec 100644 +--- a/include/sys/spa.h ++++ b/include/sys/spa.h +@@ -785,6 +785,7 @@ extern int bpobj_enqueue_free_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx); + #define SPA_ASYNC_L2CACHE_REBUILD 0x800 + #define SPA_ASYNC_L2CACHE_TRIM 0x1000 + #define SPA_ASYNC_REBUILD_DONE 0x2000 ++#define SPA_ASYNC_DETACH_SPARE 0x4000 + + /* device manipulation */ + extern int spa_vdev_add(spa_t *spa, nvlist_t *nvroot); +diff --git a/module/zfs/spa.c b/module/zfs/spa.c +index 1ed79eed3..8bc51f777 100644 +--- a/module/zfs/spa.c ++++ b/module/zfs/spa.c +@@ -6987,7 +6987,7 @@ spa_vdev_attach(spa_t *spa, uint64_t guid, nvlist_t *nvroot, int replacing, + * Detach a device from a mirror or replacing vdev. + * + * If 'replace_done' is specified, only detach if the parent +- * is a replacing vdev. ++ * is a replacing or a spare vdev. + */ + int + spa_vdev_detach(spa_t *spa, uint64_t guid, uint64_t pguid, int replace_done) +@@ -8210,7 +8210,8 @@ spa_async_thread(void *arg) + * If any devices are done replacing, detach them. + */ + if (tasks & SPA_ASYNC_RESILVER_DONE || +- tasks & SPA_ASYNC_REBUILD_DONE) { ++ tasks & SPA_ASYNC_REBUILD_DONE || ++ tasks & SPA_ASYNC_DETACH_SPARE) { + spa_vdev_resilver_done(spa); + } + +diff --git a/module/zfs/vdev.c b/module/zfs/vdev.c +index 4b9d7e7c0..ee0c1d862 100644 +--- a/module/zfs/vdev.c ++++ b/module/zfs/vdev.c +@@ -4085,9 +4085,19 @@ vdev_online(spa_t *spa, uint64_t guid, uint64_t flags, vdev_state_t *newstate) + + if (wasoffline || + (oldstate < VDEV_STATE_DEGRADED && +- vd->vdev_state >= VDEV_STATE_DEGRADED)) ++ vd->vdev_state >= VDEV_STATE_DEGRADED)) { + spa_event_notify(spa, vd, NULL, ESC_ZFS_VDEV_ONLINE); + ++ /* ++ * Asynchronously detach spare vdev if resilver or ++ * rebuild is not required ++ */ ++ if (vd->vdev_unspare && ++ !dsl_scan_resilvering(spa->spa_dsl_pool) && ++ !dsl_scan_resilver_scheduled(spa->spa_dsl_pool) && ++ !vdev_rebuild_active(tvd)) ++ spa_async_request(spa, SPA_ASYNC_DETACH_SPARE); ++ } + return (spa_vdev_state_exit(spa, vd, 0)); + } + +-- +2.39.2 + diff -Nru zfs-linux-2.1.11/debian/patches/0020-Fix-NULL-pointer-dereference-when-doing-concurrent-s.patch zfs-linux-2.1.11/debian/patches/0020-Fix-NULL-pointer-dereference-when-doing-concurrent-s.patch --- zfs-linux-2.1.11/debian/patches/0020-Fix-NULL-pointer-dereference-when-doing-concurrent-s.patch 1970-01-01 00:00:00.000000000 +0000 +++ zfs-linux-2.1.11/debian/patches/0020-Fix-NULL-pointer-dereference-when-doing-concurrent-s.patch 2024-11-02 07:34:23.000000000 +0000 @@ -0,0 +1,65 @@ +From 671b1af1bc4b20ddd939c2ede22748bd027d30be Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Lu=C3=ADs=20Henriques?= + <73643340+lumigch@users.noreply.github.com> +Date: Tue, 30 May 2023 23:15:24 +0100 +Subject: [PATCH] Fix NULL pointer dereference when doing concurrent 'send' + operations +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +A NULL pointer will occur when doing a 'zfs send -S' on a dataset that +is still being received. The problem is that the new 'send' will +rightfully fail to own the datasets (i.e. dsl_dataset_own_force() will +fail), but then dmu_send() will still do the dsl_dataset_disown(). + +Reviewed-by: Brian Behlendorf +Signed-off-by: Luís Henriques +Closes #14903 +Closes #14890 +--- + module/zfs/dmu_send.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/module/zfs/dmu_send.c b/module/zfs/dmu_send.c +index cd9ecc07f..0dd1ec210 100644 +--- a/module/zfs/dmu_send.c ++++ b/module/zfs/dmu_send.c +@@ -2797,6 +2797,7 @@ dmu_send(const char *tosnap, const char *fromsnap, boolean_t embedok, + } + + if (err == 0) { ++ owned = B_TRUE; + err = zap_lookup(dspp.dp->dp_meta_objset, + dspp.to_ds->ds_object, + DS_FIELD_RESUME_TOGUID, 8, 1, +@@ -2810,21 +2811,24 @@ dmu_send(const char *tosnap, const char *fromsnap, boolean_t embedok, + sizeof (dspp.saved_toname), + dspp.saved_toname); + } +- if (err != 0) ++ /* Only disown if there was an error in the lookups */ ++ if (owned && (err != 0)) + dsl_dataset_disown(dspp.to_ds, dsflags, FTAG); + + kmem_strfree(name); + } else { + err = dsl_dataset_own(dspp.dp, tosnap, dsflags, + FTAG, &dspp.to_ds); ++ if (err == 0) ++ owned = B_TRUE; + } +- owned = B_TRUE; + } else { + err = dsl_dataset_hold_flags(dspp.dp, tosnap, dsflags, FTAG, + &dspp.to_ds); + } + + if (err != 0) { ++ /* Note: dsl dataset is not owned at this point */ + dsl_pool_rele(dspp.dp, FTAG); + return (err); + } +-- +2.39.2 + diff -Nru zfs-linux-2.1.11/debian/patches/0021-Revert-initramfs-use-mount.zfs-instead-of-mount.patch zfs-linux-2.1.11/debian/patches/0021-Revert-initramfs-use-mount.zfs-instead-of-mount.patch --- zfs-linux-2.1.11/debian/patches/0021-Revert-initramfs-use-mount.zfs-instead-of-mount.patch 1970-01-01 00:00:00.000000000 +0000 +++ zfs-linux-2.1.11/debian/patches/0021-Revert-initramfs-use-mount.zfs-instead-of-mount.patch 2024-11-02 07:34:23.000000000 +0000 @@ -0,0 +1,45 @@ +From 93a99c6daae6e8c126ead2bcf331e5772c966cc7 Mon Sep 17 00:00:00 2001 +From: Rich Ercolani <214141+rincebrain@users.noreply.github.com> +Date: Wed, 31 May 2023 19:58:41 -0400 +Subject: [PATCH] Revert "initramfs: use `mount.zfs` instead of `mount`" + +This broke mounting of snapshots on / for users. + +See https://github.com/openzfs/zfs/issues/9461#issuecomment-1376162949 for more context. + +Reviewed-by: Brian Behlendorf +Signed-off-by: Rich Ercolani +Closes #14908 +--- + contrib/initramfs/scripts/zfs | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/contrib/initramfs/scripts/zfs ++++ b/contrib/initramfs/scripts/zfs +@@ -342,7 +342,7 @@ + + # Need the _original_ datasets mountpoint! + mountpoint=$(get_fs_value "$fs" mountpoint) +- ZFS_CMD="mount.zfs -o zfsutil" ++ ZFS_CMD="mount -o zfsutil -t zfs" + if [ "$mountpoint" = "legacy" ] || [ "$mountpoint" = "none" ]; then + # Can't use the mountpoint property. Might be one of our + # clones. Check the 'org.zol:mountpoint' property set in +@@ -359,7 +359,7 @@ + fi + # Don't use mount.zfs -o zfsutils for legacy mountpoint + if [ "$mountpoint" = "legacy" ]; then +- ZFS_CMD="mount.zfs" ++ ZFS_CMD="mount -t zfs" + fi + # Last hail-mary: Hope 'rootmnt' is set! + mountpoint="" +@@ -930,7 +930,7 @@ + echo " not specified on the kernel command line." + echo "" + echo "Manually mount the root filesystem on $rootmnt and then exit." +- echo "Hint: Try: mount.zfs -o zfsutil ${ZFS_RPOOL-rpool}/ROOT/system $rootmnt" ++ echo "Hint: Try: mount -o zfsutil -t zfs ${ZFS_RPOOL-rpool}/ROOT/system $rootmnt" + shell + fi + diff -Nru zfs-linux-2.1.11/debian/patches/0022-zil-Don-t-expect-zio_shrink-to-succeed.patch zfs-linux-2.1.11/debian/patches/0022-zil-Don-t-expect-zio_shrink-to-succeed.patch --- zfs-linux-2.1.11/debian/patches/0022-zil-Don-t-expect-zio_shrink-to-succeed.patch 1970-01-01 00:00:00.000000000 +0000 +++ zfs-linux-2.1.11/debian/patches/0022-zil-Don-t-expect-zio_shrink-to-succeed.patch 2024-11-02 07:34:23.000000000 +0000 @@ -0,0 +1,31 @@ +From b01a8cc2c0fe6ee4af05bb0b1911afcbd39da64b Mon Sep 17 00:00:00 2001 +From: Alexander Motin +Date: Thu, 11 May 2023 17:27:12 -0400 +Subject: [PATCH] zil: Don't expect zio_shrink() to succeed. + +At least for RAIDZ zio_shrink() does not reduce zio size, but reduced +wsz in that case likely results in writing uninitialized memory. + +Reviewed-by: Brian Behlendorf +Signed-off-by: Alexander Motin +Sponsored by: iXsystems, Inc. +Closes #14853 +--- + module/zfs/zil.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/module/zfs/zil.c b/module/zfs/zil.c +index 0456d3801..cca061040 100644 +--- a/module/zfs/zil.c ++++ b/module/zfs/zil.c +@@ -1593,6 +1593,7 @@ zil_lwb_write_issue(zilog_t *zilog, lwb_t *lwb) + wsz = P2ROUNDUP_TYPED(lwb->lwb_nused, ZIL_MIN_BLKSZ, uint64_t); + ASSERT3U(wsz, <=, lwb->lwb_sz); + zio_shrink(lwb->lwb_write_zio, wsz); ++ wsz = lwb->lwb_write_zio->io_size; + + } else { + wsz = lwb->lwb_sz; +-- +2.39.2 + diff -Nru zfs-linux-2.1.11/debian/patches/0027-Linux-Never-sleep-in-kmem_cache_alloc-.-KM_NOSLEEP-1.patch zfs-linux-2.1.11/debian/patches/0027-Linux-Never-sleep-in-kmem_cache_alloc-.-KM_NOSLEEP-1.patch --- zfs-linux-2.1.11/debian/patches/0027-Linux-Never-sleep-in-kmem_cache_alloc-.-KM_NOSLEEP-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ zfs-linux-2.1.11/debian/patches/0027-Linux-Never-sleep-in-kmem_cache_alloc-.-KM_NOSLEEP-1.patch 2024-11-02 07:34:23.000000000 +0000 @@ -0,0 +1,48 @@ +From 837e426c1f302e580a18a213fd216322f480caf8 Mon Sep 17 00:00:00 2001 +From: Brian Behlendorf +Date: Wed, 7 Jun 2023 10:43:43 -0700 +Subject: [PATCH] Linux: Never sleep in kmem_cache_alloc(..., KM_NOSLEEP) + (#14926) + +When a kmem cache is exhausted and needs to be expanded a new +slab is allocated. KM_SLEEP callers can block and wait for the +allocation, but KM_NOSLEEP callers were incorrectly allowed to +block as well. + +Resolve this by attempting an emergency allocation as a best +effort. This may fail but that's fine since any KM_NOSLEEP +consumer is required to handle an allocation failure. + +Signed-off-by: Brian Behlendorf +Reviewed-by: Adam Moss +Reviewed-by: Brian Atkinson +Reviewed-by: Richard Yao +Reviewed-by: Tony Hutter +--- + module/os/linux/spl/spl-kmem-cache.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +--- a/module/os/linux/spl/spl-kmem-cache.c ++++ b/module/os/linux/spl/spl-kmem-cache.c +@@ -1017,10 +1017,20 @@ + ASSERT0(flags & ~KM_PUBLIC_MASK); + ASSERT(skc->skc_magic == SKC_MAGIC); + ASSERT((skc->skc_flags & KMC_SLAB) == 0); +- might_sleep(); ++ + *obj = NULL; + + /* ++ * Since we can't sleep attempt an emergency allocation to satisfy ++ * the request. The only alterative is to fail the allocation but ++ * it's preferable try. The use of KM_NOSLEEP is expected to be rare. ++ */ ++ if (flags & KM_NOSLEEP) ++ return (spl_emergency_alloc(skc, flags, obj)); ++ ++ might_sleep(); ++ ++ /* + * Before allocating a new slab wait for any reaping to complete and + * then return so the local magazine can be rechecked for new objects. + */ diff -Nru zfs-linux-2.1.11/debian/patches/0028-dnode_is_dirty-check-dnode-and-its-data-for-dirtines.patch zfs-linux-2.1.11/debian/patches/0028-dnode_is_dirty-check-dnode-and-its-data-for-dirtines.patch --- zfs-linux-2.1.11/debian/patches/0028-dnode_is_dirty-check-dnode-and-its-data-for-dirtines.patch 1970-01-01 00:00:00.000000000 +0000 +++ zfs-linux-2.1.11/debian/patches/0028-dnode_is_dirty-check-dnode-and-its-data-for-dirtines.patch 2024-11-02 07:34:23.000000000 +0000 @@ -0,0 +1,93 @@ +From 77b0c6f0403b2b7d145bf6c244b6acbc757ccdc9 Mon Sep 17 00:00:00 2001 +From: Rob N +Date: Wed, 29 Nov 2023 04:16:49 +1100 +Subject: [PATCH] dnode_is_dirty: check dnode and its data for dirtiness + +Over its history this the dirty dnode test has been changed between +checking for a dnodes being on `os_dirty_dnodes` (`dn_dirty_link`) and +`dn_dirty_record`. + + de198f2d9 Fix lseek(SEEK_DATA/SEEK_HOLE) mmap consistency + 2531ce372 Revert "Report holes when there are only metadata changes" + ec4f9b8f3 Report holes when there are only metadata changes + 454365bba Fix dirty check in dmu_offset_next() + 66aca2473 SEEK_HOLE should not block on txg_wait_synced() + +Also illumos/illumos-gate@c543ec060d illumos/illumos-gate@2bcf0248e9 + +It turns out both are actually required. + +In the case of appending data to a newly created file, the dnode proper +is dirtied (at least to change the blocksize) and dirty records are +added. Thus, a single logical operation is represented by separate +dirty indicators, and must not be separated. + +The incorrect dirty check becomes a problem when the first block of a +file is being appended to while another process is calling lseek to skip +holes. There is a small window where the dnode part is undirtied while +there are still dirty records. In this case, `lseek(fd, 0, SEEK_DATA)` +would not know that the file is dirty, and would go to +`dnode_next_offset()`. Since the object has no data blocks yet, it +returns `ESRCH`, indicating no data found, which results in `ENXIO` +being returned to `lseek()`'s caller. + +Since coreutils 9.2, `cp` performs sparse copies by default, that is, it +uses `SEEK_DATA` and `SEEK_HOLE` against the source file and attempts to +replicate the holes in the target. When it hits the bug, its initial +search for data fails, and it goes on to call `fallocate()` to create a +hole over the entire destination file. + +This has come up more recently as users upgrade their systems, getting +OpenZFS 2.2 as well as a newer coreutils. However, this problem has been +reproduced against 2.1, as well as on FreeBSD 13 and 14. + +This change simply updates the dirty check to check both types of dirty. +If there's anything dirty at all, we immediately go to the "wait for +sync" stage, It doesn't really matter after that; both changes are on +disk, so the dirty fields should be correct. + +Sponsored-by: Klara, Inc. +Sponsored-by: Wasabi Technology, Inc. +Reviewed-by: Brian Behlendorf +Reviewed-by: Alexander Motin +Reviewed-by: Rich Ercolani +Signed-off-by: Rob Norris +Closes #15571 +Closes #15526 +--- + module/zfs/dnode.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/module/zfs/dnode.c b/module/zfs/dnode.c +index a9aaa4d21..efebc443a 100644 +--- a/module/zfs/dnode.c ++++ b/module/zfs/dnode.c +@@ -1773,7 +1773,14 @@ dnode_try_claim(objset_t *os, uint64_t object, int slots) + } + + /* +- * Checks if the dnode contains any uncommitted dirty records. ++ * Checks if the dnode itself is dirty, or is carrying any uncommitted records. ++ * It is important to check both conditions, as some operations (eg appending ++ * to a file) can dirty both as a single logical unit, but they are not synced ++ * out atomically, so checking one and not the other can result in an object ++ * appearing to be clean mid-way through a commit. ++ * ++ * Do not change this lightly! If you get it wrong, dmu_offset_next() can ++ * detect a hole where there is really data, leading to silent corruption. + */ + boolean_t + dnode_is_dirty(dnode_t *dn) +@@ -1781,7 +1788,8 @@ dnode_is_dirty(dnode_t *dn) + mutex_enter(&dn->dn_mtx); + + for (int i = 0; i < TXG_SIZE; i++) { +- if (multilist_link_active(&dn->dn_dirty_link[i])) { ++ if (multilist_link_active(&dn->dn_dirty_link[i]) || ++ !list_is_empty(&dn->dn_dirty_records[i])) { + mutex_exit(&dn->dn_mtx); + return (B_TRUE); + } +-- +2.39.2 + diff -Nru zfs-linux-2.1.11/debian/patches/0029-Zpool-can-start-allocating-from-metaslab-before-TRIM.patch zfs-linux-2.1.11/debian/patches/0029-Zpool-can-start-allocating-from-metaslab-before-TRIM.patch --- zfs-linux-2.1.11/debian/patches/0029-Zpool-can-start-allocating-from-metaslab-before-TRIM.patch 1970-01-01 00:00:00.000000000 +0000 +++ zfs-linux-2.1.11/debian/patches/0029-Zpool-can-start-allocating-from-metaslab-before-TRIM.patch 2024-11-02 07:34:23.000000000 +0000 @@ -0,0 +1,104 @@ +From 1ca531971f176ae7b8ca440e836985ae1d7fa0ec Mon Sep 17 00:00:00 2001 +From: Jason King +Date: Thu, 12 Oct 2023 13:01:54 -0500 +Subject: [PATCH] Zpool can start allocating from metaslab before TRIMs have + completed + +When doing a manual TRIM on a zpool, the metaslab being TRIMmed is +potentially re-enabled before all queued TRIM zios for that metaslab +have completed. Since TRIM zios have the lowest priority, it is +possible to get into a situation where allocations occur from the +just re-enabled metaslab and cut ahead of queued TRIMs to the same +metaslab. If the ranges overlap, this will cause corruption. + +We were able to trigger this pretty consistently with a small single +top-level vdev zpool (i.e. small number of metaslabs) with heavy +parallel write activity while performing a manual TRIM against a +somewhat 'slow' device (so TRIMs took a bit of time to complete). +With the patch, we've not been able to recreate it since. It was on +illumos, but inspection of the OpenZFS trim code looks like the +relevant pieces are largely unchanged and so it appears it would be +vulnerable to the same issue. + +Reviewed-by: Igor Kozhukhov +Reviewed-by: Alexander Motin +Reviewed-by: Brian Behlendorf +Signed-off-by: Jason King +Illumos-issue: https://www.illumos.org/issues/15939 +Closes #15395 +--- + module/zfs/vdev_trim.c | 28 +++++++++++++++++++--------- + 1 file changed, 19 insertions(+), 9 deletions(-) + +diff --git a/module/zfs/vdev_trim.c b/module/zfs/vdev_trim.c +index 92daed48f..c0ce2ac28 100644 +--- a/module/zfs/vdev_trim.c ++++ b/module/zfs/vdev_trim.c +@@ -23,6 +23,7 @@ + * Copyright (c) 2016 by Delphix. All rights reserved. + * Copyright (c) 2019 by Lawrence Livermore National Security, LLC. + * Copyright (c) 2021 Hewlett Packard Enterprise Development LP ++ * Copyright 2023 RackTop Systems, Inc. + */ + + #include +@@ -572,6 +573,7 @@ vdev_trim_ranges(trim_args_t *ta) + uint64_t extent_bytes_max = ta->trim_extent_bytes_max; + uint64_t extent_bytes_min = ta->trim_extent_bytes_min; + spa_t *spa = vd->vdev_spa; ++ int error = 0; + + ta->trim_start_time = gethrtime(); + ta->trim_bytes_done = 0; +@@ -591,19 +593,32 @@ vdev_trim_ranges(trim_args_t *ta) + uint64_t writes_required = ((size - 1) / extent_bytes_max) + 1; + + for (uint64_t w = 0; w < writes_required; w++) { +- int error; +- + error = vdev_trim_range(ta, VDEV_LABEL_START_SIZE + + rs_get_start(rs, ta->trim_tree) + + (w *extent_bytes_max), MIN(size - + (w * extent_bytes_max), extent_bytes_max)); + if (error != 0) { +- return (error); ++ goto done; + } + } + } + +- return (0); ++done: ++ /* ++ * Make sure all TRIMs for this metaslab have completed before ++ * returning. TRIM zios have lower priority over regular or syncing ++ * zios, so all TRIM zios for this metaslab must complete before the ++ * metaslab is re-enabled. Otherwise it's possible write zios to ++ * this metaslab could cut ahead of still queued TRIM zios for this ++ * metaslab causing corruption if the ranges overlap. ++ */ ++ mutex_enter(&vd->vdev_trim_io_lock); ++ while (vd->vdev_trim_inflight[0] > 0) { ++ cv_wait(&vd->vdev_trim_io_cv, &vd->vdev_trim_io_lock); ++ } ++ mutex_exit(&vd->vdev_trim_io_lock); ++ ++ return (error); + } + + static void +@@ -922,11 +937,6 @@ vdev_trim_thread(void *arg) + } + + spa_config_exit(spa, SCL_CONFIG, FTAG); +- mutex_enter(&vd->vdev_trim_io_lock); +- while (vd->vdev_trim_inflight[0] > 0) { +- cv_wait(&vd->vdev_trim_io_cv, &vd->vdev_trim_io_lock); +- } +- mutex_exit(&vd->vdev_trim_io_lock); + + range_tree_destroy(ta.trim_tree); + +-- +2.39.2 + diff -Nru zfs-linux-2.1.11/debian/patches/0030-libshare-nfs-pass-through-ipv6-addresses-in-bracket.patch zfs-linux-2.1.11/debian/patches/0030-libshare-nfs-pass-through-ipv6-addresses-in-bracket.patch --- zfs-linux-2.1.11/debian/patches/0030-libshare-nfs-pass-through-ipv6-addresses-in-bracket.patch 1970-01-01 00:00:00.000000000 +0000 +++ zfs-linux-2.1.11/debian/patches/0030-libshare-nfs-pass-through-ipv6-addresses-in-bracket.patch 2024-11-02 07:34:23.000000000 +0000 @@ -0,0 +1,94 @@ +From 6cb5e1e7591da20af3a15793e022345a73e40fb7 Mon Sep 17 00:00:00 2001 +From: felixdoerre +Date: Wed, 20 Oct 2021 19:40:00 +0200 +Subject: [PATCH] libshare: nfs: pass through ipv6 addresses in bracket + notation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Recognize when the host part of a sharenfs attribute is an ipv6 +Literal and pass that through without modification. + +Reviewed-by: Brian Behlendorf +Signed-off-by: Felix Dörre +Closes: #11171 +Closes #11939 +Closes: #1894 +--- +--- a/lib/libshare/os/linux/nfs.c ++++ b/lib/libshare/os/linux/nfs.c +@@ -180,8 +180,9 @@ + { + int error; + const char *access; +- char *host_dup, *host, *next; ++ char *host_dup, *host, *next, *v6Literal; + nfs_host_cookie_t *udata = (nfs_host_cookie_t *)pcookie; ++ int cidr_len; + + #ifdef DEBUG + fprintf(stderr, "foreach_nfs_host_cb: key=%s, value=%s\n", opt, value); +@@ -204,10 +205,46 @@ + host = host_dup; + + do { +- next = strchr(host, ':'); +- if (next != NULL) { +- *next = '\0'; +- next++; ++ if (*host == '[') { ++ host++; ++ v6Literal = strchr(host, ']'); ++ if (v6Literal == NULL) { ++ free(host_dup); ++ return (SA_SYNTAX_ERR); ++ } ++ if (v6Literal[1] == '\0') { ++ *v6Literal = '\0'; ++ next = NULL; ++ } else if (v6Literal[1] == '/') { ++ next = strchr(v6Literal + 2, ':'); ++ if (next == NULL) { ++ cidr_len = ++ strlen(v6Literal + 1); ++ memmove(v6Literal, ++ v6Literal + 1, ++ cidr_len); ++ v6Literal[cidr_len] = '\0'; ++ } else { ++ cidr_len = next - v6Literal - 1; ++ memmove(v6Literal, ++ v6Literal + 1, ++ cidr_len); ++ v6Literal[cidr_len] = '\0'; ++ next++; ++ } ++ } else if (v6Literal[1] == ':') { ++ *v6Literal = '\0'; ++ next = v6Literal + 2; ++ } else { ++ free(host_dup); ++ return (SA_SYNTAX_ERR); ++ } ++ } else { ++ next = strchr(host, ':'); ++ if (next != NULL) { ++ *next = '\0'; ++ next++; ++ } + } + + error = udata->callback(udata->filename, +--- a/man/man8/zfs.8 ++++ b/man/man8/zfs.8 +@@ -545,7 +545,7 @@ + on the + .Ar tank/home + file system: +-.Dl # Nm zfs Cm set Sy sharenfs Ns = Ns ' Ns Ar rw Ns =@123.123.0.0/16,root= Ns Ar neo Ns ' tank/home ++.Dl # Nm zfs Cm set Sy sharenfs Ns = Ns ' Ns Ar rw Ns =@123.123.0.0/16:[::1],root= Ns Ar neo Ns ' tank/home + .Pp + If you are using DNS for host name resolution, + specify the fully-qualified hostname. + diff -Nru zfs-linux-2.1.11/debian/patches/series zfs-linux-2.1.11/debian/patches/series --- zfs-linux-2.1.11/debian/patches/series 2023-04-19 05:37:42.000000000 +0000 +++ zfs-linux-2.1.11/debian/patches/series 2024-11-02 07:34:23.000000000 +0000 @@ -27,3 +27,12 @@ 0006-rootdelay-on-zfs-should-be-adaptive.patch 0009-zdb-zero-pad-checksum-output.patch 0010-zdb-zero-pad-checksum-output-follow-up.patch +# 2.1.11+deb12u1 +0013-Fix-Detach-spare-vdev-in-case-if-resilvering-does-no.patch +0020-Fix-NULL-pointer-dereference-when-doing-concurrent-s.patch +0021-Revert-initramfs-use-mount.zfs-instead-of-mount.patch +0022-zil-Don-t-expect-zio_shrink-to-succeed.patch +0027-Linux-Never-sleep-in-kmem_cache_alloc-.-KM_NOSLEEP-1.patch +0028-dnode_is_dirty-check-dnode-and-its-data-for-dirtines.patch +0029-Zpool-can-start-allocating-from-metaslab-before-TRIM.patch +0030-libshare-nfs-pass-through-ipv6-addresses-in-bracket.patch