git: f2d3322c4511 - stable/13 - zfs: merge OpenZFS master-bedbc13da

Martin Matuska mm at FreeBSD.org
Wed Mar 10 09:38:05 UTC 2021


The branch stable/13 has been updated by mm:

URL: https://cgit.FreeBSD.org/src/commit/?id=f2d3322c451180acca945aae2a5f1e334c7edd1d

commit f2d3322c451180acca945aae2a5f1e334c7edd1d
Author:     Martin Matuska <mm at FreeBSD.org>
AuthorDate: 2021-03-03 01:15:33 +0000
Commit:     Martin Matuska <mm at FreeBSD.org>
CommitDate: 2021-03-10 01:58:07 +0000

    zfs: merge OpenZFS master-bedbc13da
    
    Notable upstream commits:
      8e43fa12c Fix vdev_rebuild_thread deadlock
      03ef8f09e Add missing checks for unsupported features
      2e160dee9 Fix assert in FreeBSD-specific dmu_read_pages
      bedbc13da Cancel TRIM / initialize on FAULTED non-writeable vdevs
    
    Obtained from:  OpenZFS
    
    (cherry picked from commit caed7b1c399de04279822028e15b36367e84232f)
---
 sys/contrib/openzfs/cmd/vdev_id/vdev_id            | 12 ++-
 sys/contrib/openzfs/cmd/zpool/Makefile.am          |  2 +-
 sys/contrib/openzfs/config/kernel-bio.m4           | 29 ++++++++
 .../openzfs/config/kernel-generic_io_acct.m4       | 69 +++++++++++------
 sys/contrib/openzfs/configure.ac                   |  1 +
 .../include/os/linux/kernel/linux/blkdev_compat.h  |  8 +-
 sys/contrib/openzfs/include/sys/dsl_synctask.h     |  9 ++-
 sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c   |  9 +++
 .../openzfs/man/man5/zfs-module-parameters.5       |  2 +-
 .../openzfs/module/os/linux/zfs/vdev_disk.c        |  4 +
 .../openzfs/module/os/linux/zfs/zfs_ioctl_os.c     |  2 +-
 sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c  |  4 +
 sys/contrib/openzfs/module/zfs/spa_misc.c          | 27 ++++---
 sys/contrib/openzfs/module/zfs/zfs_ioctl.c         |  4 +-
 sys/contrib/openzfs/tests/runfiles/common.run      |  2 +-
 .../openzfs/tests/zfs-tests/cmd/Makefile.am        |  1 +
 .../tests/zfs-tests/cmd/send_doall/.gitignore      |  1 +
 .../tests/zfs-tests/cmd/send_doall/Makefile.am     | 11 +++
 .../tests/zfs-tests/cmd/send_doall/send_doall.c    | 87 ++++++++++++++++++++++
 .../openzfs/tests/zfs-tests/include/commands.cfg   |  1 +
 .../zpool_trim/zpool_trim_start_and_cancel_pos.ksh | 22 +++---
 .../zfs-tests/tests/functional/rsend/Makefile.am   |  4 +-
 .../tests/functional/rsend/send_doall.ksh          | 67 +++++++++++++++++
 23 files changed, 319 insertions(+), 59 deletions(-)

