diff --git a/META b/META index 0953cc51922f..9ffe90458dbd 100644 --- a/META +++ b/META @@ -6,5 +6,5 @@ Release: rc4 Release-Tags: relext License: CDDL Author: OpenZFS -Linux-Maximum: 6.4 +Linux-Maximum: 6.5 Linux-Minimum: 3.10 diff --git a/cmd/zed/agents/zfs_mod.c b/cmd/zed/agents/zfs_mod.c index ecba2d4a563e..ad52acda8e19 100644 --- a/cmd/zed/agents/zfs_mod.c +++ b/cmd/zed/agents/zfs_mod.c @@ -374,6 +374,7 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled) /* Only autoreplace bad disks */ if ((vs->vs_state != VDEV_STATE_DEGRADED) && (vs->vs_state != VDEV_STATE_FAULTED) && + (vs->vs_state != VDEV_STATE_REMOVED) && (vs->vs_state != VDEV_STATE_CANT_OPEN)) { zed_log_msg(LOG_INFO, " not autoreplacing since disk isn't in " "a bad state (currently %llu)", vs->vs_state); diff --git a/cmd/zed/zed.d/statechange-led.sh b/cmd/zed/zed.d/statechange-led.sh index 46bfc1b866f1..40cb61f17307 100755 --- a/cmd/zed/zed.d/statechange-led.sh +++ b/cmd/zed/zed.d/statechange-led.sh @@ -121,7 +121,7 @@ state_to_val() { state="$1" case "$state" in - FAULTED|DEGRADED|UNAVAIL) + FAULTED|DEGRADED|UNAVAIL|REMOVED) echo 1 ;; ONLINE) diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index 5ed25d1ea720..c344ca8eccf8 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -132,6 +132,8 @@ static int zfs_do_zone(int argc, char **argv); static int zfs_do_unzone(int argc, char **argv); #endif +static int zfs_do_help(int argc, char **argv); + /* * Enable a reasonable set of defaults for libumem debugging on DEBUG builds. */ @@ -606,6 +608,9 @@ usage(boolean_t requested) (void) fprintf(fp, gettext("\nFor the delegated permission list, run: %s\n"), "zfs allow|unallow"); + (void) fprintf(fp, + gettext("\nFor further help on a command or topic, " + "run: %s\n"), "zfs help []"); } /* @@ -4198,8 +4203,9 @@ static int set_callback(zfs_handle_t *zhp, void *data) { nvlist_t *props = data; + int ret = zfs_prop_set_list(zhp, props); - if (zfs_prop_set_list(zhp, props) != 0) { + if (ret != 0 || libzfs_errno(g_zfs) != EZFS_SUCCESS) { switch (libzfs_errno(g_zfs)) { case EZFS_MOUNTFAILED: (void) fprintf(stderr, gettext("property may be set " @@ -4210,9 +4216,8 @@ set_callback(zfs_handle_t *zhp, void *data) "but unable to reshare filesystem\n")); break; } - return (1); } - return (0); + return (ret); } static int @@ -8726,6 +8731,25 @@ zfs_do_version(int argc, char **argv) return (zfs_version_print() != 0); } +/* Display documentation */ +static int +zfs_do_help(int argc, char **argv) +{ + char page[MAXNAMELEN]; + if (argc < 3 || strcmp(argv[2], "zfs") == 0) + strcpy(page, "zfs"); + else if (strcmp(argv[2], "concepts") == 0 || + strcmp(argv[2], "props") == 0) + snprintf(page, sizeof (page), "zfs%s", argv[2]); + else + snprintf(page, sizeof (page), "zfs-%s", argv[2]); + + execlp("man", "man", page, NULL); + + fprintf(stderr, "couldn't run man program: %s", strerror(errno)); + return (-1); +} + int main(int argc, char **argv) { @@ -8781,6 +8805,12 @@ main(int argc, char **argv) if ((strcmp(cmdname, "-V") == 0) || (strcmp(cmdname, "--version") == 0)) return (zfs_do_version(argc, argv)); + /* + * Special case 'help' + */ + if (strcmp(cmdname, "help") == 0) + return (zfs_do_help(argc, argv)); + if ((g_zfs = libzfs_init()) == NULL) { (void) fprintf(stderr, "%s\n", libzfs_error_init(errno)); return (1); diff --git a/cmd/zpool/zpool_main.c b/cmd/zpool/zpool_main.c index 6d0dae8d8b05..d64fdfa5ba4c 100644 --- a/cmd/zpool/zpool_main.c +++ b/cmd/zpool/zpool_main.c @@ -126,6 +126,8 @@ static int zpool_do_version(int, char **); static int zpool_do_wait(int, char **); +static int zpool_do_help(int argc, char **argv); + static zpool_compat_status_t zpool_do_load_compat( const char *, boolean_t *); @@ -538,6 +540,10 @@ usage(boolean_t requested) (void) fprintf(fp, "%s", get_usage(command_table[i].usage)); } + + (void) fprintf(fp, + gettext("\nFor further help on a command or topic, " + "run: %s\n"), "zpool help []"); } else { (void) fprintf(fp, gettext("usage:\n")); (void) fprintf(fp, "%s", get_usage(current_command->usage)); @@ -11051,6 +11057,25 @@ zpool_do_version(int argc, char **argv) return (zfs_version_print() != 0); } +/* Display documentation */ +static int +zpool_do_help(int argc, char **argv) +{ + char page[MAXNAMELEN]; + if (argc < 3 || strcmp(argv[2], "zpool") == 0) + strcpy(page, "zpool"); + else if (strcmp(argv[2], "concepts") == 0 || + strcmp(argv[2], "props") == 0) + snprintf(page, sizeof (page), "zpool%s", argv[2]); + else + snprintf(page, sizeof (page), "zpool-%s", argv[2]); + + execlp("man", "man", page, NULL); + + fprintf(stderr, "couldn't run man program: %s", strerror(errno)); + return (-1); +} + /* * Do zpool_load_compat() and print error message on failure */ @@ -11118,6 +11143,12 @@ main(int argc, char **argv) if ((strcmp(cmdname, "-V") == 0) || (strcmp(cmdname, "--version") == 0)) return (zpool_do_version(argc, argv)); + /* + * Special case 'help' + */ + if (strcmp(cmdname, "help") == 0) + return (zpool_do_help(argc, argv)); + if ((g_zfs = libzfs_init()) == NULL) { (void) fprintf(stderr, "%s\n", libzfs_error_init(errno)); return (1); diff --git a/cmd/ztest.c b/cmd/ztest.c index 398c519cfc35..8cfbdfe1c2e2 100644 --- a/cmd/ztest.c +++ b/cmd/ztest.c @@ -2457,8 +2457,7 @@ ztest_get_data(void *arg, uint64_t arg2, lr_write_t *lr, char *buf, zgd->zgd_lr = (struct zfs_locked_range *)ztest_range_lock(zd, object, offset, size, RL_READER); - error = dmu_buf_hold(os, object, offset, zgd, &db, - DMU_READ_NO_PREFETCH); + error = dmu_buf_hold_noread(os, object, offset, zgd, &db); if (error == 0) { blkptr_t *bp = &lr->lr_blkptr; @@ -3767,7 +3766,7 @@ ztest_vdev_attach_detach(ztest_ds_t *zd, uint64_t id) else if (ashift > oldvd->vdev_top->vdev_ashift) expected_error = EDOM; else if (newvd_is_dspare && pvd != vdev_draid_spare_get_parent(newvd)) - expected_error = ENOTSUP; + expected_error = EINVAL; else expected_error = 0; @@ -6379,6 +6378,7 @@ ztest_reguid(ztest_ds_t *zd, uint64_t id) spa_t *spa = ztest_spa; uint64_t orig, load; int error; + ztest_shared_t *zs = ztest_shared; if (ztest_opts.zo_mmp_test) return; @@ -6388,6 +6388,7 @@ ztest_reguid(ztest_ds_t *zd, uint64_t id) (void) pthread_rwlock_wrlock(&ztest_name_lock); error = spa_change_guid(spa); + zs->zs_guid = spa_guid(spa); (void) pthread_rwlock_unlock(&ztest_name_lock); if (error != 0) @@ -6917,7 +6918,7 @@ ztest_trim(ztest_ds_t *zd, uint64_t id) * Verify pool integrity by running zdb. */ static void -ztest_run_zdb(const char *pool) +ztest_run_zdb(uint64_t guid) { int status; char *bin; @@ -6941,13 +6942,13 @@ ztest_run_zdb(const char *pool) free(set_gvars_args); size_t would = snprintf(zdb, len, - "%s -bcc%s%s -G -d -Y -e -y %s -p %s %s", + "%s -bcc%s%s -G -d -Y -e -y %s -p %s %"PRIu64, bin, ztest_opts.zo_verbose >= 3 ? "s" : "", ztest_opts.zo_verbose >= 4 ? "v" : "", set_gvars_args_joined, ztest_opts.zo_dir, - pool); + guid); ASSERT3U(would, <, len); umem_free(set_gvars_args_joined, strlen(set_gvars_args_joined) + 1); @@ -7525,14 +7526,15 @@ ztest_import(ztest_shared_t *zs) VERIFY0(spa_open(ztest_opts.zo_pool, &spa, FTAG)); zs->zs_metaslab_sz = 1ULL << spa->spa_root_vdev->vdev_child[0]->vdev_ms_shift; + zs->zs_guid = spa_guid(spa); spa_close(spa, FTAG); kernel_fini(); if (!ztest_opts.zo_mmp_test) { - ztest_run_zdb(ztest_opts.zo_pool); + ztest_run_zdb(zs->zs_guid); ztest_freeze(); - ztest_run_zdb(ztest_opts.zo_pool); + ztest_run_zdb(zs->zs_guid); } (void) pthread_rwlock_destroy(&ztest_name_lock); @@ -7603,7 +7605,6 @@ ztest_run(ztest_shared_t *zs) dsl_pool_config_enter(dmu_objset_pool(os), FTAG); dmu_objset_fast_stat(os, &dds); dsl_pool_config_exit(dmu_objset_pool(os), FTAG); - zs->zs_guid = dds.dds_guid; dmu_objset_disown(os, B_TRUE, FTAG); /* @@ -7874,14 +7875,15 @@ ztest_init(ztest_shared_t *zs) VERIFY0(spa_open(ztest_opts.zo_pool, &spa, FTAG)); zs->zs_metaslab_sz = 1ULL << spa->spa_root_vdev->vdev_child[0]->vdev_ms_shift; + zs->zs_guid = spa_guid(spa); spa_close(spa, FTAG); kernel_fini(); if (!ztest_opts.zo_mmp_test) { - ztest_run_zdb(ztest_opts.zo_pool); + ztest_run_zdb(zs->zs_guid); ztest_freeze(); - ztest_run_zdb(ztest_opts.zo_pool); + ztest_run_zdb(zs->zs_guid); } (void) pthread_rwlock_destroy(&ztest_name_lock); @@ -8304,7 +8306,7 @@ main(int argc, char **argv) } if (!ztest_opts.zo_mmp_test) - ztest_run_zdb(ztest_opts.zo_pool); + ztest_run_zdb(zs->zs_guid); } if (ztest_opts.zo_verbose >= 1) { diff --git a/config/kernel-blkdev.m4 b/config/kernel-blkdev.m4 index 887acee670ba..e04a2bd2c3b6 100644 --- a/config/kernel-blkdev.m4 +++ b/config/kernel-blkdev.m4 @@ -16,12 +16,63 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH], [ ]) ]) +dnl # +dnl # 6.5.x API change, +dnl # blkdev_get_by_path() takes 4 args +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH_4ARG], [ + ZFS_LINUX_TEST_SRC([blkdev_get_by_path_4arg], [ + #include + #include + ], [ + struct block_device *bdev __attribute__ ((unused)) = NULL; + const char *path = "path"; + fmode_t mode = 0; + void *holder = NULL; + struct blk_holder_ops h; + + bdev = blkdev_get_by_path(path, mode, holder, &h); + ]) +]) + AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH], [ - AC_MSG_CHECKING([whether blkdev_get_by_path() exists]) + AC_MSG_CHECKING([whether blkdev_get_by_path() exists and takes 3 args]) ZFS_LINUX_TEST_RESULT([blkdev_get_by_path], [ AC_MSG_RESULT(yes) ], [ - ZFS_LINUX_TEST_ERROR([blkdev_get_by_path()]) + AC_MSG_RESULT(no) + AC_MSG_CHECKING([whether blkdev_get_by_path() exists and takes 4 args]) + ZFS_LINUX_TEST_RESULT([blkdev_get_by_path_4arg], [ + AC_DEFINE(HAVE_BLKDEV_GET_BY_PATH_4ARG, 1, + [blkdev_get_by_path() exists and takes 4 args]) + AC_MSG_RESULT(yes) + ], [ + ZFS_LINUX_TEST_ERROR([blkdev_get_by_path()]) + ]) + ]) +]) + +dnl # +dnl # 6.5.x API change +dnl # blk_mode_t was added as a type to supercede some places where fmode_t +dnl # is used +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BLK_MODE_T], [ + ZFS_LINUX_TEST_SRC([blk_mode_t], [ + #include + #include + ], [ + blk_mode_t m __attribute((unused)) = (blk_mode_t)0; + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BLK_MODE_T], [ + AC_MSG_CHECKING([whether blk_mode_t is defined]) + ZFS_LINUX_TEST_RESULT([blk_mode_t], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BLK_MODE_T, 1, [blk_mode_t is defined]) + ], [ + AC_MSG_RESULT(no) ]) ]) @@ -41,12 +92,35 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_PUT], [ ]) ]) +dnl # +dnl # 6.5.x API change. +dnl # blkdev_put() takes (void* holder) as arg 2 +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_PUT_HOLDER], [ + ZFS_LINUX_TEST_SRC([blkdev_put_holder], [ + #include + #include + ], [ + struct block_device *bdev = NULL; + void *holder = NULL; + + blkdev_put(bdev, holder); + ]) +]) + AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_PUT], [ AC_MSG_CHECKING([whether blkdev_put() exists]) ZFS_LINUX_TEST_RESULT([blkdev_put], [ AC_MSG_RESULT(yes) ], [ - ZFS_LINUX_TEST_ERROR([blkdev_put()]) + AC_MSG_CHECKING([whether blkdev_put() accepts void* as arg 2]) + ZFS_LINUX_TEST_RESULT([blkdev_put_holder], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BLKDEV_PUT_HOLDER, 1, + [blkdev_put() accepts void* as arg 2]) + ], [ + ZFS_LINUX_TEST_ERROR([blkdev_put()]) + ]) ]) ]) @@ -495,7 +569,9 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BLK_STS_RESV_CONFLICT], [ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [ ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH + ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH_4ARG ZFS_AC_KERNEL_SRC_BLKDEV_PUT + ZFS_AC_KERNEL_SRC_BLKDEV_PUT_HOLDER ZFS_AC_KERNEL_SRC_BLKDEV_REREAD_PART ZFS_AC_KERNEL_SRC_BLKDEV_INVALIDATE_BDEV ZFS_AC_KERNEL_SRC_BLKDEV_LOOKUP_BDEV @@ -510,6 +586,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [ ZFS_AC_KERNEL_SRC_BLKDEV_PART_TO_DEV ZFS_AC_KERNEL_SRC_BLKDEV_DISK_CHECK_MEDIA_CHANGE ZFS_AC_KERNEL_SRC_BLKDEV_BLK_STS_RESV_CONFLICT + ZFS_AC_KERNEL_SRC_BLKDEV_BLK_MODE_T ]) AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [ @@ -530,4 +607,5 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [ ZFS_AC_KERNEL_BLKDEV_PART_TO_DEV ZFS_AC_KERNEL_BLKDEV_DISK_CHECK_MEDIA_CHANGE ZFS_AC_KERNEL_BLKDEV_BLK_STS_RESV_CONFLICT + ZFS_AC_KERNEL_BLKDEV_BLK_MODE_T ]) diff --git a/config/kernel-block-device-operations.m4 b/config/kernel-block-device-operations.m4 index 84e39dc8a2f6..d13c1337b1fb 100644 --- a/config/kernel-block-device-operations.m4 +++ b/config/kernel-block-device-operations.m4 @@ -49,12 +49,42 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [ ], [], []) ]) +dnl # +dnl # 5.9.x API change +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG], [ + ZFS_LINUX_TEST_SRC([block_device_operations_release_void_1arg], [ + #include + + void blk_release(struct gendisk *g) { + (void) g; + return; + } + + static const struct block_device_operations + bops __attribute__ ((unused)) = { + .open = NULL, + .release = blk_release, + .ioctl = NULL, + .compat_ioctl = NULL, + }; + ], [], []) +]) + AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [ - AC_MSG_CHECKING([whether bops->release() is void]) + AC_MSG_CHECKING([whether bops->release() is void and takes 2 args]) ZFS_LINUX_TEST_RESULT([block_device_operations_release_void], [ AC_MSG_RESULT(yes) ],[ - ZFS_LINUX_TEST_ERROR([bops->release()]) + AC_MSG_RESULT(no) + AC_MSG_CHECKING([whether bops->release() is void and takes 1 arg]) + ZFS_LINUX_TEST_RESULT([block_device_operations_release_void_1arg], [ + AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG], [1], + [Define if release() in block_device_operations takes 1 arg]) + ],[ + ZFS_LINUX_TEST_ERROR([bops->release()]) + ]) ]) ]) @@ -92,6 +122,7 @@ AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK], [ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS], [ ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID + ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK ]) diff --git a/config/kernel-filemap-splice-read.m4 b/config/kernel-filemap-splice-read.m4 new file mode 100644 index 000000000000..4c83b31d738a --- /dev/null +++ b/config/kernel-filemap-splice-read.m4 @@ -0,0 +1,25 @@ +AC_DEFUN([ZFS_AC_KERNEL_SRC_COPY_SPLICE_READ], [ + dnl # + dnl # Kernel 6.5 - generic_file_splice_read was removed in favor + dnl # of copy_splice_read for the .splice_read member of the + dnl # file_operations struct. + dnl # + ZFS_LINUX_TEST_SRC([has_copy_splice_read], [ + #include + + struct file_operations fops __attribute__((unused)) = { + .splice_read = copy_splice_read, + }; + ],[]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_COPY_SPLICE_READ], [ + AC_MSG_CHECKING([whether copy_splice_read() exists]) + ZFS_LINUX_TEST_RESULT([has_copy_splice_read], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_COPY_SPLICE_READ, 1, + [copy_splice_read exists]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-register_sysctl_table.m4 b/config/kernel-register_sysctl_table.m4 new file mode 100644 index 000000000000..a5e934f56d29 --- /dev/null +++ b/config/kernel-register_sysctl_table.m4 @@ -0,0 +1,27 @@ +dnl # +dnl # Linux 6.5 removes register_sysctl_table +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_TABLE], [ + ZFS_LINUX_TEST_SRC([has_register_sysctl_table], [ + #include + + static struct ctl_table dummy_table[] = { + {} + }; + + ],[ + struct ctl_table_header *h + __attribute((unused)) = register_sysctl_table(dummy_table); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_REGISTER_SYSCTL_TABLE], [ + AC_MSG_CHECKING([whether register_sysctl_table exists]) + ZFS_LINUX_TEST_RESULT([has_register_sysctl_table], [ + AC_MSG_RESULT([yes]) + AC_DEFINE(HAVE_REGISTER_SYSCTL_TABLE, 1, + [register_sysctl_table exists]) + ],[ + AC_MSG_RESULT([no]) + ]) +]) diff --git a/config/kernel-vfs-iov_iter.m4 b/config/kernel-vfs-iov_iter.m4 index e0617faab02c..ff560ff3eef0 100644 --- a/config/kernel-vfs-iov_iter.m4 +++ b/config/kernel-vfs-iov_iter.m4 @@ -6,8 +6,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_IOV_ITER], [ #include #include ],[ - int type __attribute__ ((unused)) = - ITER_IOVEC | ITER_KVEC | ITER_BVEC | ITER_PIPE; + int type __attribute__ ((unused)) = ITER_KVEC; ]) ZFS_LINUX_TEST_SRC([iov_iter_advance], [ @@ -93,6 +92,14 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_IOV_ITER], [ struct iov_iter iter = { 0 }; __attribute__((unused)) enum iter_type i = iov_iter_type(&iter); ]) + + ZFS_LINUX_TEST_SRC([iter_iov], [ + #include + #include + ],[ + struct iov_iter iter = { 0 }; + __attribute__((unused)) const struct iovec *iov = iter_iov(&iter); + ]) ]) AC_DEFUN([ZFS_AC_KERNEL_VFS_IOV_ITER], [ @@ -201,4 +208,19 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_IOV_ITER], [ AC_DEFINE(HAVE_VFS_IOV_ITER, 1, [All required iov_iter interfaces are available]) ]) + + dnl # + dnl # Kernel 6.5 introduces the iter_iov() function that returns the + dnl # __iov member of an iov_iter*. The iov member was renamed to this + dnl # __iov member, and is intended to be accessed via the helper + dnl # function now. + dnl # + AC_MSG_CHECKING([whether iter_iov() is available]) + ZFS_LINUX_TEST_RESULT([iter_iov], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_ITER_IOV, 1, + [iter_iov() is available]) + ],[ + AC_MSG_RESULT(no) + ]) ]) diff --git a/config/kernel.m4 b/config/kernel.m4 index 1487fa2e7793..df194ec72207 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -160,6 +160,8 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [ ZFS_AC_KERNEL_SRC_FILEMAP ZFS_AC_KERNEL_SRC_WRITEPAGE_T ZFS_AC_KERNEL_SRC_RECLAIMED + ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_TABLE + ZFS_AC_KERNEL_SRC_COPY_SPLICE_READ case "$host_cpu" in powerpc*) ZFS_AC_KERNEL_SRC_CPU_HAS_FEATURE @@ -299,6 +301,8 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [ ZFS_AC_KERNEL_FILEMAP ZFS_AC_KERNEL_WRITEPAGE_T ZFS_AC_KERNEL_RECLAIMED + ZFS_AC_KERNEL_REGISTER_SYSCTL_TABLE + ZFS_AC_KERNEL_COPY_SPLICE_READ case "$host_cpu" in powerpc*) ZFS_AC_KERNEL_CPU_HAS_FEATURE diff --git a/contrib/debian/rules.in b/contrib/debian/rules.in index 9ff28b663b5f..e8cb5aa0ce3d 100755 --- a/contrib/debian/rules.in +++ b/contrib/debian/rules.in @@ -168,7 +168,6 @@ override_dh_installinit: dh_installinit -r --no-restart-after-upgrade --name zfs-import dh_installinit -r --no-restart-after-upgrade --name zfs-mount dh_installinit -r --no-restart-after-upgrade --name zfs-load-key - dh_installinit -R --name zfs-share dh_installinit -R --name zfs-zed override_dh_installsystemd: diff --git a/etc/systemd/system/50-zfs.preset b/etc/systemd/system/50-zfs.preset index e4056a92cd98..d2da85d330eb 100644 --- a/etc/systemd/system/50-zfs.preset +++ b/etc/systemd/system/50-zfs.preset @@ -3,7 +3,7 @@ enable zfs-import-cache.service disable zfs-import-scan.service enable zfs-import.target enable zfs-mount.service -enable zfs-share.service +disable zfs-share.service enable zfs-zed.service enable zfs-volume-wait.service enable zfs.target diff --git a/etc/systemd/system/zfs-share.service.in b/etc/systemd/system/zfs-share.service.in index 1a6342a06fec..7c90f74a684a 100644 --- a/etc/systemd/system/zfs-share.service.in +++ b/etc/systemd/system/zfs-share.service.in @@ -17,4 +17,4 @@ EnvironmentFile=-@initconfdir@/zfs ExecStart=@sbindir@/zfs share -a [Install] -WantedBy=zfs.target +WantedBy=multi-user.target diff --git a/include/os/freebsd/zfs/sys/zfs_vfsops_os.h b/include/os/freebsd/zfs/sys/zfs_vfsops_os.h index f765d38dbac8..24bb03575f33 100644 --- a/include/os/freebsd/zfs/sys/zfs_vfsops_os.h +++ b/include/os/freebsd/zfs/sys/zfs_vfsops_os.h @@ -93,7 +93,6 @@ struct zfsvfs { zfs_teardown_lock_t z_teardown_lock; zfs_teardown_inactive_lock_t z_teardown_inactive_lock; list_t z_all_znodes; /* all vnodes in the fs */ - uint64_t z_nr_znodes; /* number of znodes in the fs */ kmutex_t z_znodes_lock; /* lock for z_all_znodes */ struct zfsctl_root *z_ctldir; /* .zfs directory pointer */ boolean_t z_show_ctldir; /* expose .zfs in the root dir */ diff --git a/include/os/linux/kernel/linux/blkdev_compat.h b/include/os/linux/kernel/linux/blkdev_compat.h index e0f20ba32008..f111e648ccf7 100644 --- a/include/os/linux/kernel/linux/blkdev_compat.h +++ b/include/os/linux/kernel/linux/blkdev_compat.h @@ -347,6 +347,7 @@ zfs_check_media_change(struct block_device *bdev) #define vdev_bdev_reread_part(bdev) zfs_check_media_change(bdev) #elif defined(HAVE_DISK_CHECK_MEDIA_CHANGE) #define vdev_bdev_reread_part(bdev) disk_check_media_change(bdev->bd_disk) +#define zfs_check_media_change(bdev) disk_check_media_change(bdev->bd_disk) #else /* * This is encountered if check_disk_change() and bdev_check_media_change() @@ -397,6 +398,12 @@ vdev_lookup_bdev(const char *path, dev_t *dev) #endif } +#if defined(HAVE_BLK_MODE_T) +#define blk_mode_is_open_write(flag) ((flag) & BLK_OPEN_WRITE) +#else +#define blk_mode_is_open_write(flag) ((flag) & FMODE_WRITE) +#endif + /* * Kernels without bio_set_op_attrs use bi_rw for the bio flags. */ diff --git a/include/os/linux/spl/sys/uio.h b/include/os/linux/spl/sys/uio.h index fe2b5c07a018..cce097e16fbc 100644 --- a/include/os/linux/spl/sys/uio.h +++ b/include/os/linux/spl/sys/uio.h @@ -173,4 +173,16 @@ zfs_uio_iov_iter_init(zfs_uio_t *uio, struct iov_iter *iter, offset_t offset, } #endif +#if defined(HAVE_ITER_IOV) +#define zfs_uio_iter_iov(iter) iter_iov((iter)) +#else +#define zfs_uio_iter_iov(iter) (iter)->iov +#endif + +#if defined(HAVE_IOV_ITER_TYPE) +#define zfs_uio_iov_iter_type(iter) iov_iter_type((iter)) +#else +#define zfs_uio_iov_iter_type(iter) (iter)->type +#endif + #endif /* SPL_UIO_H */ diff --git a/include/os/linux/zfs/sys/zfs_vfsops_os.h b/include/os/linux/zfs/sys/zfs_vfsops_os.h index e320b8de4222..b4d5db21f5e5 100644 --- a/include/os/linux/zfs/sys/zfs_vfsops_os.h +++ b/include/os/linux/zfs/sys/zfs_vfsops_os.h @@ -105,7 +105,6 @@ struct zfsvfs { rrmlock_t z_teardown_lock; krwlock_t z_teardown_inactive_lock; list_t z_all_znodes; /* all znodes in the fs */ - uint64_t z_nr_znodes; /* number of znodes in the fs */ unsigned long z_rollback_time; /* last online rollback time */ unsigned long z_snap_defer_time; /* last snapshot unmount deferral */ kmutex_t z_znodes_lock; /* lock for z_all_znodes */ diff --git a/lib/libshare/os/freebsd/nfs.c b/lib/libshare/os/freebsd/nfs.c index 521631c51f07..d9fc66106369 100644 --- a/lib/libshare/os/freebsd/nfs.c +++ b/lib/libshare/os/freebsd/nfs.c @@ -161,7 +161,8 @@ nfs_is_shared(sa_share_impl_t impl_share) static int nfs_validate_shareopts(const char *shareopts) { - (void) shareopts; + if (strlen(shareopts) == 0) + return (SA_SYNTAX_ERR); return (SA_OK); } diff --git a/lib/libshare/os/linux/nfs.c b/lib/libshare/os/linux/nfs.c index c27e5564c1e1..004946b0cfe4 100644 --- a/lib/libshare/os/linux/nfs.c +++ b/lib/libshare/os/linux/nfs.c @@ -319,12 +319,49 @@ get_linux_shareopts_cb(const char *key, const char *value, void *cookie) "wdelay" }; char **plinux_opts = (char **)cookie; + char *host, *val_dup, *literal, *next; - /* host-specific options, these are taken care of elsewhere */ - if (strcmp(key, "ro") == 0 || strcmp(key, "rw") == 0 || - strcmp(key, "sec") == 0) + if (strcmp(key, "sec") == 0) return (SA_OK); + if (strcmp(key, "ro") == 0 || strcmp(key, "rw") == 0) { + if (value == NULL || strlen(value) == 0) + return (SA_OK); + val_dup = strdup(value); + host = val_dup; + if (host == NULL) + return (SA_NO_MEMORY); + do { + if (*host == '[') { + host++; + literal = strchr(host, ']'); + if (literal == NULL) { + free(val_dup); + return (SA_SYNTAX_ERR); + } + if (literal[1] == '\0') + next = NULL; + else if (literal[1] == '/') { + next = strchr(literal + 2, ':'); + if (next != NULL) + ++next; + } else if (literal[1] == ':') + next = literal + 2; + else { + free(val_dup); + return (SA_SYNTAX_ERR); + } + } else { + next = strchr(host, ':'); + if (next != NULL) + ++next; + } + host = next; + } while (host != NULL); + free(val_dup); + return (SA_OK); + } + if (strcmp(key, "anon") == 0) key = "anonuid"; @@ -472,6 +509,10 @@ static int nfs_validate_shareopts(const char *shareopts) { char *linux_opts = NULL; + + if (strlen(shareopts) == 0) + return (SA_SYNTAX_ERR); + int error = get_linux_shareopts(shareopts, &linux_opts); if (error != SA_OK) return (error); diff --git a/lib/libzfs/libzfs_changelist.c b/lib/libzfs/libzfs_changelist.c index dd14c570ec03..efe1c0c06035 100644 --- a/lib/libzfs/libzfs_changelist.c +++ b/lib/libzfs/libzfs_changelist.c @@ -174,7 +174,6 @@ changelist_postfix(prop_changelist_t *clp) prop_changenode_t *cn; uu_avl_walk_t *walk; char shareopts[ZFS_MAXPROPLEN]; - int errors = 0; boolean_t commit_smb_shares = B_FALSE; boolean_t commit_nfs_shares = B_FALSE; @@ -244,13 +243,13 @@ changelist_postfix(prop_changelist_t *clp) zfs_is_mounted(cn->cn_handle, NULL); if (!mounted && !needs_key && (cn->cn_mounted || - ((sharenfs || sharesmb || clp->cl_waslegacy) && + (((clp->cl_prop == ZFS_PROP_MOUNTPOINT && + clp->cl_prop == clp->cl_realprop) || + sharenfs || sharesmb || clp->cl_waslegacy) && (zfs_prop_get_int(cn->cn_handle, ZFS_PROP_CANMOUNT) == ZFS_CANMOUNT_ON)))) { - if (zfs_mount(cn->cn_handle, NULL, 0) != 0) - errors++; - else + if (zfs_mount(cn->cn_handle, NULL, 0) == 0) mounted = TRUE; } @@ -262,19 +261,19 @@ changelist_postfix(prop_changelist_t *clp) const enum sa_protocol nfs[] = {SA_PROTOCOL_NFS, SA_NO_PROTOCOL}; if (sharenfs && mounted) { - errors += zfs_share(cn->cn_handle, nfs); + zfs_share(cn->cn_handle, nfs); commit_nfs_shares = B_TRUE; } else if (cn->cn_shared || clp->cl_waslegacy) { - errors += zfs_unshare(cn->cn_handle, NULL, nfs); + zfs_unshare(cn->cn_handle, NULL, nfs); commit_nfs_shares = B_TRUE; } const enum sa_protocol smb[] = {SA_PROTOCOL_SMB, SA_NO_PROTOCOL}; if (sharesmb && mounted) { - errors += zfs_share(cn->cn_handle, smb); + zfs_share(cn->cn_handle, smb); commit_smb_shares = B_TRUE; } else if (cn->cn_shared || clp->cl_waslegacy) { - errors += zfs_unshare(cn->cn_handle, NULL, smb); + zfs_unshare(cn->cn_handle, NULL, smb); commit_smb_shares = B_TRUE; } } @@ -288,7 +287,7 @@ changelist_postfix(prop_changelist_t *clp) zfs_commit_shares(proto); uu_avl_walk_end(walk); - return (errors ? -1 : 0); + return (0); } /* diff --git a/lib/libzfs/libzfs_pool.c b/lib/libzfs/libzfs_pool.c index a28ec7745c90..916abd07e633 100644 --- a/lib/libzfs/libzfs_pool.c +++ b/lib/libzfs/libzfs_pool.c @@ -29,7 +29,7 @@ * Copyright (c) 2017, Intel Corporation. * Copyright (c) 2018, loli10K * Copyright (c) 2021, Colm Buckley - * Copyright (c) 2021, Klara Inc. + * Copyright (c) 2021, 2023, Klara Inc. */ #include @@ -255,6 +255,7 @@ zpool_get_state_str(zpool_handle_t *zhp) if (zpool_get_state(zhp) == POOL_STATE_UNAVAIL) { str = gettext("FAULTED"); } else if (status == ZPOOL_STATUS_IO_FAILURE_WAIT || + status == ZPOOL_STATUS_IO_FAILURE_CONTINUE || status == ZPOOL_STATUS_IO_FAILURE_MMP) { str = gettext("SUSPENDED"); } else { diff --git a/lib/libzfs_core/libzfs_core.c b/lib/libzfs_core/libzfs_core.c index c63a16de5ab6..01d803e21db0 100644 --- a/lib/libzfs_core/libzfs_core.c +++ b/lib/libzfs_core/libzfs_core.c @@ -650,10 +650,12 @@ send_worker(void *arg) unsigned int bufsiz = max_pipe_buffer(ctx->from); ssize_t rd; - while ((rd = splice(ctx->from, NULL, ctx->to, NULL, bufsiz, - SPLICE_F_MOVE | SPLICE_F_MORE)) > 0) - ; - + for (;;) { + rd = splice(ctx->from, NULL, ctx->to, NULL, bufsiz, + SPLICE_F_MOVE | SPLICE_F_MORE); + if ((rd == -1 && errno != EINTR) || rd == 0) + break; + } int err = (rd == -1) ? errno : 0; close(ctx->from); return ((void *)(uintptr_t)err); diff --git a/man/man7/zpoolconcepts.7 b/man/man7/zpoolconcepts.7 index db3fd4926236..98f3ee7cd660 100644 --- a/man/man7/zpoolconcepts.7 +++ b/man/man7/zpoolconcepts.7 @@ -203,11 +203,9 @@ For more information, see the section. .El .Pp -Virtual devices cannot be nested, so a mirror or raidz virtual device can only -contain files or disks. -Mirrors of mirrors -.Pq or other combinations -are not allowed. +Virtual devices cannot be nested arbitrarily. +A mirror, raidz or draid virtual device can only be created with files or disks. +Mirrors of mirrors or other such combinations are not allowed. .Pp A pool can have any number of virtual devices at the top of the configuration .Po known as diff --git a/module/Makefile.in b/module/Makefile.in index 4f99e3f31ea2..d42d9cc1f804 100644 --- a/module/Makefile.in +++ b/module/Makefile.in @@ -169,4 +169,4 @@ gen-zstd-symbols: for obj in $(addprefix zstd/,$(ZSTD_UPSTREAM_OBJS)); do echo; echo "/* $${obj#zstd/}: */"; @OBJDUMP@ -t $$obj | awk '$$2 == "g" && !/ zfs_/ {print "#define\t" $$6 " zfs_" $$6}' | sort; done >> zstd/include/zstd_compat_wrapper.h check-zstd-symbols: - @OBJDUMP@ -t $(addprefix zstd/,$(ZSTD_UPSTREAM_OBJS)) | awk '/file format/ {print} $$2 == "g" && !/ zfs_/ {++ret; print} END {exit ret}' + @OBJDUMP@ -t $(addprefix zstd/,$(ZSTD_UPSTREAM_OBJS)) | awk '/file format/ {print} $$2 == "g" && (!/ zfs_/ && !/ __pfx_zfs_/) {++ret; print} END {exit ret}' diff --git a/module/os/freebsd/zfs/zfs_vfsops.c b/module/os/freebsd/zfs/zfs_vfsops.c index 33759fa26169..e8b9ada1316b 100644 --- a/module/os/freebsd/zfs/zfs_vfsops.c +++ b/module/os/freebsd/zfs/zfs_vfsops.c @@ -1154,7 +1154,6 @@ zfsvfs_free(zfsvfs_t *zfsvfs) mutex_destroy(&zfsvfs->z_znodes_lock); mutex_destroy(&zfsvfs->z_lock); - ASSERT3U(zfsvfs->z_nr_znodes, ==, 0); list_destroy(&zfsvfs->z_all_znodes); ZFS_TEARDOWN_DESTROY(zfsvfs); ZFS_TEARDOWN_INACTIVE_DESTROY(zfsvfs); @@ -1558,12 +1557,11 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting) * may add the parents of dir-based xattrs to the taskq * so we want to wait for these. * - * We can safely read z_nr_znodes without locking because the - * VFS has already blocked operations which add to the - * z_all_znodes list and thus increment z_nr_znodes. + * We can safely check z_all_znodes for being empty because the + * VFS has already blocked operations which add to it. */ int round = 0; - while (zfsvfs->z_nr_znodes > 0) { + while (!list_is_empty(&zfsvfs->z_all_znodes)) { taskq_wait_outstanding(dsl_pool_zrele_taskq( dmu_objset_pool(zfsvfs->z_os)), 0); if (++round > 1 && !unmounting) diff --git a/module/os/freebsd/zfs/zfs_znode.c b/module/os/freebsd/zfs/zfs_znode.c index c4f2b722ef4e..0d4c94555c6b 100644 --- a/module/os/freebsd/zfs/zfs_znode.c +++ b/module/os/freebsd/zfs/zfs_znode.c @@ -537,7 +537,6 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz, mutex_enter(&zfsvfs->z_znodes_lock); list_insert_tail(&zfsvfs->z_all_znodes, zp); - zfsvfs->z_nr_znodes++; zp->z_zfsvfs = zfsvfs; mutex_exit(&zfsvfs->z_znodes_lock); @@ -1286,7 +1285,6 @@ zfs_znode_free(znode_t *zp) mutex_enter(&zfsvfs->z_znodes_lock); POINTER_INVALIDATE(&zp->z_zfsvfs); list_remove(&zfsvfs->z_all_znodes, zp); - zfsvfs->z_nr_znodes--; mutex_exit(&zfsvfs->z_znodes_lock); #if __FreeBSD_version >= 1300139 diff --git a/module/os/linux/spl/spl-proc.c b/module/os/linux/spl/spl-proc.c index 01f5619e1893..f0f929d3ce90 100644 --- a/module/os/linux/spl/spl-proc.c +++ b/module/os/linux/spl/spl-proc.c @@ -47,6 +47,10 @@ static unsigned long table_min = 0; static unsigned long table_max = ~0; static struct ctl_table_header *spl_header = NULL; +#ifndef HAVE_REGISTER_SYSCTL_TABLE +static struct ctl_table_header *spl_kmem = NULL; +static struct ctl_table_header *spl_kstat = NULL; +#endif static struct proc_dir_entry *proc_spl = NULL; static struct proc_dir_entry *proc_spl_kmem = NULL; static struct proc_dir_entry *proc_spl_kmem_slab = NULL; @@ -624,6 +628,7 @@ static struct ctl_table spl_table[] = { .mode = 0644, .proc_handler = &proc_dohostid, }, +#ifdef HAVE_REGISTER_SYSCTL_TABLE { .procname = "kmem", .mode = 0555, @@ -634,9 +639,11 @@ static struct ctl_table spl_table[] = { .mode = 0555, .child = spl_kstat_table, }, +#endif {}, }; +#ifdef HAVE_REGISTER_SYSCTL_TABLE static struct ctl_table spl_dir[] = { { .procname = "spl", @@ -648,21 +655,64 @@ static struct ctl_table spl_dir[] = { static struct ctl_table spl_root[] = { { - .procname = "kernel", - .mode = 0555, - .child = spl_dir, + .procname = "kernel", + .mode = 0555, + .child = spl_dir, }, {} }; +#endif + +static void spl_proc_cleanup(void) +{ + remove_proc_entry("kstat", proc_spl); + remove_proc_entry("slab", proc_spl_kmem); + remove_proc_entry("kmem", proc_spl); + remove_proc_entry("taskq-all", proc_spl); + remove_proc_entry("taskq", proc_spl); + remove_proc_entry("spl", NULL); + +#ifndef HAVE_REGISTER_SYSCTL_TABLE + if (spl_kstat) { + unregister_sysctl_table(spl_kstat); + spl_kstat = NULL; + } + if (spl_kmem) { + unregister_sysctl_table(spl_kmem); + spl_kmem = NULL; + } +#endif + if (spl_header) { + unregister_sysctl_table(spl_header); + spl_header = NULL; + } +} int spl_proc_init(void) { int rc = 0; +#ifdef HAVE_REGISTER_SYSCTL_TABLE spl_header = register_sysctl_table(spl_root); if (spl_header == NULL) return (-EUNATCH); +#else + spl_header = register_sysctl("kernel/spl", spl_table); + if (spl_header == NULL) + return (-EUNATCH); + + spl_kmem = register_sysctl("kernel/spl/kmem", spl_kmem_table); + if (spl_kmem == NULL) { + rc = -EUNATCH; + goto out; + } + spl_kstat = register_sysctl("kernel/spl/kstat", spl_kstat_table); + if (spl_kstat == NULL) { + rc = -EUNATCH; + goto out; + } +#endif proc_spl = proc_mkdir("spl", NULL); if (proc_spl == NULL) { @@ -703,15 +753,8 @@ spl_proc_init(void) goto out; } out: - if (rc) { - remove_proc_entry("kstat", proc_spl); - remove_proc_entry("slab", proc_spl_kmem); - remove_proc_entry("kmem", proc_spl); - remove_proc_entry("taskq-all", proc_spl); - remove_proc_entry("taskq", proc_spl); - remove_proc_entry("spl", NULL); - unregister_sysctl_table(spl_header); - } + if (rc) + spl_proc_cleanup(); return (rc); } @@ -719,13 +762,5 @@ spl_proc_init(void) void spl_proc_fini(void) { - remove_proc_entry("kstat", proc_spl); - remove_proc_entry("slab", proc_spl_kmem); - remove_proc_entry("kmem", proc_spl); - remove_proc_entry("taskq-all", proc_spl); - remove_proc_entry("taskq", proc_spl); - remove_proc_entry("spl", NULL); - - ASSERT(spl_header != NULL); - unregister_sysctl_table(spl_header); + spl_proc_cleanup(); } diff --git a/module/os/linux/zfs/vdev_disk.c b/module/os/linux/zfs/vdev_disk.c index 925ee9d9fe9c..48ac55f07034 100644 --- a/module/os/linux/zfs/vdev_disk.c +++ b/module/os/linux/zfs/vdev_disk.c @@ -80,9 +80,22 @@ typedef struct dio_request { static unsigned int zfs_vdev_failfast_mask = 1; +#ifdef HAVE_BLK_MODE_T +static blk_mode_t +#else static fmode_t +#endif vdev_bdev_mode(spa_mode_t spa_mode) { +#ifdef HAVE_BLK_MODE_T + blk_mode_t mode = 0; + + if (spa_mode & SPA_MODE_READ) + mode |= BLK_OPEN_READ; + + if (spa_mode & SPA_MODE_WRITE) + mode |= BLK_OPEN_WRITE; +#else fmode_t mode = 0; if (spa_mode & SPA_MODE_READ) @@ -90,6 +103,7 @@ vdev_bdev_mode(spa_mode_t spa_mode) if (spa_mode & SPA_MODE_WRITE) mode |= FMODE_WRITE; +#endif return (mode); } @@ -197,12 +211,47 @@ vdev_disk_kobj_evt_post(vdev_t *v) } } +#if !defined(HAVE_BLKDEV_GET_BY_PATH_4ARG) +/* + * Define a dummy struct blk_holder_ops for kernel versions + * prior to 6.5. + */ +struct blk_holder_ops {}; +#endif + +static struct block_device * +vdev_blkdev_get_by_path(const char *path, spa_mode_t mode, void *holder, + const struct blk_holder_ops *hops) +{ +#ifdef HAVE_BLKDEV_GET_BY_PATH_4ARG + return (blkdev_get_by_path(path, + vdev_bdev_mode(mode) | BLK_OPEN_EXCL, holder, hops)); +#else + return (blkdev_get_by_path(path, + vdev_bdev_mode(mode) | FMODE_EXCL, holder)); +#endif +} + +static void +vdev_blkdev_put(struct block_device *bdev, spa_mode_t mode, void *holder) +{ +#ifdef HAVE_BLKDEV_PUT_HOLDER + return (blkdev_put(bdev, holder)); +#else + return (blkdev_put(bdev, vdev_bdev_mode(mode) | FMODE_EXCL)); +#endif +} + static int vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize, uint64_t *logical_ashift, uint64_t *physical_ashift) { struct block_device *bdev; +#ifdef HAVE_BLK_MODE_T + blk_mode_t mode = vdev_bdev_mode(spa_mode(v->vdev_spa)); +#else fmode_t mode = vdev_bdev_mode(spa_mode(v->vdev_spa)); +#endif hrtime_t timeout = MSEC2NSEC(zfs_vdev_open_timeout_ms); vdev_disk_t *vd; @@ -252,15 +301,15 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize, reread_part = B_TRUE; } - blkdev_put(bdev, mode | FMODE_EXCL); + vdev_blkdev_put(bdev, mode, zfs_vdev_holder); } if (reread_part) { - bdev = blkdev_get_by_path(disk_name, mode | FMODE_EXCL, - zfs_vdev_holder); + bdev = vdev_blkdev_get_by_path(disk_name, mode, + zfs_vdev_holder, NULL); if (!IS_ERR(bdev)) { int error = vdev_bdev_reread_part(bdev); - blkdev_put(bdev, mode | FMODE_EXCL); + vdev_blkdev_put(bdev, mode, zfs_vdev_holder); if (error == 0) { timeout = MSEC2NSEC( zfs_vdev_open_timeout_ms * 2); @@ -305,8 +354,8 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize, hrtime_t start = gethrtime(); bdev = ERR_PTR(-ENXIO); while (IS_ERR(bdev) && ((gethrtime() - start) < timeout)) { - bdev = blkdev_get_by_path(v->vdev_path, mode | FMODE_EXCL, - zfs_vdev_holder); + bdev = vdev_blkdev_get_by_path(v->vdev_path, mode, + zfs_vdev_holder, NULL); if (unlikely(PTR_ERR(bdev) == -ENOENT)) { /* * There is no point of waiting since device is removed @@ -382,8 +431,8 @@ vdev_disk_close(vdev_t *v) return; if (vd->vd_bdev != NULL) { - blkdev_put(vd->vd_bdev, - vdev_bdev_mode(spa_mode(v->vdev_spa)) | FMODE_EXCL); + vdev_blkdev_put(vd->vd_bdev, spa_mode(v->vdev_spa), + zfs_vdev_holder); } rw_destroy(&vd->vd_lock); diff --git a/module/os/linux/zfs/zfs_ctldir.c b/module/os/linux/zfs/zfs_ctldir.c index c45a3eb5a4eb..02cb379ea840 100644 --- a/module/os/linux/zfs/zfs_ctldir.c +++ b/module/os/linux/zfs/zfs_ctldir.c @@ -537,7 +537,6 @@ zfsctl_inode_alloc(zfsvfs_t *zfsvfs, uint64_t id, mutex_enter(&zfsvfs->z_znodes_lock); list_insert_tail(&zfsvfs->z_all_znodes, zp); - zfsvfs->z_nr_znodes++; membar_producer(); mutex_exit(&zfsvfs->z_znodes_lock); diff --git a/module/os/linux/zfs/zfs_vfsops.c b/module/os/linux/zfs/zfs_vfsops.c index e7b237e68261..8f75291f7ccf 100644 --- a/module/os/linux/zfs/zfs_vfsops.c +++ b/module/os/linux/zfs/zfs_vfsops.c @@ -1348,12 +1348,11 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting) * may add the parents of dir-based xattrs to the taskq * so we want to wait for these. * - * We can safely read z_nr_znodes without locking because the - * VFS has already blocked operations which add to the - * z_all_znodes list and thus increment z_nr_znodes. + * We can safely check z_all_znodes for being empty because the + * VFS has already blocked operations which add to it. */ int round = 0; - while (zfsvfs->z_nr_znodes > 0) { + while (!list_is_empty(&zfsvfs->z_all_znodes)) { taskq_wait_outstanding(dsl_pool_zrele_taskq( dmu_objset_pool(zfsvfs->z_os)), 0); if (++round > 1 && !unmounting) diff --git a/module/os/linux/zfs/zfs_vnops_os.c b/module/os/linux/zfs/zfs_vnops_os.c index a940b5a00e8e..e8594a994c08 100644 --- a/module/os/linux/zfs/zfs_vnops_os.c +++ b/module/os/linux/zfs/zfs_vnops_os.c @@ -186,7 +186,7 @@ zfs_open(struct inode *ip, int mode, int flag, cred_t *cr) return (error); /* Honor ZFS_APPENDONLY file attribute */ - if ((mode & FMODE_WRITE) && (zp->z_pflags & ZFS_APPENDONLY) && + if (blk_mode_is_open_write(mode) && (zp->z_pflags & ZFS_APPENDONLY) && ((flag & O_APPEND) == 0)) { zfs_exit(zfsvfs, FTAG); return (SET_ERROR(EPERM)); diff --git a/module/os/linux/zfs/zfs_znode.c b/module/os/linux/zfs/zfs_znode.c index 335ae3460c58..52c8e51df659 100644 --- a/module/os/linux/zfs/zfs_znode.c +++ b/module/os/linux/zfs/zfs_znode.c @@ -390,7 +390,6 @@ zfs_inode_destroy(struct inode *ip) mutex_enter(&zfsvfs->z_znodes_lock); if (list_link_active(&zp->z_link_node)) { list_remove(&zfsvfs->z_all_znodes, zp); - zfsvfs->z_nr_znodes--; } mutex_exit(&zfsvfs->z_znodes_lock); @@ -641,7 +640,6 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz, mutex_enter(&zfsvfs->z_znodes_lock); list_insert_tail(&zfsvfs->z_all_znodes, zp); - zfsvfs->z_nr_znodes++; mutex_exit(&zfsvfs->z_znodes_lock); if (links > 0) diff --git a/module/os/linux/zfs/zpl_ctldir.c b/module/os/linux/zfs/zpl_ctldir.c index 68a7de78f471..7786444fea35 100644 --- a/module/os/linux/zfs/zpl_ctldir.c +++ b/module/os/linux/zfs/zpl_ctldir.c @@ -42,7 +42,7 @@ static int zpl_common_open(struct inode *ip, struct file *filp) { - if (filp->f_mode & FMODE_WRITE) + if (blk_mode_is_open_write(filp->f_mode)) return (-EACCES); return (generic_file_open(ip, filp)); diff --git a/module/os/linux/zfs/zpl_file.c b/module/os/linux/zfs/zpl_file.c index 73526db731c4..3caa0fc6c214 100644 --- a/module/os/linux/zfs/zpl_file.c +++ b/module/os/linux/zfs/zpl_file.c @@ -301,15 +301,10 @@ zpl_uio_init(zfs_uio_t *uio, struct kiocb *kiocb, struct iov_iter *to, #if defined(HAVE_VFS_IOV_ITER) zfs_uio_iov_iter_init(uio, to, pos, count, skip); #else -#ifdef HAVE_IOV_ITER_TYPE - zfs_uio_iovec_init(uio, to->iov, to->nr_segs, pos, - iov_iter_type(to) & ITER_KVEC ? UIO_SYSSPACE : UIO_USERSPACE, + zfs_uio_iovec_init(uio, zfs_uio_iter_iov(to), to->nr_segs, pos, + zfs_uio_iov_iter_type(to) & ITER_KVEC ? + UIO_SYSSPACE : UIO_USERSPACE, count, skip); -#else - zfs_uio_iovec_init(uio, to->iov, to->nr_segs, pos, - to->type & ITER_KVEC ? UIO_SYSSPACE : UIO_USERSPACE, - count, skip); -#endif #endif } @@ -1328,7 +1323,11 @@ const struct file_operations zpl_file_operations = { .read_iter = zpl_iter_read, .write_iter = zpl_iter_write, #ifdef HAVE_VFS_IOV_ITER +#ifdef HAVE_COPY_SPLICE_READ + .splice_read = copy_splice_read, +#else .splice_read = generic_file_splice_read, +#endif .splice_write = iter_file_splice_write, #endif #else diff --git a/module/os/linux/zfs/zvol_os.c b/module/os/linux/zfs/zvol_os.c index 38bc8e2c4eeb..7a95b54bdf0d 100644 --- a/module/os/linux/zfs/zvol_os.c +++ b/module/os/linux/zfs/zvol_os.c @@ -671,7 +671,11 @@ zvol_request(struct request_queue *q, struct bio *bio) } static int +#ifdef HAVE_BLK_MODE_T +zvol_open(struct gendisk *disk, blk_mode_t flag) +#else zvol_open(struct block_device *bdev, fmode_t flag) +#endif { zvol_state_t *zv; int error = 0; @@ -686,10 +690,14 @@ zvol_open(struct block_device *bdev, fmode_t flag) /* * Obtain a copy of private_data under the zvol_state_lock to make * sure that either the result of zvol free code path setting - * bdev->bd_disk->private_data to NULL is observed, or zvol_os_free() + * disk->private_data to NULL is observed, or zvol_os_free() * is not called on this zv because of the positive zv_open_count. */ +#ifdef HAVE_BLK_MODE_T + zv = disk->private_data; +#else zv = bdev->bd_disk->private_data; +#endif if (zv == NULL) { rw_exit(&zvol_state_lock); return (SET_ERROR(-ENXIO)); @@ -769,14 +777,15 @@ zvol_open(struct block_device *bdev, fmode_t flag) } } - error = -zvol_first_open(zv, !(flag & FMODE_WRITE)); + error = -zvol_first_open(zv, !(blk_mode_is_open_write(flag))); if (drop_namespace) mutex_exit(&spa_namespace_lock); } if (error == 0) { - if ((flag & FMODE_WRITE) && (zv->zv_flags & ZVOL_RDONLY)) { + if ((blk_mode_is_open_write(flag)) && + (zv->zv_flags & ZVOL_RDONLY)) { if (zv->zv_open_count == 0) zvol_last_close(zv); @@ -791,14 +800,25 @@ zvol_open(struct block_device *bdev, fmode_t flag) rw_exit(&zv->zv_suspend_lock); if (error == 0) +#ifdef HAVE_BLK_MODE_T + disk_check_media_change(disk); +#else zfs_check_media_change(bdev); +#endif return (error); } static void -zvol_release(struct gendisk *disk, fmode_t mode) +#ifdef HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG +zvol_release(struct gendisk *disk) +#else +zvol_release(struct gendisk *disk, fmode_t unused) +#endif { +#if !defined(HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG) + (void) unused; +#endif zvol_state_t *zv; boolean_t drop_suspend = B_TRUE; diff --git a/module/zfs/arc.c b/module/zfs/arc.c index 38d0909183cc..b6ec06407c66 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -9103,15 +9103,16 @@ l2arc_apply_transforms(spa_t *spa, arc_buf_hdr_t *hdr, uint64_t asize, * write things before deciding to fail compression in nearly * every case.) */ - cabd = abd_alloc_for_io(size, ismd); - tmp = abd_borrow_buf(cabd, size); + uint64_t bufsize = MAX(size, asize); + cabd = abd_alloc_for_io(bufsize, ismd); + tmp = abd_borrow_buf(cabd, bufsize); psize = zio_compress_data(compress, to_write, &tmp, size, hdr->b_complevel); if (psize >= asize) { psize = HDR_GET_PSIZE(hdr); - abd_return_buf_copy(cabd, tmp, size); + abd_return_buf_copy(cabd, tmp, bufsize); HDR_SET_COMPRESS(hdr, ZIO_COMPRESS_OFF); to_write = cabd; abd_copy(to_write, hdr->b_l1hdr.b_pabd, psize); @@ -9121,9 +9122,9 @@ l2arc_apply_transforms(spa_t *spa, arc_buf_hdr_t *hdr, uint64_t asize, } ASSERT3U(psize, <=, HDR_GET_PSIZE(hdr)); if (psize < asize) - memset((char *)tmp + psize, 0, asize - psize); + memset((char *)tmp + psize, 0, bufsize - psize); psize = HDR_GET_PSIZE(hdr); - abd_return_buf_copy(cabd, tmp, size); + abd_return_buf_copy(cabd, tmp, bufsize); to_write = cabd; } diff --git a/module/zfs/dsl_dir.c b/module/zfs/dsl_dir.c index bbe6a03d620f..baf970121a61 100644 --- a/module/zfs/dsl_dir.c +++ b/module/zfs/dsl_dir.c @@ -26,6 +26,7 @@ * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. * Copyright (c) 2016 Actifio, Inc. All rights reserved. * Copyright (c) 2018, loli10K . All rights reserved. + * Copyright (c) 2023 Hewlett Packard Enterprise Development LP. */ #include @@ -1358,30 +1359,23 @@ dsl_dir_tempreserve_impl(dsl_dir_t *dd, uint64_t asize, boolean_t netfree, ext_quota = 0; if (used_on_disk >= quota) { + if (retval == ENOSPC && (used_on_disk - quota) < + dsl_pool_deferred_space(dd->dd_pool)) { + retval = SET_ERROR(ERESTART); + } /* Quota exceeded */ mutex_exit(&dd->dd_lock); DMU_TX_STAT_BUMP(dmu_tx_quota); return (retval); } else if (used_on_disk + est_inflight >= quota + ext_quota) { - if (est_inflight > 0 || used_on_disk < quota) { - retval = SET_ERROR(ERESTART); - } else { - ASSERT3U(used_on_disk, >=, quota); - - if (retval == ENOSPC && (used_on_disk - quota) < - dsl_pool_deferred_space(dd->dd_pool)) { - retval = SET_ERROR(ERESTART); - } - } - dprintf_dd(dd, "failing: used=%lluK inflight = %lluK " - "quota=%lluK tr=%lluK err=%d\n", + "quota=%lluK tr=%lluK\n", (u_longlong_t)used_on_disk>>10, (u_longlong_t)est_inflight>>10, - (u_longlong_t)quota>>10, (u_longlong_t)asize>>10, retval); + (u_longlong_t)quota>>10, (u_longlong_t)asize>>10); mutex_exit(&dd->dd_lock); DMU_TX_STAT_BUMP(dmu_tx_quota); - return (retval); + return (SET_ERROR(ERESTART)); } /* We need to up our estimated delta before dropping dd_lock */ diff --git a/module/zfs/metaslab.c b/module/zfs/metaslab.c index 20dc934593f1..cdf599b17924 100644 --- a/module/zfs/metaslab.c +++ b/module/zfs/metaslab.c @@ -3208,6 +3208,15 @@ metaslab_segment_weight(metaslab_t *msp) static boolean_t metaslab_should_allocate(metaslab_t *msp, uint64_t asize, boolean_t try_hard) { + /* + * This case will usually but not always get caught by the checks below; + * metaslabs can be loaded by various means, including the trim and + * initialize code. Once that happens, without this check they are + * allocatable even before they finish their first txg sync. + */ + if (unlikely(msp->ms_new)) + return (B_FALSE); + /* * If the metaslab is loaded, ms_max_size is definitive and we can use * the fast check. If it's not, the ms_max_size is a lower bound (once diff --git a/module/zfs/spa_errlog.c b/module/zfs/spa_errlog.c index 2e5c22c11490..5dd08f597f33 100644 --- a/module/zfs/spa_errlog.c +++ b/module/zfs/spa_errlog.c @@ -930,12 +930,21 @@ spa_upgrade_errlog(spa_t *spa, dmu_tx_t *tx) if (spa->spa_errlog_last != 0) { sync_upgrade_errlog(spa, spa->spa_errlog_last, &newobj, tx); spa->spa_errlog_last = newobj; + + (void) zap_update(spa->spa_meta_objset, + DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_ERRLOG_LAST, + sizeof (uint64_t), 1, &spa->spa_errlog_last, tx); } if (spa->spa_errlog_scrub != 0) { sync_upgrade_errlog(spa, spa->spa_errlog_scrub, &newobj, tx); spa->spa_errlog_scrub = newobj; + + (void) zap_update(spa->spa_meta_objset, + DMU_POOL_DIRECTORY_OBJECT, DMU_POOL_ERRLOG_SCRUB, + sizeof (uint64_t), 1, &spa->spa_errlog_scrub, tx); } + mutex_exit(&spa->spa_errlog_lock); } diff --git a/module/zfs/spa_misc.c b/module/zfs/spa_misc.c index 3b355e0debcc..72b690162d64 100644 --- a/module/zfs/spa_misc.c +++ b/module/zfs/spa_misc.c @@ -27,6 +27,7 @@ * Copyright (c) 2017 Datto Inc. * Copyright (c) 2017, Intel Corporation. * Copyright (c) 2019, loli10K . All rights reserved. + * Copyright (c) 2023, Klara Inc. */ #include @@ -2756,8 +2757,7 @@ spa_state_to_name(spa_t *spa) vdev_state_t state = rvd->vdev_state; vdev_aux_t aux = rvd->vdev_stat.vs_aux; - if (spa_suspended(spa) && - (spa_get_failmode(spa) != ZIO_FAILURE_MODE_CONTINUE)) + if (spa_suspended(spa)) return ("SUSPENDED"); switch (state) { diff --git a/module/zfs/zil.c b/module/zfs/zil.c index b30676b42d88..9e9c9c22549d 100644 --- a/module/zfs/zil.c +++ b/module/zfs/zil.c @@ -1550,7 +1550,16 @@ zil_lwb_write_done(zio_t *zio) lwb->lwb_state = LWB_STATE_WRITE_DONE; lwb->lwb_child_zio = NULL; lwb->lwb_write_zio = NULL; + + /* + * If nlwb is not yet issued, zil_lwb_set_zio_dependency() is not + * called for it yet, and when it will be, it won't be able to make + * its write ZIO a parent this ZIO. In such case we can not defer + * our flushes or below may be a race between the done callbacks. + */ nlwb = list_next(&zilog->zl_lwb_list, lwb); + if (nlwb && nlwb->lwb_state != LWB_STATE_ISSUED) + nlwb = NULL; mutex_exit(&zilog->zl_lock); if (avl_numnodes(t) == 0) diff --git a/tests/test-runner/bin/zts-report.py.in b/tests/test-runner/bin/zts-report.py.in index e1bbe063ab4c..558e4b57279d 100755 --- a/tests/test-runner/bin/zts-report.py.in +++ b/tests/test-runner/bin/zts-report.py.in @@ -214,6 +214,7 @@ maybe = { 'cli_root/zfs_get/zfs_get_009_pos': ['SKIP', 5479], 'cli_root/zfs_rollback/zfs_rollback_001_pos': ['FAIL', known_reason], 'cli_root/zfs_rollback/zfs_rollback_002_pos': ['FAIL', known_reason], + 'cli_root/zfs_share/zfs_share_concurrent_shares': ['FAIL', known_reason], 'cli_root/zfs_snapshot/zfs_snapshot_002_neg': ['FAIL', known_reason], 'cli_root/zfs_unshare/zfs_unshare_006_pos': ['SKIP', na_reason], 'cli_root/zpool_add/zpool_add_004_pos': ['FAIL', known_reason], @@ -259,10 +260,9 @@ if sys.platform.startswith('freebsd'): maybe.update({ 'cli_root/zfs_copies/zfs_copies_002_pos': ['FAIL', known_reason], 'cli_root/zfs_inherit/zfs_inherit_001_neg': ['FAIL', known_reason], - 'cli_root/zfs_share/zfs_share_concurrent_shares': - ['FAIL', known_reason], 'cli_root/zpool_import/zpool_import_012_pos': ['FAIL', known_reason], 'delegate/zfs_allow_003_pos': ['FAIL', known_reason], + 'delegate/zfs_allow_010_pos': ['FAIL', known_reason], 'inheritance/inherit_001_pos': ['FAIL', 11829], 'resilver/resilver_restart_001': ['FAIL', known_reason], 'pool_checkpoint/checkpoint_big_rewind': ['FAIL', 12622], diff --git a/tests/zfs-tests/tests/Makefile.am b/tests/zfs-tests/tests/Makefile.am index 66aff5026f8f..1a58e6f774e9 100644 --- a/tests/zfs-tests/tests/Makefile.am +++ b/tests/zfs-tests/tests/Makefile.am @@ -1588,7 +1588,9 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \ functional/online_offline/setup.ksh \ functional/pam/cleanup.ksh \ functional/pam/pam_basic.ksh \ + functional/pam/pam_change_unmounted.ksh \ functional/pam/pam_nounmount.ksh \ + functional/pam/pam_recursive.ksh \ functional/pam/pam_short_password.ksh \ functional/pam/setup.ksh \ functional/pool_checkpoint/checkpoint_after_rewind.ksh \ diff --git a/tests/zfs-tests/tests/functional/block_cloning/block_cloning_copyfilerange_fallback_same_txg.ksh b/tests/zfs-tests/tests/functional/block_cloning/block_cloning_copyfilerange_fallback_same_txg.ksh index a10545bc0769..2cd2f4763a73 100755 --- a/tests/zfs-tests/tests/functional/block_cloning/block_cloning_copyfilerange_fallback_same_txg.ksh +++ b/tests/zfs-tests/tests/functional/block_cloning/block_cloning_copyfilerange_fallback_same_txg.ksh @@ -48,10 +48,10 @@ function cleanup log_onexit cleanup -log_must zpool create -o feature@block_cloning=enabled $TESTPOOL $DISKS - log_must set_tunable64 TXG_TIMEOUT 5000 +log_must zpool create -o feature@block_cloning=enabled $TESTPOOL $DISKS + log_must dd if=/dev/urandom of=/$TESTPOOL/file bs=128K count=4 log_must clonefile -f /$TESTPOOL/file /$TESTPOOL/clone 0 0 524288 diff --git a/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_block_size_histogram.ksh b/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_block_size_histogram.ksh index 0a4d24fa695a..cfa26f54b11f 100755 --- a/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_block_size_histogram.ksh +++ b/tests/zfs-tests/tests/functional/cli_root/zdb/zdb_block_size_histogram.ksh @@ -204,11 +204,11 @@ function histo_check_test_pool # 4096 blocksize count for asize. For verification we stick # to just lsize counts. # - # The max_variance is hard-coded here at 12% to leave us some - # margin. Testing has shown this normally to be in the range - # of 2%-8%, but it may be as large as 11%. + # Variances are expected since this test does not account for + # metadata. The hardcoded limit here is empirical and should + # not be construed as deterministic. ################### - let max_variance=12 + let max_variance=15 let fail_value=0 let error_count=0 log_note "Comparisons for ${pool}" diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_006_pos.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_006_pos.ksh index 2a2466f65c02..e9ab472795eb 100755 --- a/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_006_pos.ksh +++ b/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_006_pos.ksh @@ -94,7 +94,7 @@ while (( depth < MAXDEPTH )); do done log_must zfs set mountpoint=$mtpt $TESTPOOL/$TESTFS -log_must zfs $mountcmd $TESTPOOL/$TESTFS +log_must ismounted $TESTPOOL/$TESTFS log_must zfs set overlay=off $TESTPOOL/$TESTFS if ! is_illumos; then diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_008_pos.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_008_pos.ksh index 2c1029d551cf..0437c61a2c40 100755 --- a/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_008_pos.ksh +++ b/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_008_pos.ksh @@ -71,7 +71,7 @@ log_must mkfile 1M $testfile $testfile1 log_must zfs unmount $fs1 log_must zfs set mountpoint=$mntpnt $fs1 -log_must zfs mount $fs1 +log_must ismounted $fs1 log_must zfs unmount $fs1 log_must zfs mount -O $fs1 @@ -85,7 +85,7 @@ log_must ls $mntpnt/$TESTFILE1 $mntpnt/$TESTFILE2 # Verify $TESTFILE2 was created in $fs1, rather than $fs log_must zfs unmount $fs1 log_must zfs set mountpoint=$mntpnt1 $fs1 -log_must zfs mount $fs1 +log_must ismounted $fs1 log_must ls $testfile1 $mntpnt1/$TESTFILE2 # Verify $TESTFILE2 was not created in $fs, and $fs is accessible again. diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_012_pos.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_012_pos.ksh index 5ff094d2c479..66958f2f0884 100755 --- a/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_012_pos.ksh +++ b/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_012_pos.ksh @@ -25,13 +25,12 @@ # STRATEGY: # 1. Unmount the dataset # 2. Create a new empty directory -# 3. Set the dataset's mountpoint -# 4. Attempt to mount the dataset -# 5. Verify the mount succeeds -# 6. Unmount the dataset -# 7. Create a file in the directory created in step 2 -# 8. Attempt to mount the dataset -# 9. Verify the mount succeeds +# 3. Set the dataset's mountpoint, this should mount the dataset +# 4. Verify the mount succeeds +# 5. Unmount the dataset +# 6. Create a file in the directory created in step 2 +# 7. Attempt to mount the dataset +# 8. Verify the mount succeeds # verify_runnable "both" @@ -43,7 +42,7 @@ fs=$TESTPOOL/$TESTFS log_must zfs umount $fs log_must mkdir -p $TESTDIR log_must zfs set mountpoint=$TESTDIR $fs -log_must zfs mount $fs +log_must ismounted $fs log_must zfs umount $fs log_must touch $TESTDIR/testfile.$$ log_must zfs mount $fs diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_program/zfs_program_json.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_program/zfs_program_json.ksh index b0265c5ee4a1..2241b77bf806 100755 --- a/tests/zfs-tests/tests/functional/cli_root/zfs_program/zfs_program_json.ksh +++ b/tests/zfs-tests/tests/functional/cli_root/zfs_program/zfs_program_json.ksh @@ -117,7 +117,9 @@ usage: For the property list, run: zfs set|get -For the delegated permission list, run: zfs allow|unallow") +For the delegated permission list, run: zfs allow|unallow + +For further help on a command or topic, run: zfs help []") cnt=0 for cmd in ${neg_cmds[@]}; do log_mustnot zfs program $cmd $TESTPOOL $TESTZCP $TESTDS 2>&1 diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_set/mountpoint_002_pos.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_set/mountpoint_002_pos.ksh index a5785226e02e..c227a6fb8aa8 100755 --- a/tests/zfs-tests/tests/functional/cli_root/zfs_set/mountpoint_002_pos.ksh +++ b/tests/zfs-tests/tests/functional/cli_root/zfs_set/mountpoint_002_pos.ksh @@ -35,7 +35,9 @@ # # DESCRIPTION: # If ZFS is currently managing the file system but it is currently unmounted, -# and the mountpoint property is changed, the file system remains unmounted. +# and the mountpoint property is changed, the file system should be mounted +# if it is a valid mountpoint and canmount allows to mount, otherwise it +# should not be mounted. # # STRATEGY: # 1. Setup a pool and create fs, ctr within it. @@ -62,7 +64,7 @@ function cleanup } log_assert "Setting a valid mountpoint for an unmounted file system, \ - it remains unmounted." + it gets mounted." log_onexit cleanup old_fs_mpt=$(get_prop mountpoint $TESTPOOL/$TESTFS) @@ -83,7 +85,11 @@ while (( i < ${#dataset[@]} )); do while (( j < ${#values[@]} )); do set_n_check_prop "${values[j]}" "mountpoint" \ "${dataset[i]}" - log_mustnot ismounted ${dataset[i]} + if [ "${dataset[i]}" = "$TESTPOOL/$TESTFS" ]; then + log_must ismounted ${dataset[i]} + else + log_mustnot ismounted ${dataset[i]} + fi (( j += 1 )) done cleanup diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_set/zfs_set_003_neg.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_set/zfs_set_003_neg.ksh index 3afb0eb7010e..5901ba7dc461 100755 --- a/tests/zfs-tests/tests/functional/cli_root/zfs_set/zfs_set_003_neg.ksh +++ b/tests/zfs-tests/tests/functional/cli_root/zfs_set/zfs_set_003_neg.ksh @@ -33,7 +33,9 @@ # # DESCRIPTION: -# 'zfs set mountpoint/sharenfs' should fail when the mountpoint is invalid +# 'zfs set mountpoint/sharenfs' should set the property when mountpoint +# is invalid. Setting the property should be successful, but dataset +# should not be mounted, as mountpoint is invalid. # # STRATEGY: # 1. Create invalid scenarios @@ -62,10 +64,12 @@ longpath=$(gen_dataset_name 1030 "abcdefg") log_must zfs create -o mountpoint=legacy $TESTPOOL/foo # Do the negative testing about "property may be set but unable to remount filesystem" -log_mustnot eval "zfs set mountpoint=$badpath $TESTPOOL/foo >/dev/null 2>&1" +set_n_check_prop "$badpath" "mountpoint" "$TESTPOOL/foo" +log_mustnot ismounted $TESTPOOL/foo # Do the negative testing about "property may be set but unable to reshare filesystem" -log_mustnot eval "zfs set sharenfs=on $TESTPOOL/foo >/dev/null 2>&1" +set_n_check_prop "on" "sharenfs" "$TESTPOOL/foo" +log_mustnot ismounted $TESTPOOL/foo # Do the negative testing about "sharenfs property can not be set to null" log_mustnot eval "zfs set sharenfs= $TESTPOOL/foo >/dev/null 2>&1" diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_partial.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_partial.ksh index bdbf3db53336..9342cbe880ae 100755 --- a/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_partial.ksh +++ b/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_partial.ksh @@ -60,7 +60,7 @@ log_must set_tunable64 VDEV_MIN_MS_COUNT 64 # Minimum trim size is decreased to verify all trim sizes. typeset trim_extent_bytes_min=$(get_tunable TRIM_EXTENT_BYTES_MIN) -log_must set_tunable64 TRIM_EXTENT_BYTES_MIN 4096 +log_must set_tunable64 TRIM_EXTENT_BYTES_MIN 512 log_must mkdir "$TESTDIR" log_must truncate -s $LARGESIZE "$LARGEFILE" diff --git a/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_verify_trimmed.ksh b/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_verify_trimmed.ksh index d5aaf49aebc5..41d1decd13ce 100755 --- a/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_verify_trimmed.ksh +++ b/tests/zfs-tests/tests/functional/cli_root/zpool_trim/zpool_trim_verify_trimmed.ksh @@ -52,7 +52,7 @@ LARGEFILE="$TESTDIR/largefile" # Reduce trim size to allow for tighter tolerance below when checking. typeset trim_extent_bytes_min=$(get_tunable TRIM_EXTENT_BYTES_MIN) -log_must set_tunable64 TRIM_EXTENT_BYTES_MIN 4096 +log_must set_tunable64 TRIM_EXTENT_BYTES_MIN 512 log_must mkdir "$TESTDIR" log_must truncate -s $LARGESIZE "$LARGEFILE" diff --git a/tests/zfs-tests/tests/functional/no_space/enospc_rm.ksh b/tests/zfs-tests/tests/functional/no_space/enospc_rm.ksh index d0f4ff4a08fe..d9582fbe2a76 100755 --- a/tests/zfs-tests/tests/functional/no_space/enospc_rm.ksh +++ b/tests/zfs-tests/tests/functional/no_space/enospc_rm.ksh @@ -17,6 +17,7 @@ # # Copyright (c) 2014, 2016 by Delphix. All rights reserved. # Copyright (c) 2022 by Lawrence Livermore National Security, LLC. +# Copyright (c) 2023 Hewlett Packard Enterprise Development LP. # . $STF_SUITE/include/libtest.shlib @@ -51,11 +52,20 @@ log_must zfs create $TESTPOOL/$TESTFS log_must zfs set mountpoint=$TESTDIR $TESTPOOL/$TESTFS log_must zfs set compression=off $TESTPOOL/$TESTFS -log_note "Writing files until ENOSPC." +log_note "Writing Big(1G) files until ENOSPC." log_mustnot_expect "No space left on device" fio --name=test \ --fallocate=none --rw=write --bs=1M --size=1G --numjobs=4 \ --sync=1 --directory=$TESTDIR/ --group_reporting +log_must rm $TESTDIR/test.* +log_must test -z "$(ls -A $TESTDIR)" +sync_pool $TESTPOOL true + +log_note "Writing small(10M) files until ENOSPC." +log_mustnot_expect "No space left on device" fio --name=test \ + --fallocate=none --rw=write --bs=1M --size=10M --numjobs=200 \ + --sync=1 --directory=$TESTDIR/ --group_reporting + log_must rm $TESTDIR/test.* log_must test -z "$(ls -A $TESTDIR)" diff --git a/tests/zfs-tests/tests/functional/trim/autotrim_config.ksh b/tests/zfs-tests/tests/functional/trim/autotrim_config.ksh index c97772585737..4dba4616e947 100755 --- a/tests/zfs-tests/tests/functional/trim/autotrim_config.ksh +++ b/tests/zfs-tests/tests/functional/trim/autotrim_config.ksh @@ -57,7 +57,7 @@ log_onexit cleanup # Minimum trim size is decreased to verify all trim sizes. typeset trim_extent_bytes_min=$(get_tunable TRIM_EXTENT_BYTES_MIN) -log_must set_tunable64 TRIM_EXTENT_BYTES_MIN 4096 +log_must set_tunable64 TRIM_EXTENT_BYTES_MIN 512 # Reduced TRIM_TXG_BATCH to make trimming more frequent. typeset trim_txg_batch=$(get_tunable TRIM_TXG_BATCH) diff --git a/tests/zfs-tests/tests/functional/trim/autotrim_integrity.ksh b/tests/zfs-tests/tests/functional/trim/autotrim_integrity.ksh index e25390339b6c..e139809105df 100755 --- a/tests/zfs-tests/tests/functional/trim/autotrim_integrity.ksh +++ b/tests/zfs-tests/tests/functional/trim/autotrim_integrity.ksh @@ -54,7 +54,7 @@ log_onexit cleanup # Minimum trim size is decreased to verify all trim sizes. typeset trim_extent_bytes_min=$(get_tunable TRIM_EXTENT_BYTES_MIN) -log_must set_tunable64 TRIM_EXTENT_BYTES_MIN 4096 +log_must set_tunable64 TRIM_EXTENT_BYTES_MIN 512 # Reduced TRIM_TXG_BATCH to make trimming more frequent. typeset trim_txg_batch=$(get_tunable TRIM_TXG_BATCH) diff --git a/tests/zfs-tests/tests/functional/trim/autotrim_trim_integrity.ksh b/tests/zfs-tests/tests/functional/trim/autotrim_trim_integrity.ksh index ae7ad8d73dd8..53de485b1a8e 100755 --- a/tests/zfs-tests/tests/functional/trim/autotrim_trim_integrity.ksh +++ b/tests/zfs-tests/tests/functional/trim/autotrim_trim_integrity.ksh @@ -55,7 +55,7 @@ log_onexit cleanup # Minimum trim size is decreased to verify all trim sizes. typeset trim_extent_bytes_min=$(get_tunable TRIM_EXTENT_BYTES_MIN) -log_must set_tunable64 TRIM_EXTENT_BYTES_MIN 4096 +log_must set_tunable64 TRIM_EXTENT_BYTES_MIN 512 # Reduced TRIM_TXG_BATCH to make trimming more frequent. typeset trim_txg_batch=$(get_tunable TRIM_TXG_BATCH) diff --git a/tests/zfs-tests/tests/functional/trim/trim_config.ksh b/tests/zfs-tests/tests/functional/trim/trim_config.ksh index 6a187a05b579..c08b5edb5698 100755 --- a/tests/zfs-tests/tests/functional/trim/trim_config.ksh +++ b/tests/zfs-tests/tests/functional/trim/trim_config.ksh @@ -57,7 +57,7 @@ log_onexit cleanup # Minimum trim size is decreased to verify all trim sizes. typeset trim_extent_bytes_min=$(get_tunable TRIM_EXTENT_BYTES_MIN) -log_must set_tunable64 TRIM_EXTENT_BYTES_MIN 4096 +log_must set_tunable64 TRIM_EXTENT_BYTES_MIN 512 # Reduced TRIM_TXG_BATCH to make trimming more frequent. typeset trim_txg_batch=$(get_tunable TRIM_TXG_BATCH) diff --git a/tests/zfs-tests/tests/functional/trim/trim_integrity.ksh b/tests/zfs-tests/tests/functional/trim/trim_integrity.ksh index 2dff0924f7b1..c67697521ce8 100755 --- a/tests/zfs-tests/tests/functional/trim/trim_integrity.ksh +++ b/tests/zfs-tests/tests/functional/trim/trim_integrity.ksh @@ -54,7 +54,7 @@ log_onexit cleanup # Minimum trim size is decreased to verify all trim sizes. typeset trim_extent_bytes_min=$(get_tunable TRIM_EXTENT_BYTES_MIN) -log_must set_tunable64 TRIM_EXTENT_BYTES_MIN 4096 +log_must set_tunable64 TRIM_EXTENT_BYTES_MIN 512 # Reduced TRIM_TXG_BATCH to make trimming more frequent. typeset trim_txg_batch=$(get_tunable TRIM_TXG_BATCH)