diff --git a/sys/contrib/openzfs/cmd/vdev_id/vdev_id b/sys/contrib/openzfs/cmd/vdev_id/vdev_id
index 95a4e483b876..8a379a72690e 100755
--- a/sys/contrib/openzfs/cmd/vdev_id/vdev_id
+++ b/sys/contrib/openzfs/cmd/vdev_id/vdev_id
@@ -285,7 +285,9 @@ sas_handler() {
 		# we have to append the -part suffix directly in the
 		# helper.
 		if [ "$DEVTYPE" != "partition" ] ; then
-			PART=$(echo "$DM_NAME" | awk -Fp '/p/{print "-part"$2}')
+			# Match p[number], remove the 'p' and prepend "-part"
+			PART=$(echo "$DM_NAME" |
+				awk 'match($0,/p[0-9]+$/) {print "-part"substr($0,RSTART+1,RLENGTH-1)}')
 		fi
 
 		# Strip off partition information.
@@ -499,7 +501,9 @@ scsi_handler() {
 		# we have to append the -part suffix directly in the
 		# helper.
 		if [ "$DEVTYPE" != "partition" ] ; then
-			PART=$(echo "$DM_NAME" | awk -Fp '/p/{print "-part"$2}')
+			# Match p[number], remove the 'p' and prepend "-part"
+			PART=$(echo "$DM_NAME" |
+			    awk 'match($0,/p[0-9]+$/) {print "-part"substr($0,RSTART+1,RLENGTH-1)}')
 		fi
 
 		# Strip off partition information.
@@ -648,7 +652,9 @@ alias_handler () {
 	DM_PART=
 	if echo "$DM_NAME" | grep -q -E 'p[0-9][0-9]*$' ; then
 		if [ "$DEVTYPE" != "partition" ] ; then
-			DM_PART=$(echo "$DM_NAME" | awk -Fp '/p/{print "-part"$2}')
+			# Match p[number], remove the 'p' and prepend "-part"
+			DM_PART=$(echo "$DM_NAME" |
+			    awk 'match($0,/p[0-9]+$/) {print "-part"substr($0,RSTART+1,RLENGTH-1)}')
 		fi
 	fi
 
diff --git a/sys/contrib/openzfs/cmd/zpool/Makefile.am b/sys/contrib/openzfs/cmd/zpool/Makefile.am
index d47051e4fe50..abfa940c3d72 100644
--- a/sys/contrib/openzfs/cmd/zpool/Makefile.am
+++ b/sys/contrib/openzfs/cmd/zpool/Makefile.am
@@ -179,5 +179,5 @@ install-data-hook:
 	    ln -s "$(zpoolexecdir)/$${f}" "$(DESTDIR)$(zpoolconfdir)"; \
 	done
 	for l in $(zpoolcompatlinks); do \
-		(cd "$(DESTDIR)$(zpoolcompatdir)"; ln -s $${l} ); \
+		(cd "$(DESTDIR)$(zpoolcompatdir)"; ln -sf $${l} ); \
 	done
diff --git a/sys/contrib/openzfs/config/kernel-bio.m4 b/sys/contrib/openzfs/config/kernel-bio.m4
index 0c533531dceb..d8692bd39999 100644
--- a/sys/contrib/openzfs/config/kernel-bio.m4
+++ b/sys/contrib/openzfs/config/kernel-bio.m4
@@ -369,6 +369,33 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKG_TRYGET], [
 	])
 ])
 
+dnl #
+dnl # Linux 5.12 API,
+dnl #
+dnl # The Linux 5.12 kernel updated struct bio to create a new bi_bdev member
+dnl # and bio->bi_disk was moved to bio->bi_bdev->bd_disk
+dnl #
+AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO_BDEV_DISK], [
+	ZFS_LINUX_TEST_SRC([bio_bdev_disk], [
+		#include <linux/blk_types.h>
+		#include <linux/blkdev.h>
+	],[
+		struct bio *b = NULL;
+		struct gendisk *d = b->bi_bdev->bd_disk;
+		blk_register_queue(d);
+	])
+])
+
+AC_DEFUN([ZFS_AC_KERNEL_BIO_BDEV_DISK], [
+	AC_MSG_CHECKING([whether bio->bi_bdev->bd_disk exists])
+	ZFS_LINUX_TEST_RESULT([bio_bdev_disk], [
+		AC_MSG_RESULT(yes)
+		AC_DEFINE(HAVE_BIO_BDEV_DISK, 1, [bio->bi_bdev->bd_disk exists])
+	],[
+		AC_MSG_RESULT(no)
+	])
+])
+
 AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO], [
 	ZFS_AC_KERNEL_SRC_REQ
 	ZFS_AC_KERNEL_SRC_BIO_OPS
@@ -379,6 +406,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BIO], [
 	ZFS_AC_KERNEL_SRC_BIO_SUBMIT_BIO
 	ZFS_AC_KERNEL_SRC_BIO_CURRENT_BIO_LIST
 	ZFS_AC_KERNEL_SRC_BLKG_TRYGET
+	ZFS_AC_KERNEL_SRC_BIO_BDEV_DISK
 ])
 
 AC_DEFUN([ZFS_AC_KERNEL_BIO], [
@@ -400,4 +428,5 @@ AC_DEFUN([ZFS_AC_KERNEL_BIO], [
 	ZFS_AC_KERNEL_BIO_SUBMIT_BIO
 	ZFS_AC_KERNEL_BIO_CURRENT_BIO_LIST
 	ZFS_AC_KERNEL_BLKG_TRYGET
+	ZFS_AC_KERNEL_BIO_BDEV_DISK
 ])
diff --git a/sys/contrib/openzfs/config/kernel-generic_io_acct.m4 b/sys/contrib/openzfs/config/kernel-generic_io_acct.m4
index e4ab503d5e1c..0f4381db4c5e 100644
--- a/sys/contrib/openzfs/config/kernel-generic_io_acct.m4
+++ b/sys/contrib/openzfs/config/kernel-generic_io_acct.m4
@@ -2,6 +2,17 @@ dnl #
 dnl # Check for generic io accounting interface.
 dnl #
 AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_IO_ACCT], [
+	ZFS_LINUX_TEST_SRC([disk_io_acct], [
+		#include <linux/blkdev.h>
+	], [
+		struct gendisk *disk = NULL;
+		struct bio *bio = NULL;
+		unsigned long start_time;
+
+		start_time = disk_start_io_acct(disk, bio_sectors(bio), bio_op(bio));
+		disk_end_io_acct(disk, bio_op(bio), start_time);
+	])
+
 	ZFS_LINUX_TEST_SRC([bio_io_acct], [
 		#include <linux/blkdev.h>
 	], [
@@ -39,48 +50,62 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_GENERIC_IO_ACCT], [
 
 AC_DEFUN([ZFS_AC_KERNEL_GENERIC_IO_ACCT], [
 	dnl #
-	dnl # 5.7 API,
+	dnl # 5.12 API,
 	dnl #
-	dnl # Added bio_start_io_acct() and bio_end_io_acct() helpers.
+	dnl # bio_start_io_acct() and bio_end_io_acct() became GPL-exported
+	dnl # so use disk_start_io_acct() and disk_end_io_acct() instead
 	dnl #
-	AC_MSG_CHECKING([whether generic bio_*_io_acct() are available])
-	ZFS_LINUX_TEST_RESULT([bio_io_acct], [
+	AC_MSG_CHECKING([whether generic disk_*_io_acct() are available])
+	ZFS_LINUX_TEST_RESULT([disk_io_acct], [
 		AC_MSG_RESULT(yes)
-		AC_DEFINE(HAVE_BIO_IO_ACCT, 1, [bio_*_io_acct() available])
+		AC_DEFINE(HAVE_DISK_IO_ACCT, 1, [disk_*_io_acct() available])
 	], [
 		AC_MSG_RESULT(no)
 
 		dnl #
-		dnl # 4.14 API,
+		dnl # 5.7 API,
 		dnl #
-		dnl # generic_start_io_acct/generic_end_io_acct now require
-		dnl # request_queue to be provided. No functional changes,
-		dnl # but preparation for inflight accounting.
+		dnl # Added bio_start_io_acct() and bio_end_io_acct() helpers.
 		dnl #
-		AC_MSG_CHECKING([whether generic_*_io_acct wants 4 args])
-		ZFS_LINUX_TEST_RESULT_SYMBOL([generic_acct_4args],
-		    [generic_start_io_acct], [block/bio.c], [
+		AC_MSG_CHECKING([whether generic bio_*_io_acct() are available])
+		ZFS_LINUX_TEST_RESULT([bio_io_acct], [
 			AC_MSG_RESULT(yes)
-			AC_DEFINE(HAVE_GENERIC_IO_ACCT_4ARG, 1,
-			    [generic_*_io_acct() 4 arg available])
+			AC_DEFINE(HAVE_BIO_IO_ACCT, 1, [bio_*_io_acct() available])
 		], [
 			AC_MSG_RESULT(no)
 
 			dnl #
-			dnl # 3.19 API addition
+			dnl # 4.14 API,
 			dnl #
-			dnl # torvalds/linux at 394ffa50 allows us to increment
-			dnl # iostat counters without generic_make_request().
+			dnl # generic_start_io_acct/generic_end_io_acct now require
+			dnl # request_queue to be provided. No functional changes,
+			dnl # but preparation for inflight accounting.
 			dnl #
-			AC_MSG_CHECKING(
-			    [whether generic_*_io_acct wants 3 args])
-			ZFS_LINUX_TEST_RESULT_SYMBOL([generic_acct_3args],
+			AC_MSG_CHECKING([whether generic_*_io_acct wants 4 args])
+			ZFS_LINUX_TEST_RESULT_SYMBOL([generic_acct_4args],
 			    [generic_start_io_acct], [block/bio.c], [
 				AC_MSG_RESULT(yes)
-				AC_DEFINE(HAVE_GENERIC_IO_ACCT_3ARG, 1,
-				    [generic_*_io_acct() 3 arg available])
+				AC_DEFINE(HAVE_GENERIC_IO_ACCT_4ARG, 1,
+				    [generic_*_io_acct() 4 arg available])
 			], [
 				AC_MSG_RESULT(no)
+
+				dnl #
+				dnl # 3.19 API addition
+				dnl #
+				dnl # torvalds/linux at 394ffa50 allows us to increment
+				dnl # iostat counters without generic_make_request().
+				dnl #
+				AC_MSG_CHECKING(
+				    [whether generic_*_io_acct wants 3 args])
+				ZFS_LINUX_TEST_RESULT_SYMBOL([generic_acct_3args],
+				    [generic_start_io_acct], [block/bio.c], [
+					AC_MSG_RESULT(yes)
+					AC_DEFINE(HAVE_GENERIC_IO_ACCT_3ARG, 1,
+					    [generic_*_io_acct() 3 arg available])
+				], [
+					AC_MSG_RESULT(no)
+				])
 			])
 		])
 	])
diff --git a/sys/contrib/openzfs/configure.ac b/sys/contrib/openzfs/configure.ac
index 4520a290a9a5..b2d88554ed7d 100644
--- a/sys/contrib/openzfs/configure.ac
+++ b/sys/contrib/openzfs/configure.ac
@@ -230,6 +230,7 @@ AC_CONFIG_FILES([
 	tests/zfs-tests/cmd/readmmap/Makefile
 	tests/zfs-tests/cmd/rename_dir/Makefile
 	tests/zfs-tests/cmd/rm_lnkcnt_zero_file/Makefile
+	tests/zfs-tests/cmd/send_doall/Makefile
 	tests/zfs-tests/cmd/stride_dd/Makefile
 	tests/zfs-tests/cmd/threadsappend/Makefile
 	tests/zfs-tests/cmd/user_ns_exec/Makefile
diff --git a/sys/contrib/openzfs/include/os/linux/kernel/linux/blkdev_compat.h b/sys/contrib/openzfs/include/os/linux/kernel/linux/blkdev_compat.h
index e41b248b0405..ee066537b900 100644
--- a/sys/contrib/openzfs/include/os/linux/kernel/linux/blkdev_compat.h
+++ b/sys/contrib/openzfs/include/os/linux/kernel/linux/blkdev_compat.h
@@ -520,7 +520,9 @@ blk_generic_start_io_acct(struct request_queue *q __attribute__((unused)),
     struct gendisk *disk __attribute__((unused)),
     int rw __attribute__((unused)), struct bio *bio)
 {
-#if defined(HAVE_BIO_IO_ACCT)
+#if defined(HAVE_DISK_IO_ACCT)
+	return (disk_start_io_acct(disk, bio_sectors(bio), bio_op(bio)));
+#elif defined(HAVE_BIO_IO_ACCT)
 	return (bio_start_io_acct(bio));
 #elif defined(HAVE_GENERIC_IO_ACCT_3ARG)
 	unsigned long start_time = jiffies;
@@ -541,7 +543,9 @@ blk_generic_end_io_acct(struct request_queue *q __attribute__((unused)),
     struct gendisk *disk __attribute__((unused)),
     int rw __attribute__((unused)), struct bio *bio, unsigned long start_time)
 {
-#if defined(HAVE_BIO_IO_ACCT)
+#if defined(HAVE_DISK_IO_ACCT)
+	disk_end_io_acct(disk, bio_op(bio), start_time);
+#elif defined(HAVE_BIO_IO_ACCT)
 	bio_end_io_acct(bio, start_time);
 #elif defined(HAVE_GENERIC_IO_ACCT_3ARG)
 	generic_end_io_acct(rw, &disk->part0, start_time);
diff --git a/sys/contrib/openzfs/include/sys/dsl_synctask.h b/sys/contrib/openzfs/include/sys/dsl_synctask.h
index 0bb602e8f7ff..5a5b306419f1 100644
--- a/sys/contrib/openzfs/include/sys/dsl_synctask.h
+++ b/sys/contrib/openzfs/include/sys/dsl_synctask.h
@@ -41,10 +41,11 @@ typedef void (dsl_sigfunc_t)(void *, dmu_tx_t *);
 
 typedef enum zfs_space_check {
 	/*
-	 * Normal space check: if there is less than 3.2% free space,
-	 * the operation will fail.  Operations which are logically
-	 * creating things should use this (e.g. "zfs create", "zfs snapshot").
-	 * User writes (via the ZPL / ZVOL) also fail at this point.
+	 * Normal space check: if there is less than 3.2% free space (bounded
+	 * by spa_max_slop), the operation will fail.  Operations which are
+	 * logically creating things should use this (e.g. "zfs create", "zfs
+	 * snapshot").  User writes (via the ZPL / ZVOL) also fail at this
+	 * point.
 	 */
 	ZFS_SPACE_CHECK_NORMAL,
 
diff --git a/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c b/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c
index 62a94264494f..1e3a0bf5618a 100644
--- a/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c
+++ b/sys/contrib/openzfs/lib/libzfs/libzfs_sendrecv.c
@@ -321,6 +321,15 @@ send_iterate_snap(zfs_handle_t *zhp, void *arg)
 	}
 
 	if (!sd->recursive) {
+
+		/*
+		 * To allow a doall stream to work properly
+		 * with a NULL fromsnap
+		 */
+		if (sd->doall && sd->fromsnap == NULL && !sd->seenfrom) {
+			sd->seenfrom = B_TRUE;
+		}
+
 		if (!sd->seenfrom && isfromsnap) {
 			sd->seenfrom = B_TRUE;
 			zfs_close(zhp);
diff --git a/sys/contrib/openzfs/man/man5/zfs-module-parameters.5 b/sys/contrib/openzfs/man/man5/zfs-module-parameters.5
index 8fec44dd37e5..d68e85fa078d 100644
--- a/sys/contrib/openzfs/man/man5/zfs-module-parameters.5
+++ b/sys/contrib/openzfs/man/man5/zfs-module-parameters.5
@@ -1238,7 +1238,7 @@ amount of memory. When the limit is exceeded, the ioctl fails with EINVAL and a
 description of the error is sent to the zfs-dbgmsg log. This parameter should
 not need to be touched under normal circumstances. On FreeBSD, the default is
 based on the system limit on user wired memory. On Linux, the default is
-\fBKMALLOC_MAX_SIZE\fR .
+\fB128MB\fR.
 .sp
 Default value: \fB0\fR (kernel decides)
 .RE
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/vdev_disk.c b/sys/contrib/openzfs/module/os/linux/zfs/vdev_disk.c
index b373f2c2e83c..ff71ef4cd065 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/vdev_disk.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/vdev_disk.c
@@ -494,7 +494,11 @@ vdev_blkg_tryget(struct blkcg_gq *blkg)
 static inline void
 vdev_bio_associate_blkg(struct bio *bio)
 {
+#if defined(HAVE_BIO_BDEV_DISK)
+	struct request_queue *q = bio->bi_bdev->bd_disk->queue;
+#else
 	struct request_queue *q = bio->bi_disk->queue;
+#endif
 
 	ASSERT3P(q, !=, NULL);
 	ASSERT3P(bio->bi_blkg, ==, NULL);
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_ioctl_os.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_ioctl_os.c
index b88e0497d000..6f5cff1770e1 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_ioctl_os.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_ioctl_os.c
@@ -209,7 +209,7 @@ zfs_max_nvlist_src_size_os(void)
 	if (zfs_max_nvlist_src_size != 0)
 		return (zfs_max_nvlist_src_size);
 
-	return (KMALLOC_MAX_SIZE);
+	return (MIN(ptob(zfs_totalram_pages) / 4, 128 * 1024 * 1024));
 }
 
 void
diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c b/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c
index 0caf31307718..0d62b1490702 100644
--- a/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c
+++ b/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c
@@ -307,7 +307,11 @@ zvol_request(struct request_queue *q, struct bio *bio)
 #endif
 {
 #ifdef HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS
+#if defined(HAVE_BIO_BDEV_DISK)
+	struct request_queue *q = bio->bi_bdev->bd_disk->queue;
+#else
 	struct request_queue *q = bio->bi_disk->queue;
+#endif
 #endif
 	zvol_state_t *zv = q->queuedata;
 	fstrans_cookie_t cookie = spl_fstrans_mark();
diff --git a/sys/contrib/openzfs/module/zfs/spa_misc.c b/sys/contrib/openzfs/module/zfs/spa_misc.c
index 5d45e5a21159..0dacf9027b27 100644
--- a/sys/contrib/openzfs/module/zfs/spa_misc.c
+++ b/sys/contrib/openzfs/module/zfs/spa_misc.c
@@ -347,13 +347,14 @@ int spa_asize_inflation = 24;
 
 /*
  * Normally, we don't allow the last 3.2% (1/(2^spa_slop_shift)) of space in
- * the pool to be consumed.  This ensures that we don't run the pool
- * completely out of space, due to unaccounted changes (e.g. to the MOS).
- * It also limits the worst-case time to allocate space.  If we have less than
- * this amount of free space, most ZPL operations (e.g. write, create) will
- * return ENOSPC.  The ZIL metaslabs (spa_embedded_log_class) are also part of
- * this 3.2% of space which can't be consumed by normal writes; the slop space
- * "proper" (spa_get_slop_space()) is decreased by the embedded log space.
+ * the pool to be consumed (bounded by spa_max_slop).  This ensures that we
+ * don't run the pool completely out of space, due to unaccounted changes (e.g.
+ * to the MOS).  It also limits the worst-case time to allocate space.  If we
+ * have less than this amount of free space, most ZPL operations (e.g.  write,
+ * create) will return ENOSPC.  The ZIL metaslabs (spa_embedded_log_class) are
+ * also part of this 3.2% of space which can't be consumed by normal writes;
+ * the slop space "proper" (spa_get_slop_space()) is decreased by the embedded
+ * log space.
  *
  * Certain operations (e.g. file removal, most administrative actions) can
  * use half the slop space.  They will only return ENOSPC if less than half
@@ -376,10 +377,15 @@ int spa_asize_inflation = 24;
  * 3.2%, in an effort to have it be at least spa_min_slop (128MB),
  * but we never allow it to be more than half the pool size.
  *
+ * Further, on very large pools, the slop space will be smaller than
+ * 3.2%, to avoid reserving much more space than we actually need; bounded
+ * by spa_max_slop (128GB).
+ *
  * See also the comments in zfs_space_check_t.
  */
 int spa_slop_shift = 5;
-uint64_t spa_min_slop = 128 * 1024 * 1024;
+uint64_t spa_min_slop = 128ULL * 1024 * 1024;
+uint64_t spa_max_slop = 128ULL * 1024 * 1024 * 1024;
 int spa_allocators = 4;
 
 
@@ -1781,7 +1787,8 @@ spa_get_worst_case_asize(spa_t *spa, uint64_t lsize)
 /*
  * Return the amount of slop space in bytes.  It is typically 1/32 of the pool
  * (3.2%), minus the embedded log space.  On very small pools, it may be
- * slightly larger than this. The embedded log space is not included in
+ * slightly larger than this.  On very large pools, it will be capped to
+ * the value of spa_max_slop.  The embedded log space is not included in
  * spa_dspace.  By subtracting it, the usable space (per "zfs list") is a
  * constant 97% of the total space, regardless of metaslab size (assuming the
  * default spa_slop_shift=5 and a non-tiny pool).
@@ -1792,7 +1799,7 @@ uint64_t
 spa_get_slop_space(spa_t *spa)
 {
 	uint64_t space = spa_get_dspace(spa);
-	uint64_t slop = space >> spa_slop_shift;
+	uint64_t slop = MIN(space >> spa_slop_shift, spa_max_slop);
 
 	/*
 	 * Subtract the embedded log space, but no more than half the (3.2%)
diff --git a/sys/contrib/openzfs/module/zfs/zfs_ioctl.c b/sys/contrib/openzfs/module/zfs/zfs_ioctl.c
index 922253469fba..5f291d067bef 100644
--- a/sys/contrib/openzfs/module/zfs/zfs_ioctl.c
+++ b/sys/contrib/openzfs/module/zfs/zfs_ioctl.c
@@ -3988,7 +3988,7 @@ zfs_ioc_pool_initialize(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
 	fnvlist_free(vdev_errlist);
 
 	spa_close(spa, FTAG);
-	return (total_errors > 0 ? EINVAL : 0);
+	return (total_errors > 0 ? SET_ERROR(EINVAL) : 0);
 }
 
 /*
@@ -4073,7 +4073,7 @@ zfs_ioc_pool_trim(const char *poolname, nvlist_t *innvl, nvlist_t *outnvl)
 	fnvlist_free(vdev_errlist);
 
 	spa_close(spa, FTAG);
-	return (total_errors > 0 ? EINVAL : 0);
+	return (total_errors > 0 ? SET_ERROR(EINVAL) : 0);
 }
 
 /*
diff --git a/sys/contrib/openzfs/tests/runfiles/common.run b/sys/contrib/openzfs/tests/runfiles/common.run
index f86d0283bf37..fcb0fa6cd24f 100644
--- a/sys/contrib/openzfs/tests/runfiles/common.run
+++ b/sys/contrib/openzfs/tests/runfiles/common.run
@@ -809,7 +809,7 @@ tests = ['recv_dedup', 'recv_dedup_encrypted_zvol', 'rsend_001_pos',
     'send_freeobjects', 'send_realloc_files',
     'send_realloc_encrypted_files', 'send_spill_block', 'send_holds',
     'send_hole_birth', 'send_mixed_raw', 'send-wR_encrypted_zvol',
-    'send_partial_dataset', 'send_invalid']
+    'send_partial_dataset', 'send_invalid', 'send_doall']
 tags = ['functional', 'rsend']
 
 [tests/functional/scrub_mirror]
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am
index 7fe9a2c571f8..2b965ca70009 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/Makefile.am
@@ -25,6 +25,7 @@ SUBDIRS = \
 	readmmap \
 	rename_dir \
 	rm_lnkcnt_zero_file \
+	send_doall \
 	stride_dd \
 	threadsappend
 
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/send_doall/.gitignore b/sys/contrib/openzfs/tests/zfs-tests/cmd/send_doall/.gitignore
new file mode 100644
index 000000000000..6ba2e603f744
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/send_doall/.gitignore
@@ -0,0 +1 @@
+/send_doall
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/send_doall/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/cmd/send_doall/Makefile.am
new file mode 100644
index 000000000000..33a6b83122b8
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/send_doall/Makefile.am
@@ -0,0 +1,11 @@
+include $(top_srcdir)/config/Rules.am
+
+pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin
+
+pkgexec_PROGRAMS = send_doall
+
+send_doall_SOURCES = send_doall.c
+send_doall_LDADD = \
+	$(abs_top_builddir)/lib/libzfs_core/libzfs_core.la \
+	$(abs_top_builddir)/lib/libzfs/libzfs.la \
+	$(abs_top_builddir)/lib/libnvpair/libnvpair.la
diff --git a/sys/contrib/openzfs/tests/zfs-tests/cmd/send_doall/send_doall.c b/sys/contrib/openzfs/tests/zfs-tests/cmd/send_doall/send_doall.c
new file mode 100644
index 000000000000..6f47df047478
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/cmd/send_doall/send_doall.c
@@ -0,0 +1,87 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Portions Copyright 2020 iXsystems, Inc.
+ */
+
+/*
+ * Test a corner case : a "doall" send without children datasets.
+ */
+
+#include <libzfs.h>
+#include <libzfs_core.h>
+
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sysexits.h>
+#include <err.h>
+
+static void
+usage(const char *name)
+{
+	fprintf(stderr, "usage: %s snap\n", name);
+	exit(EX_USAGE);
+}
+
+int
+main(int argc, char const * const argv[])
+{
+	sendflags_t flags = { 0 };
+	libzfs_handle_t *zhdl;
+	zfs_handle_t *zhp;
+	const char *tofull, *fsname, *tosnap, *p;
+	int error;
+
+	if (argc != 2)
+		usage(argv[0]);
+
+	tofull = argv[1];
+
+	p = strchr(tofull, '@');
+	if (p == NULL)
+		usage(argv[0]);
+	tosnap = p + 1;
+
+	fsname = strndup(tofull, p - tofull);
+
+	zhdl = libzfs_init();
+	if (zhdl == NULL)
+		errx(EX_OSERR, "libzfs_init(): %s", libzfs_error_init(errno));
+
+	zhp = zfs_open(zhdl, fsname, ZFS_TYPE_FILESYSTEM);
+	if (zhp == NULL)
+		err(EX_OSERR, "zfs_open(\"%s\")", fsname);
+
+	flags.doall = B_TRUE;
+
+	error = zfs_send(zhp, NULL, tosnap, &flags,
+	    STDOUT_FILENO, NULL, NULL, NULL);
+
+	zfs_close(zhp);
+
+	libzfs_fini(zhdl);
+	free((void *)fsname);
+
+	return (error);
+}
diff --git a/sys/contrib/openzfs/tests/zfs-tests/include/commands.cfg b/sys/contrib/openzfs/tests/zfs-tests/include/commands.cfg
index 299653547759..a43ddd016fde 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/include/commands.cfg
+++ b/sys/contrib/openzfs/tests/zfs-tests/include/commands.cfg
@@ -217,6 +217,7 @@ export ZFSTEST_FILES='badsend
     readmmap
     rename_dir
     rm_lnkcnt_zero_file
+    send_doall
     threadsappend
     user_ns_exec
     xattrtest
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_start_and_cancel_pos.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_start_and_cancel_pos.ksh
index eaa4d90444b6..fbb0c291046c 100755
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_start_and_cancel_pos.ksh
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_start_and_cancel_pos.ksh
@@ -20,29 +20,29 @@
 #
 
 . $STF_SUITE/include/libtest.shlib
-. $STF_SUITE/tests/functional/cli_root/zpool_initialize/zpool_initialize.kshlib
+. $STF_SUITE/tests/functional/cli_root/zpool_trim/zpool_trim.kshlib
 
 #
 # DESCRIPTION:
-# Starting and stopping an initialize works.
+# Starting and stopping a trim works.
 #
 # STRATEGY:
 # 1. Create a one-disk pool.
-# 2. Start initializing and verify that initializing is active.
-# 3. Cancel initializing and verify that initializing is not active.
+# 2. Start trimming and verify that trimming is active.
+# 3. Cancel trimming and verify that trimming is not active.
 #
 
 DISK1=${DISKS%% *}
 
 log_must zpool create -f $TESTPOOL $DISK1
-log_must zpool initialize $TESTPOOL
+log_must zpool trim $TESTPOOL
 
-[[ -z "$(initialize_progress $TESTPOOL $DISK1)" ]] && \
-    log_fail "Initialize did not start"
+[[ -z "$(trim_progress $TESTPOOL $DISK1)" ]] && \
+    log_fail "TRIM did not start"
 
-log_must zpool initialize -c $TESTPOOL
+log_must zpool trim -c $TESTPOOL
 
-[[ -z "$(initialize_progress $TESTPOOL $DISK1)" ]] || \
-    log_fail "Initialize did not stop"
+[[ -z "$(trim_progress $TESTPOOL $DISK1)" ]] || \
+    log_fail "TRIM did not stop"
 
-log_pass "Initialize start + cancel works"
+log_pass "TRIM start + cancel works"
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/rsend/Makefile.am b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/rsend/Makefile.am
index 61be2ec1889d..94bdd2674517 100644
--- a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/rsend/Makefile.am
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/rsend/Makefile.am
@@ -53,7 +53,8 @@ dist_pkgdata_SCRIPTS = \
 	send_hole_birth.ksh \
 	send_invalid.ksh \
 	send_mixed_raw.ksh \
-	send-wR_encrypted_zvol.ksh
+	send-wR_encrypted_zvol.ksh \
+	send_doall.ksh
 
 dist_pkgdata_DATA = \
 	dedup.zsend.bz2 \
@@ -62,3 +63,4 @@ dist_pkgdata_DATA = \
 	fs.tar.gz \
 	rsend.cfg \
 	rsend.kshlib
+
diff --git a/sys/contrib/openzfs/tests/zfs-tests/tests/functional/rsend/send_doall.ksh b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/rsend/send_doall.ksh
new file mode 100755
index 000000000000..e5c3490b32cd
--- /dev/null
+++ b/sys/contrib/openzfs/tests/zfs-tests/tests/functional/rsend/send_doall.ksh
@@ -0,0 +1,67 @@
+#!/bin/ksh
+
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright (c) 2019 by Lawrence Livermore National Security, LLC.
+#
+
+. $STF_SUITE/include/libtest.shlib
+. $STF_SUITE/tests/functional/rsend/rsend.kshlib
+
+#
+# Description:
+# Verify send_doall stream is properly received
+#
+# Strategy:
+# 1) Create a set of snapshots.
+# 2) Send these snapshots (from origin to the last one) to a file using send_doall.
+# 3) Receive the file to newfs to test if the stream is properly handled.
+#
+
+verify_runnable "both"
+
+log_assert "Verify send_doall stream is correct"
+
+function cleanup
+{
+	rm -f $BACKDIR/fs@*
+	destroy_dataset $POOL/fs "-rR"
+	destroy_dataset $POOL/newfs "-rR"
+}
+
+log_onexit cleanup
+
+log_must zfs create $POOL/fs
+log_must zfs create $POOL/fs/child
+
+# Create 3 files and a snapshot between each file creation.
+for i in {1..3}; do
+	file="/$POOL/fs/file$i"
+	log_must mkfile 16384 $file
+
+	file="/$POOL/fs/child/file$i"
+	log_must mkfile 16384 $file
+
+	log_must zfs snapshot -r $POOL/fs at snap$i
+done
+
+# Snapshot the pool and send it to the new dataset.
+log_must eval "send_doall $POOL/fs at snap3 >$BACKDIR/fs at snap3"
+log_must eval "zfs recv $POOL/newfs < $BACKDIR/fs at snap3"
+
+zfs list $POOL/newfs/child
+if [[ $? -eq 0 ]]; then
+	log_fail "Children dataset should not have been received"
+fi
+
+log_pass "Verify send_doall stream is correct"


More information about the dev-commits-src-all mailing list