diff --git a/.github/workflows/scripts/qemu-2-start.sh b/.github/workflows/scripts/qemu-2-start.sh index 39ac92107b71..73496d4f3de6 100755 --- a/.github/workflows/scripts/qemu-2-start.sh +++ b/.github/workflows/scripts/qemu-2-start.sh @@ -14,7 +14,7 @@ OSv=$OS # compressed with .zst extension REPO="https://github.com/mcmilk/openzfs-freebsd-images" -FREEBSD="$REPO/releases/download/v2024-10-05" +FREEBSD="$REPO/releases/download/v2024-12-14" URLzs="" # Ubuntu mirrors @@ -40,6 +40,12 @@ case "$OS" in # dns sometimes fails with that url :/ echo "89.187.191.12 geo.mirror.pkgbuild.com" | sudo tee /etc/hosts > /dev/null ;; + centos-stream10) + OSNAME="CentOS Stream 10" + # TODO: #16903 Overwrite OSv to stream9 for virt-install until it's added to osinfo + OSv="centos-stream9" + URL="https://cloud.centos.org/centos/10-stream/x86_64/images/CentOS-Stream-GenericCloud-10-latest.x86_64.qcow2" + ;; centos-stream9) OSNAME="CentOS Stream 9" URL="https://cloud.centos.org/centos/9-stream/x86_64/images/CentOS-Stream-GenericCloud-9-latest.x86_64.qcow2" @@ -76,28 +82,29 @@ case "$OS" in BASH="/usr/local/bin/bash" NIC="rtl8139" ;; - freebsd14-0r) - OSNAME="FreeBSD 14.0-RELEASE" - OSv="freebsd14.0" - URLzs="$FREEBSD/amd64-freebsd-14.0-RELEASE.qcow2.zst" - BASH="/usr/local/bin/bash" - ;; freebsd14-1r) OSNAME="FreeBSD 14.1-RELEASE" OSv="freebsd14.0" URLzs="$FREEBSD/amd64-freebsd-14.1-RELEASE.qcow2.zst" BASH="/usr/local/bin/bash" ;; + freebsd14-2r) + OSNAME="FreeBSD 14.2-RELEASE" + OSv="freebsd14.0" + URLzs="$FREEBSD/amd64-freebsd-14.2-RELEASE.qcow2.zst" + BASH="/usr/local/bin/bash" + ;; freebsd13-4s) OSNAME="FreeBSD 13.4-STABLE" OSv="freebsd13.0" URLzs="$FREEBSD/amd64-freebsd-13.4-STABLE.qcow2.zst" BASH="/usr/local/bin/bash" + NIC="rtl8139" ;; - freebsd14-1s) - OSNAME="FreeBSD 14.1-STABLE" + freebsd14-2s) + OSNAME="FreeBSD 14.2-STABLE" OSv="freebsd14.0" - URLzs="$FREEBSD/amd64-freebsd-14.1-STABLE.qcow2.zst" + URLzs="$FREEBSD/amd64-freebsd-14.2-STABLE.qcow2.zst" BASH="/usr/local/bin/bash" ;; freebsd15-0c) diff --git a/.github/workflows/scripts/qemu-3-deps.sh b/.github/workflows/scripts/qemu-3-deps.sh index 96979cd02e09..9b8957734277 100755 --- a/.github/workflows/scripts/qemu-3-deps.sh +++ b/.github/workflows/scripts/qemu-3-deps.sh @@ -104,7 +104,7 @@ case "$1" in sudo dnf install -y kernel-abi-whitelists echo "##[endgroup]" ;; - almalinux9|centos-stream9) + almalinux9|centos-stream9|centos-stream10) echo "##[group]Enable epel and crb repositories" sudo dnf config-manager -y --set-enabled crb sudo dnf install -y epel-release diff --git a/.github/workflows/zfs-qemu.yml b/.github/workflows/zfs-qemu.yml index e90030f4c02e..af26e135b91f 100644 --- a/.github/workflows/zfs-qemu.yml +++ b/.github/workflows/zfs-qemu.yml @@ -3,6 +3,18 @@ name: zfs-qemu on: push: pull_request: + workflow_dispatch: + inputs: + include_stream9: + type: boolean + required: false + default: false + description: 'Test on CentOS 9 stream' + include_stream10: + type: boolean + required: false + default: false + description: 'Test on CentOS 10 stream' concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} @@ -22,8 +34,8 @@ jobs: - name: Generate OS config and CI type id: os run: | - FULL_OS='["almalinux8", "almalinux9", "centos-stream9", "debian11", "debian12", "fedora40", "fedora41", "freebsd13-4r", "freebsd14-0r", "freebsd14-1s", "ubuntu20", "ubuntu22", "ubuntu24"]' - QUICK_OS='["almalinux8", "almalinux9", "debian12", "fedora41", "freebsd13-3r", "freebsd14-1r", "ubuntu24"]' + FULL_OS='["almalinux8", "almalinux9", "debian11", "debian12", "fedora40", "fedora41", "freebsd13-3r", "freebsd13-4s", "freebsd14-1r", "freebsd14-2s", "freebsd15-0c", "ubuntu20", "ubuntu22", "ubuntu24"]' + QUICK_OS='["almalinux8", "almalinux9", "debian12", "fedora41", "freebsd13-3r", "freebsd14-2r", "ubuntu24"]' # determine CI type when running on PR ci_type="full" if ${{ github.event_name == 'pull_request' }}; then @@ -37,9 +49,22 @@ jobs: os_selection="$FULL_OS" fi os_json=$(echo ${os_selection} | jq -c) + + # Add optional runners + if [ "${{ github.event.inputs.include_stream9 }}" == 'true' ]; then + os_json=$(echo $os_json | jq -c '. += ["centos-stream9"]') + fi + if [ "${{ github.event.inputs.include_stream10 }}" == 'true' ]; then + os_json=$(echo $os_json | jq -c '. += ["centos-stream10"]') + fi + + echo $os_json echo "os=$os_json" >> $GITHUB_OUTPUT echo "ci_type=$ci_type" >> $GITHUB_OUTPUT + + + qemu-vm: name: qemu-x86 needs: [ test-config ] @@ -49,8 +74,9 @@ jobs: # rhl: almalinux8, almalinux9, centos-stream9, fedora40, fedora41 # debian: debian11, debian12, ubuntu20, ubuntu22, ubuntu24 # misc: archlinux, tumbleweed - # FreeBSD Release: freebsd13-3r, freebsd13-4r, freebsd14-0r, freebsd14-1r - # FreeBSD Stable: freebsd13-4s, freebsd14-1s + # FreeBSD variants of 2024-12: + # FreeBSD Release: freebsd13-3r, freebsd13-4r, freebsd14-1r, freebsd14-2r + # FreeBSD Stable: freebsd13-4s, freebsd14-2s # FreeBSD Current: freebsd15-0c os: ${{ fromJson(needs.test-config.outputs.test_os) }} runs-on: ubuntu-24.04 diff --git a/META b/META index 5446d3e7c348..d7a8e3604e58 100644 --- a/META +++ b/META @@ -2,7 +2,7 @@ Meta: 1 Name: zfs Branch: 1.0 Version: 2.3.0 -Release: rc4 +Release: rc5 Release-Tags: relext License: CDDL Author: OpenZFS diff --git a/cmd/zfs/zfs_main.c b/cmd/zfs/zfs_main.c index 7836f5909f4a..73ccf72d263c 100644 --- a/cmd/zfs/zfs_main.c +++ b/cmd/zfs/zfs_main.c @@ -500,7 +500,7 @@ usage_prop_cb(int prop, void *cb) { FILE *fp = cb; - (void) fprintf(fp, "\t%-15s ", zfs_prop_to_name(prop)); + (void) fprintf(fp, "\t%-22s ", zfs_prop_to_name(prop)); if (zfs_prop_readonly(prop)) (void) fprintf(fp, " NO "); @@ -561,40 +561,40 @@ usage(boolean_t requested) (void) fprintf(fp, "%s", gettext("\nThe following properties are supported:\n")); - (void) fprintf(fp, "\n\t%-14s %s %s %s\n\n", + (void) fprintf(fp, "\n\t%-21s %s %s %s\n\n", "PROPERTY", "EDIT", "INHERIT", "VALUES"); /* Iterate over all properties */ (void) zprop_iter(usage_prop_cb, fp, B_FALSE, B_TRUE, ZFS_TYPE_DATASET); - (void) fprintf(fp, "\t%-15s ", "userused@..."); + (void) fprintf(fp, "\t%-22s ", "userused@..."); (void) fprintf(fp, " NO NO \n"); - (void) fprintf(fp, "\t%-15s ", "groupused@..."); + (void) fprintf(fp, "\t%-22s ", "groupused@..."); (void) fprintf(fp, " NO NO \n"); - (void) fprintf(fp, "\t%-15s ", "projectused@..."); + (void) fprintf(fp, "\t%-22s ", "projectused@..."); (void) fprintf(fp, " NO NO \n"); - (void) fprintf(fp, "\t%-15s ", "userobjused@..."); + (void) fprintf(fp, "\t%-22s ", "userobjused@..."); (void) fprintf(fp, " NO NO \n"); - (void) fprintf(fp, "\t%-15s ", "groupobjused@..."); + (void) fprintf(fp, "\t%-22s ", "groupobjused@..."); (void) fprintf(fp, " NO NO \n"); - (void) fprintf(fp, "\t%-15s ", "projectobjused@..."); + (void) fprintf(fp, "\t%-22s ", "projectobjused@..."); (void) fprintf(fp, " NO NO \n"); - (void) fprintf(fp, "\t%-15s ", "userquota@..."); + (void) fprintf(fp, "\t%-22s ", "userquota@..."); (void) fprintf(fp, "YES NO | none\n"); - (void) fprintf(fp, "\t%-15s ", "groupquota@..."); + (void) fprintf(fp, "\t%-22s ", "groupquota@..."); (void) fprintf(fp, "YES NO | none\n"); - (void) fprintf(fp, "\t%-15s ", "projectquota@..."); + (void) fprintf(fp, "\t%-22s ", "projectquota@..."); (void) fprintf(fp, "YES NO | none\n"); - (void) fprintf(fp, "\t%-15s ", "userobjquota@..."); + (void) fprintf(fp, "\t%-22s ", "userobjquota@..."); (void) fprintf(fp, "YES NO | none\n"); - (void) fprintf(fp, "\t%-15s ", "groupobjquota@..."); + (void) fprintf(fp, "\t%-22s ", "groupobjquota@..."); (void) fprintf(fp, "YES NO | none\n"); - (void) fprintf(fp, "\t%-15s ", "projectobjquota@..."); + (void) fprintf(fp, "\t%-22s ", "projectobjquota@..."); (void) fprintf(fp, "YES NO | none\n"); - (void) fprintf(fp, "\t%-15s ", "written@"); + (void) fprintf(fp, "\t%-22s ", "written@"); (void) fprintf(fp, " NO NO \n"); - (void) fprintf(fp, "\t%-15s ", "written#"); + (void) fprintf(fp, "\t%-22s ", "written#"); (void) fprintf(fp, " NO NO \n"); (void) fprintf(fp, gettext("\nSizes are specified in bytes " diff --git a/config/kernel-pin-user-pages.m4 b/config/kernel-pin-user-pages.m4 new file mode 100644 index 000000000000..fe7aff375208 --- /dev/null +++ b/config/kernel-pin-user-pages.m4 @@ -0,0 +1,33 @@ +dnl # +dnl # Check for pin_user_pages_unlocked(). +dnl # +AC_DEFUN([ZFS_AC_KERNEL_SRC_PIN_USER_PAGES], [ + ZFS_LINUX_TEST_SRC([pin_user_pages_unlocked], [ + #include + ],[ + unsigned long start = 0; + unsigned long nr_pages = 1; + struct page **pages = NULL; + unsigned int gup_flags = 0; + long ret __attribute__ ((unused)); + + ret = pin_user_pages_unlocked(start, nr_pages, pages, + gup_flags); + ]) +]) + +AC_DEFUN([ZFS_AC_KERNEL_PIN_USER_PAGES], [ + + dnl # + dnl # Kernal 5.8 introduced the pin_user_pages* interfaces which should + dnl # be used for Direct I/O requests. + dnl # + AC_MSG_CHECKING([whether pin_user_pages_unlocked() is available]) + ZFS_LINUX_TEST_RESULT([pin_user_pages_unlocked], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_PIN_USER_PAGES_UNLOCKED, 1, + [pin_user_pages_unlocked() is available]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel-vfs-direct_IO.m4 b/config/kernel-vfs-direct_IO.m4 deleted file mode 100644 index 17605a13fdef..000000000000 --- a/config/kernel-vfs-direct_IO.m4 +++ /dev/null @@ -1,57 +0,0 @@ -dnl # -dnl # Check for Direct I/O interfaces. -dnl # -AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_DIRECT_IO], [ - ZFS_LINUX_TEST_SRC([direct_io_iter], [ - #include - - static ssize_t test_direct_IO(struct kiocb *kiocb, - struct iov_iter *iter) { return 0; } - - static const struct address_space_operations - aops __attribute__ ((unused)) = { - .direct_IO = test_direct_IO, - }; - ],[]) - - ZFS_LINUX_TEST_SRC([direct_io_iter_offset], [ - #include - - static ssize_t test_direct_IO(struct kiocb *kiocb, - struct iov_iter *iter, loff_t offset) { return 0; } - - static const struct address_space_operations - aops __attribute__ ((unused)) = { - .direct_IO = test_direct_IO, - }; - ],[]) -]) - -AC_DEFUN([ZFS_AC_KERNEL_VFS_DIRECT_IO], [ - dnl # - dnl # Linux 4.6.x API change - dnl # - AC_MSG_CHECKING([whether aops->direct_IO() uses iov_iter]) - ZFS_LINUX_TEST_RESULT([direct_io_iter], [ - AC_MSG_RESULT([yes]) - AC_DEFINE(HAVE_VFS_DIRECT_IO_ITER, 1, - [aops->direct_IO() uses iov_iter without rw]) - ],[ - AC_MSG_RESULT([no]) - - dnl # - dnl # Linux 4.1.x API change - dnl # - AC_MSG_CHECKING( - [whether aops->direct_IO() uses offset]) - ZFS_LINUX_TEST_RESULT([direct_io_iter_offset], [ - AC_MSG_RESULT([yes]) - AC_DEFINE(HAVE_VFS_DIRECT_IO_ITER_OFFSET, 1, - [aops->direct_IO() uses iov_iter with offset]) - - ],[ - AC_MSG_RESULT([no]) - ZFS_LINUX_TEST_ERROR([Direct I/O]) - ]) - ]) -]) diff --git a/config/kernel-vfs-iov_iter.m4 b/config/kernel-vfs-iov_iter.m4 index ed7961a9e9dd..a223343030db 100644 --- a/config/kernel-vfs-iov_iter.m4 +++ b/config/kernel-vfs-iov_iter.m4 @@ -13,40 +13,21 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_IOV_ITER], [ error = fault_in_iov_iter_readable(&iter, size); ]) - ZFS_LINUX_TEST_SRC([iov_iter_get_pages2], [ - #include - ], [ - struct iov_iter iter = { 0 }; - struct page **pages = NULL; - size_t maxsize = 4096; - unsigned maxpages = 1; - size_t start; - size_t ret __attribute__ ((unused)); - - ret = iov_iter_get_pages2(&iter, pages, maxsize, maxpages, - &start); - ]) - - ZFS_LINUX_TEST_SRC([iov_iter_get_pages], [ + ZFS_LINUX_TEST_SRC([iov_iter_type], [ + #include #include - ], [ + ],[ struct iov_iter iter = { 0 }; - struct page **pages = NULL; - size_t maxsize = 4096; - unsigned maxpages = 1; - size_t start; - size_t ret __attribute__ ((unused)); - - ret = iov_iter_get_pages(&iter, pages, maxsize, maxpages, - &start); + __attribute__((unused)) enum iter_type i = iov_iter_type(&iter); ]) - ZFS_LINUX_TEST_SRC([iov_iter_type], [ - #include + ZFS_LINUX_TEST_SRC([iter_is_ubuf], [ #include ],[ struct iov_iter iter = { 0 }; - __attribute__((unused)) enum iter_type i = iov_iter_type(&iter); + bool ret __attribute__((unused)); + + ret = iter_is_ubuf(&iter); ]) ZFS_LINUX_TEST_SRC([iter_iov], [ @@ -59,7 +40,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_IOV_ITER], [ ]) AC_DEFUN([ZFS_AC_KERNEL_VFS_IOV_ITER], [ - enable_vfs_iov_iter="yes" AC_MSG_CHECKING([whether fault_in_iov_iter_readable() is available]) ZFS_LINUX_TEST_RESULT([fault_in_iov_iter_readable], [ @@ -70,27 +50,6 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_IOV_ITER], [ AC_MSG_RESULT(no) ]) - dnl # - dnl # Kernel 6.0 changed iov_iter_get_pages() to iov_iter_page_pages2(). - dnl # - AC_MSG_CHECKING([whether iov_iter_get_pages2() is available]) - ZFS_LINUX_TEST_RESULT([iov_iter_get_pages2], [ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_IOV_ITER_GET_PAGES2, 1, - [iov_iter_get_pages2() is available]) - ], [ - AC_MSG_RESULT(no) - AC_MSG_CHECKING([whether iov_iter_get_pages() is available]) - ZFS_LINUX_TEST_RESULT([iov_iter_get_pages], [ - AC_MSG_RESULT(yes) - AC_DEFINE(HAVE_IOV_ITER_GET_PAGES, 1, - [iov_iter_get_pages() is available]) - ], [ - AC_MSG_RESULT(no) - enable_vfs_iov_iter="no" - ]) - ]) - dnl # dnl # This checks for iov_iter_type() in linux/uio.h. It is not dnl # required, however, and the module will compiled without it @@ -106,14 +65,15 @@ AC_DEFUN([ZFS_AC_KERNEL_VFS_IOV_ITER], [ ]) dnl # - dnl # As of the 4.9 kernel support is provided for iovecs, kvecs, - dnl # bvecs and pipes in the iov_iter structure. As long as the - dnl # other support interfaces are all available the iov_iter can - dnl # be correctly used in the uio structure. + dnl # Kernel 6.0 introduced the ITER_UBUF iov_iter type. iter_is_ubuf() + dnl # was also added to determine if the iov_iter is an ITER_UBUF. dnl # - AS_IF([test "x$enable_vfs_iov_iter" = "xyes"], [ - AC_DEFINE(HAVE_VFS_IOV_ITER, 1, - [All required iov_iter interfaces are available]) + AC_MSG_CHECKING([whether iter_is_ubuf() is available]) + ZFS_LINUX_TEST_RESULT([iter_is_ubuf], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_ITER_IS_UBUF, 1, [iter_is_ubuf() is available]) + ],[ + AC_MSG_RESULT(no) ]) dnl # diff --git a/config/kernel-xattr-handler.m4 b/config/kernel-xattr-handler.m4 index d933cff7a4b9..ea4466d83fcc 100644 --- a/config/kernel-xattr-handler.m4 +++ b/config/kernel-xattr-handler.m4 @@ -54,7 +54,6 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_XATTR_HANDLER_GET_DENTRY_INODE_FLAGS], [ ]) AC_DEFUN([ZFS_AC_KERNEL_XATTR_HANDLER_GET_DENTRY_INODE_FLAGS], [ - AC_MSG_RESULT(no) AC_MSG_CHECKING( [whether xattr_handler->get() wants dentry and inode and flags]) ZFS_LINUX_TEST_RESULT([xattr_handler_get_dentry_inode_flags], [ diff --git a/config/kernel.m4 b/config/kernel.m4 index 78f178ff27ac..9928ead1b6ce 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -79,7 +79,6 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [ ZFS_AC_KERNEL_SRC_VFS_READ_FOLIO ZFS_AC_KERNEL_SRC_VFS_MIGRATE_FOLIO ZFS_AC_KERNEL_SRC_VFS_FSYNC_2ARGS - ZFS_AC_KERNEL_SRC_VFS_DIRECT_IO ZFS_AC_KERNEL_SRC_VFS_READPAGES ZFS_AC_KERNEL_SRC_VFS_SET_PAGE_DIRTY_NOBUFFERS ZFS_AC_KERNEL_SRC_VFS_IOV_ITER @@ -128,6 +127,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [ ZFS_AC_KERNEL_SRC_MM_PAGE_SIZE ZFS_AC_KERNEL_SRC_MM_PAGE_MAPPING ZFS_AC_KERNEL_SRC_FILE + ZFS_AC_KERNEL_SRC_PIN_USER_PAGES case "$host_cpu" in powerpc*) ZFS_AC_KERNEL_SRC_CPU_HAS_FEATURE @@ -190,7 +190,6 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [ ZFS_AC_KERNEL_VFS_READ_FOLIO ZFS_AC_KERNEL_VFS_MIGRATE_FOLIO ZFS_AC_KERNEL_VFS_FSYNC_2ARGS - ZFS_AC_KERNEL_VFS_DIRECT_IO ZFS_AC_KERNEL_VFS_READPAGES ZFS_AC_KERNEL_VFS_SET_PAGE_DIRTY_NOBUFFERS ZFS_AC_KERNEL_VFS_IOV_ITER @@ -240,6 +239,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [ ZFS_AC_KERNEL_MM_PAGE_MAPPING ZFS_AC_KERNEL_1ARG_ASSIGN_STR ZFS_AC_KERNEL_FILE + ZFS_AC_KERNEL_PIN_USER_PAGES case "$host_cpu" in powerpc*) ZFS_AC_KERNEL_CPU_HAS_FEATURE @@ -681,11 +681,16 @@ AC_DEFUN([ZFS_LINUX_COMPILE], [ building kernel modules]) AC_ARG_VAR([KERNEL_LLVM], [Binary option to build kernel modules with LLVM/CLANG toolchain]) + AC_ARG_VAR([KERNEL_CROSS_COMPILE], [Cross compile prefix + for kernel module builds]) + AC_ARG_VAR([KERNEL_ARCH], [Architecture to build kernel modules for]) AC_TRY_COMMAND([ KBUILD_MODPOST_NOFINAL="$5" KBUILD_MODPOST_WARN="$6" make modules -k -j$TEST_JOBS ${KERNEL_CC:+CC=$KERNEL_CC} ${KERNEL_LD:+LD=$KERNEL_LD} ${KERNEL_LLVM:+LLVM=$KERNEL_LLVM} CONFIG_MODULES=y CFLAGS_MODULE=-DCONFIG_MODULES + ${KERNEL_CROSS_COMPILE:+CROSS_COMPILE=$KERNEL_CROSS_COMPILE} + ${KERNEL_ARCH:+ARCH=$KERNEL_ARCH} -C $LINUX_OBJ $ARCH_UM M=$PWD/$1 >$1/build.log 2>&1]) AS_IF([AC_TRY_COMMAND([$2])], [$3], [$4]) ]) diff --git a/config/user.m4 b/config/user.m4 index 4e31745a2abc..badd920d2b8a 100644 --- a/config/user.m4 +++ b/config/user.m4 @@ -33,7 +33,7 @@ AC_DEFUN([ZFS_AC_CONFIG_USER], [ ZFS_AC_CONFIG_USER_MAKEDEV_IN_MKDEV ZFS_AC_CONFIG_USER_ZFSEXEC - AC_CHECK_FUNCS([execvpe issetugid mlockall strerror_l strlcat strlcpy gettid]) + AC_CHECK_FUNCS([execvpe issetugid mlockall strlcat strlcpy gettid]) AC_SUBST(RM) ]) diff --git a/config/zfs-build.m4 b/config/zfs-build.m4 index 255813f46d19..55fc029f0847 100644 --- a/config/zfs-build.m4 +++ b/config/zfs-build.m4 @@ -393,6 +393,8 @@ AC_DEFUN([ZFS_AC_RPM], [ RPM_DEFINE_KMOD=${RPM_DEFINE_KMOD}' --define "kernel_cc KERNEL_CC=$(KERNEL_CC)"' RPM_DEFINE_KMOD=${RPM_DEFINE_KMOD}' --define "kernel_ld KERNEL_LD=$(KERNEL_LD)"' RPM_DEFINE_KMOD=${RPM_DEFINE_KMOD}' --define "kernel_llvm KERNEL_LLVM=$(KERNEL_LLVM)"' + RPM_DEFINE_KMOD=${RPM_DEFINE_KMOD}' --define "kernel_cross_compile KERNEL_CROSS_COMPILE=$(KERNEL_CROSS_COMPILE)"' + RPM_DEFINE_KMOD=${RPM_DEFINE_KMOD}' --define "kernel_arch KERNEL_ARCH=$(KERNEL_ARCH)"' ]) RPM_DEFINE_DKMS='' @@ -627,7 +629,7 @@ AC_DEFUN([ZFS_AC_DEFAULT_PACKAGE], [ AC_MSG_CHECKING([default bash completion directory]) case "$VENDOR" in - alpine|artix|debian|gentoo|ubuntu) + alpine|arch|artix|debian|gentoo|ubuntu) bashcompletiondir=/usr/share/bash-completion/completions ;; freebsd) diff --git a/etc/systemd/system/zfs-mount.service.in b/etc/systemd/system/zfs-mount.service.in index 66d894923f4a..41c02c8238ca 100644 --- a/etc/systemd/system/zfs-mount.service.in +++ b/etc/systemd/system/zfs-mount.service.in @@ -8,6 +8,13 @@ After=systemd-remount-fs.service Before=local-fs.target ConditionPathIsDirectory=/sys/module/zfs +# This merely tells the service manager +# that unmounting everything undoes the +# effect of this service. No extra logic +# is ran as a result of these settings. +Conflicts=umount.target +Before=umount.target + [Service] Type=oneshot RemainAfterExit=yes diff --git a/include/libzutil.h b/include/libzutil.h index f8712340cc5e..bcfe2fcf7960 100644 --- a/include/libzutil.h +++ b/include/libzutil.h @@ -27,7 +27,7 @@ #define _LIBZUTIL_H extern __attribute__((visibility("default"))) #include -#include +#include #include #include @@ -276,11 +276,14 @@ _LIBZUTIL_H void update_vdev_config_dev_sysfs_path(nvlist_t *nv, * Thread-safe strerror() for use in ZFS libraries */ static inline char *zfs_strerror(int errnum) { -#ifdef HAVE_STRERROR_L - return (strerror_l(errnum, uselocale(0))); -#else - return (strerror(errnum)); -#endif + static __thread char errbuf[512]; + static pthread_mutex_t zfs_strerror_lock = PTHREAD_MUTEX_INITIALIZER; + + (void) pthread_mutex_lock(&zfs_strerror_lock); + (void) strlcpy(errbuf, strerror(errnum), sizeof (errbuf)); + (void) pthread_mutex_unlock(&zfs_strerror_lock); + + return (errbuf); } #ifdef __cplusplus diff --git a/include/os/linux/spl/sys/uio.h b/include/os/linux/spl/sys/uio.h index 5d483685eb20..9e7afea2ab34 100644 --- a/include/os/linux/spl/sys/uio.h +++ b/include/os/linux/spl/sys/uio.h @@ -40,7 +40,7 @@ */ #define UIO_DIRECT 0x0001 /* Direct I/O request */ -#if defined(HAVE_VFS_IOV_ITER) && defined(HAVE_FAULT_IN_IOV_ITER_READABLE) +#if defined(HAVE_FAULT_IN_IOV_ITER_READABLE) #define iov_iter_fault_in_readable(a, b) fault_in_iov_iter_readable(a, b) #endif @@ -52,12 +52,9 @@ typedef enum zfs_uio_rw { } zfs_uio_rw_t; typedef enum zfs_uio_seg { - UIO_USERSPACE = 0, - UIO_SYSSPACE = 1, - UIO_BVEC = 2, -#if defined(HAVE_VFS_IOV_ITER) - UIO_ITER = 3, -#endif + UIO_SYSSPACE = 0, + UIO_BVEC = 1, + UIO_ITER = 2, } zfs_uio_seg_t; /* @@ -72,9 +69,7 @@ typedef struct zfs_uio { union { const struct iovec *uio_iov; const struct bio_vec *uio_bvec; -#if defined(HAVE_VFS_IOV_ITER) struct iov_iter *uio_iter; -#endif }; int uio_iovcnt; /* Number of iovecs */ offset_t uio_soffset; /* Starting logical offset */ @@ -129,7 +124,7 @@ zfs_uio_iovec_init(zfs_uio_t *uio, const struct iovec *iov, unsigned long nr_segs, offset_t offset, zfs_uio_seg_t seg, ssize_t resid, size_t skip) { - ASSERT(seg == UIO_USERSPACE || seg == UIO_SYSSPACE); + ASSERT(seg == UIO_SYSSPACE); uio->uio_iov = iov; uio->uio_iovcnt = nr_segs; @@ -175,7 +170,6 @@ zfs_uio_bvec_init(zfs_uio_t *uio, struct bio *bio, struct request *rq) memset(&uio->uio_dio, 0, sizeof (zfs_uio_dio_t)); } -#if defined(HAVE_VFS_IOV_ITER) static inline void zfs_uio_iov_iter_init(zfs_uio_t *uio, struct iov_iter *iter, offset_t offset, ssize_t resid, size_t skip) @@ -192,7 +186,6 @@ zfs_uio_iov_iter_init(zfs_uio_t *uio, struct iov_iter *iter, offset_t offset, uio->uio_soffset = uio->uio_loffset; memset(&uio->uio_dio, 0, sizeof (zfs_uio_dio_t)); } -#endif /* HAVE_VFS_IOV_ITER */ #if defined(HAVE_ITER_IOV) #define zfs_uio_iter_iov(iter) iter_iov((iter)) diff --git a/include/sys/zvol_impl.h b/include/sys/zvol_impl.h index 3cd0d78c353d..a8168850023a 100644 --- a/include/sys/zvol_impl.h +++ b/include/sys/zvol_impl.h @@ -88,6 +88,11 @@ int zvol_get_data(void *arg, uint64_t arg2, lr_write_t *lr, char *buf, int zvol_init_impl(void); void zvol_fini_impl(void); void zvol_wait_close(zvol_state_t *zv); +int zvol_clone_range(zvol_state_handle_t *, uint64_t, + zvol_state_handle_t *, uint64_t, uint64_t); +void zvol_log_clone_range(zilog_t *zilog, dmu_tx_t *tx, int txtype, + uint64_t off, uint64_t len, uint64_t blksz, const blkptr_t *bps, + size_t nbps); /* * platform dependent functions exported to platform independent code diff --git a/lib/libspl/backtrace.c b/lib/libspl/backtrace.c index 6e8b3b12122d..7f1ef596f8ed 100644 --- a/lib/libspl/backtrace.c +++ b/lib/libspl/backtrace.c @@ -38,7 +38,7 @@ */ #define spl_bt_write_n(fd, s, n) \ do { ssize_t r __maybe_unused = write(fd, s, n); } while (0) -#define spl_bt_write(fd, s) spl_bt_write_n(fd, s, sizeof (s)) +#define spl_bt_write(fd, s) spl_bt_write_n(fd, s, sizeof (s)-1) #if defined(HAVE_LIBUNWIND) #define UNW_LOCAL_ONLY diff --git a/lib/libspl/include/sys/uio.h b/lib/libspl/include/sys/uio.h index 16749fa492e5..f86be64ce7f3 100644 --- a/lib/libspl/include/sys/uio.h +++ b/lib/libspl/include/sys/uio.h @@ -57,8 +57,7 @@ typedef enum zfs_uio_rw { } zfs_uio_rw_t; typedef enum zfs_uio_seg { - UIO_USERSPACE = 0, - UIO_SYSSPACE = 1, + UIO_SYSSPACE = 0, } zfs_uio_seg_t; #elif defined(__FreeBSD__) diff --git a/lib/libzfs/libzfs_changelist.c b/lib/libzfs/libzfs_changelist.c index 4db1cbce9568..47df8663165e 100644 --- a/lib/libzfs/libzfs_changelist.c +++ b/lib/libzfs/libzfs_changelist.c @@ -563,8 +563,15 @@ change_one(zfs_handle_t *zhp, void *data) cn = NULL; } - if (!clp->cl_alldependents) - ret = zfs_iter_children_v2(zhp, 0, change_one, data); + if (!clp->cl_alldependents) { + if (clp->cl_prop != ZFS_PROP_MOUNTPOINT) { + ret = zfs_iter_filesystems_v2(zhp, 0, + change_one, data); + } else { + ret = zfs_iter_children_v2(zhp, 0, change_one, + data); + } + } /* * If we added the handle to the changelist, we will re-use it @@ -738,6 +745,11 @@ changelist_gather(zfs_handle_t *zhp, zfs_prop_t prop, int gather_flags, changelist_free(clp); return (NULL); } + } else if (clp->cl_prop != ZFS_PROP_MOUNTPOINT) { + if (zfs_iter_filesystems_v2(zhp, 0, change_one, clp) != 0) { + changelist_free(clp); + return (NULL); + } } else if (zfs_iter_children_v2(zhp, 0, change_one, clp) != 0) { changelist_free(clp); return (NULL); diff --git a/lib/libzfs/libzfs_pool.c b/lib/libzfs/libzfs_pool.c index f256535e8ea0..64f9d1f6eb49 100644 --- a/lib/libzfs/libzfs_pool.c +++ b/lib/libzfs/libzfs_pool.c @@ -5342,7 +5342,8 @@ zpool_get_vdev_prop_value(nvlist_t *nvprop, vdev_prop_t prop, char *prop_name, strval = fnvlist_lookup_string(nv, ZPROP_VALUE); } else { /* user prop not found */ - return (-1); + src = ZPROP_SRC_DEFAULT; + strval = "-"; } (void) strlcpy(buf, strval, len); if (srctype) diff --git a/man/man4/zfs.4 b/man/man4/zfs.4 index da027798f962..7078a5ba8373 100644 --- a/man/man4/zfs.4 +++ b/man/man4/zfs.4 @@ -867,14 +867,14 @@ where that percent may exceed This only operates during memory pressure/reclaim. . -.It Sy zfs_arc_shrinker_limit Ns = Ns Sy 10000 Pq int +.It Sy zfs_arc_shrinker_limit Ns = Ns Sy 0 Pq int This is a limit on how many pages the ARC shrinker makes available for eviction in response to one page allocation attempt. Note that in practice, the kernel's shrinker can ask us to evict up to about four times this for one allocation attempt. To reduce OOM risk, this limit is applied for kswapd reclaims only. .Pp -The default limit of +For example a value of .Sy 10000 Pq in practice, Em 160 MiB No per allocation attempt with 4 KiB pages limits the amount of time spent attempting to reclaim ARC memory to less than 100 ms per allocation attempt, diff --git a/module/Makefile.in b/module/Makefile.in index 9b34b3dfaec7..529ab81dcec5 100644 --- a/module/Makefile.in +++ b/module/Makefile.in @@ -55,6 +55,8 @@ modules-Linux: mkdir -p $(sort $(dir $(zfs-objs) $(zfs-))) $(MAKE) -C @LINUX_OBJ@ $(if @KERNEL_CC@,CC=@KERNEL_CC@) \ $(if @KERNEL_LD@,LD=@KERNEL_LD@) $(if @KERNEL_LLVM@,LLVM=@KERNEL_LLVM@) \ + $(if @KERNEL_CROSS_COMPILE@,CROSS_COMPILE=@KERNEL_CROSS_COMPILE@) \ + $(if @KERNEL_ARCH@,ARCH=@KERNEL_ARCH@) \ M="$$PWD" @KERNEL_MAKE@ CONFIG_ZFS=m modules modules-FreeBSD: diff --git a/module/os/freebsd/zfs/vdev_geom.c b/module/os/freebsd/zfs/vdev_geom.c index b7ff1063b089..7aaa42bfb1a8 100644 --- a/module/os/freebsd/zfs/vdev_geom.c +++ b/module/os/freebsd/zfs/vdev_geom.c @@ -1014,21 +1014,6 @@ vdev_geom_io_intr(struct bio *bp) zio->io_error = SET_ERROR(EIO); switch (zio->io_error) { - case ENOTSUP: - /* - * If we get ENOTSUP for BIO_FLUSH or BIO_DELETE we know - * that future attempts will never succeed. In this case - * we set a persistent flag so that we don't bother with - * requests in the future. - */ - switch (bp->bio_cmd) { - case BIO_FLUSH: - vd->vdev_nowritecache = B_TRUE; - break; - case BIO_DELETE: - break; - } - break; case ENXIO: if (!vd->vdev_remove_wanted) { /* diff --git a/module/os/freebsd/zfs/zfs_vnops_os.c b/module/os/freebsd/zfs/zfs_vnops_os.c index b8c2c341dace..5edd3fcc76e7 100644 --- a/module/os/freebsd/zfs/zfs_vnops_os.c +++ b/module/os/freebsd/zfs/zfs_vnops_os.c @@ -6258,7 +6258,7 @@ struct vop_vector zfs_vnodeops = { .vop_fplookup_vexec = zfs_freebsd_fplookup_vexec, .vop_fplookup_symlink = zfs_freebsd_fplookup_symlink, .vop_access = zfs_freebsd_access, - .vop_allocate = VOP_EINVAL, + .vop_allocate = VOP_EOPNOTSUPP, #if __FreeBSD_version >= 1400032 .vop_deallocate = zfs_deallocate, #endif diff --git a/module/os/linux/zfs/arc_os.c b/module/os/linux/zfs/arc_os.c index b1e45b28743e..3238977af6d1 100644 --- a/module/os/linux/zfs/arc_os.c +++ b/module/os/linux/zfs/arc_os.c @@ -63,7 +63,7 @@ * practice, the kernel's shrinker can ask us to evict up to about 4x this * for one allocation attempt. * - * The default limit of 10,000 (in practice, 160MB per allocation attempt + * For example a value of 10,000 (in practice, 160MB per allocation attempt * with 4K pages) limits the amount of time spent attempting to reclaim ARC * memory to less than 100ms per allocation attempt, even with a small * average compressed block size of ~8KB. @@ -71,7 +71,7 @@ * See also the comment in arc_shrinker_count(). * Set to 0 to disable limit. */ -static int zfs_arc_shrinker_limit = 10000; +static int zfs_arc_shrinker_limit = 0; /* * Relative cost of ARC eviction, AKA number of seeks needed to restore evicted diff --git a/module/os/linux/zfs/vdev_disk.c b/module/os/linux/zfs/vdev_disk.c index 6a66a72b91a9..e8bd513e6909 100644 --- a/module/os/linux/zfs/vdev_disk.c +++ b/module/os/linux/zfs/vdev_disk.c @@ -1198,9 +1198,8 @@ vdev_disk_io_flush_completion(struct bio *bio) { zio_t *zio = bio->bi_private; zio->io_error = bi_status_to_errno(bio->bi_status); - - if (zio->io_error && (zio->io_error == EOPNOTSUPP)) - zio->io_vd->vdev_nowritecache = B_TRUE; + if (zio->io_error == EOPNOTSUPP || zio->io_error == ENOTTY) + zio->io_error = SET_ERROR(ENOTSUP); bio_put(bio); ASSERT3S(zio->io_error, >=, 0); diff --git a/module/os/linux/zfs/zfs_uio.c b/module/os/linux/zfs/zfs_uio.c index f08415fdb2e3..db85b626f12a 100644 --- a/module/os/linux/zfs/zfs_uio.c +++ b/module/os/linux/zfs/zfs_uio.c @@ -68,55 +68,13 @@ zfs_uiomove_iov(void *p, size_t n, zfs_uio_rw_t rw, zfs_uio_t *uio) size_t skip = uio->uio_skip; ulong_t cnt; + ASSERT3S(uio->uio_segflg, ==, UIO_SYSSPACE); while (n && uio->uio_resid) { cnt = MIN(iov->iov_len - skip, n); - switch (uio->uio_segflg) { - case UIO_USERSPACE: - /* - * p = kernel data pointer - * iov->iov_base = user data pointer - */ - if (rw == UIO_READ) { - if (copy_to_user(iov->iov_base+skip, p, cnt)) - return (EFAULT); - } else { - unsigned long b_left = 0; - if (uio->uio_fault_disable) { - if (!zfs_access_ok(VERIFY_READ, - (iov->iov_base + skip), cnt)) { - return (EFAULT); - } - pagefault_disable(); - b_left = - __copy_from_user_inatomic(p, - (iov->iov_base + skip), cnt); - pagefault_enable(); - } else { - b_left = - copy_from_user(p, - (iov->iov_base + skip), cnt); - } - if (b_left > 0) { - unsigned long c_bytes = - cnt - b_left; - uio->uio_skip += c_bytes; - ASSERT3U(uio->uio_skip, <, - iov->iov_len); - uio->uio_resid -= c_bytes; - uio->uio_loffset += c_bytes; - return (EFAULT); - } - } - break; - case UIO_SYSSPACE: - if (rw == UIO_READ) - memcpy(iov->iov_base + skip, p, cnt); - else - memcpy(p, iov->iov_base + skip, cnt); - break; - default: - ASSERT(0); - } + if (rw == UIO_READ) + memcpy(iov->iov_base + skip, p, cnt); + else + memcpy(p, iov->iov_base + skip, cnt); skip += cnt; if (skip == iov->iov_len) { skip = 0; @@ -268,7 +226,6 @@ zfs_uiomove_bvec(void *p, size_t n, zfs_uio_rw_t rw, zfs_uio_t *uio) return (zfs_uiomove_bvec_impl(p, n, rw, uio)); } -#if defined(HAVE_VFS_IOV_ITER) static int zfs_uiomove_iter(void *p, size_t n, zfs_uio_rw_t rw, zfs_uio_t *uio, boolean_t revert) @@ -303,17 +260,14 @@ zfs_uiomove_iter(void *p, size_t n, zfs_uio_rw_t rw, zfs_uio_t *uio, return (0); } -#endif int zfs_uiomove(void *p, size_t n, zfs_uio_rw_t rw, zfs_uio_t *uio) { if (uio->uio_segflg == UIO_BVEC) return (zfs_uiomove_bvec(p, n, rw, uio)); -#if defined(HAVE_VFS_IOV_ITER) else if (uio->uio_segflg == UIO_ITER) return (zfs_uiomove_iter(p, n, rw, uio, B_FALSE)); -#endif else return (zfs_uiomove_iov(p, n, rw, uio)); } @@ -336,44 +290,14 @@ zfs_uio_prefaultpages(ssize_t n, zfs_uio_t *uio) * there is never a time for these pages a fault will occur. */ return (0); -#if defined(HAVE_VFS_IOV_ITER) - } else if (uio->uio_segflg == UIO_ITER) { + } else { + ASSERT3S(uio->uio_segflg, ==, UIO_ITER); /* - * At least a Linux 4.9 kernel, iov_iter_fault_in_readable() + * At least a Linux 4.18 kernel, iov_iter_fault_in_readable() * can be relied on to fault in user pages when referenced. */ if (iov_iter_fault_in_readable(uio->uio_iter, n)) return (EFAULT); -#endif - } else { - /* Fault in all user pages */ - ASSERT3S(uio->uio_segflg, ==, UIO_USERSPACE); - const struct iovec *iov = uio->uio_iov; - int iovcnt = uio->uio_iovcnt; - size_t skip = uio->uio_skip; - uint8_t tmp; - caddr_t p; - - for (; n > 0 && iovcnt > 0; iov++, iovcnt--, skip = 0) { - ulong_t cnt = MIN(iov->iov_len - skip, n); - /* empty iov */ - if (cnt == 0) - continue; - n -= cnt; - /* touch each page in this segment. */ - p = iov->iov_base + skip; - while (cnt) { - if (copy_from_user(&tmp, p, 1)) - return (EFAULT); - ulong_t incr = MIN(cnt, PAGESIZE); - p += incr; - cnt -= incr; - } - /* touch the last byte in case it straddles a page. */ - p--; - if (copy_from_user(&tmp, p, 1)) - return (EFAULT); - } } return (0); @@ -394,10 +318,8 @@ zfs_uiocopy(void *p, size_t n, zfs_uio_rw_t rw, zfs_uio_t *uio, size_t *cbytes) if (uio->uio_segflg == UIO_BVEC) ret = zfs_uiomove_bvec(p, n, rw, &uio_copy); -#if defined(HAVE_VFS_IOV_ITER) else if (uio->uio_segflg == UIO_ITER) ret = zfs_uiomove_iter(p, n, rw, &uio_copy, B_TRUE); -#endif else ret = zfs_uiomove_iov(p, n, rw, &uio_copy); @@ -430,11 +352,10 @@ zfs_uioskip(zfs_uio_t *uio, size_t n) uio->uio_bvec++; uio->uio_iovcnt--; } -#if defined(HAVE_VFS_IOV_ITER) } else if (uio->uio_segflg == UIO_ITER) { iov_iter_advance(uio->uio_iter, n); -#endif } else { + ASSERT3S(uio->uio_segflg, ==, UIO_SYSSPACE); uio->uio_skip += n; while (uio->uio_iovcnt && uio->uio_skip >= uio->uio_iov->iov_len) { @@ -457,8 +378,7 @@ zfs_uio_page_aligned(zfs_uio_t *uio) { boolean_t aligned = B_TRUE; - if (uio->uio_segflg == UIO_USERSPACE || - uio->uio_segflg == UIO_SYSSPACE) { + if (uio->uio_segflg == UIO_SYSSPACE) { const struct iovec *iov = uio->uio_iov; size_t skip = uio->uio_skip; @@ -472,12 +392,10 @@ zfs_uio_page_aligned(zfs_uio_t *uio) } skip = 0; } -#if defined(HAVE_VFS_IOV_ITER) } else if (uio->uio_segflg == UIO_ITER) { unsigned long alignment = iov_iter_alignment(uio->uio_iter); aligned = IS_P2ALIGNED(alignment, PAGE_SIZE); -#endif } else { /* Currently not supported */ aligned = B_FALSE; @@ -523,6 +441,7 @@ zfs_unmark_page(struct page *page) } #endif /* HAVE_ZERO_PAGE_GPL_ONLY || !_LP64 */ +#if !defined(HAVE_PIN_USER_PAGES_UNLOCKED) static void zfs_uio_dio_check_for_zero_page(zfs_uio_t *uio) { @@ -554,6 +473,7 @@ zfs_uio_dio_check_for_zero_page(zfs_uio_t *uio) } } } +#endif void zfs_uio_free_dio_pages(zfs_uio_t *uio, zfs_uio_rw_t rw) @@ -562,6 +482,9 @@ zfs_uio_free_dio_pages(zfs_uio_t *uio, zfs_uio_rw_t rw) ASSERT(uio->uio_extflg & UIO_DIRECT); ASSERT3P(uio->uio_dio.pages, !=, NULL); +#if defined(HAVE_PIN_USER_PAGES_UNLOCKED) + unpin_user_pages(uio->uio_dio.pages, uio->uio_dio.npages); +#else for (long i = 0; i < uio->uio_dio.npages; i++) { struct page *p = uio->uio_dio.pages[i]; @@ -573,114 +496,106 @@ zfs_uio_free_dio_pages(zfs_uio_t *uio, zfs_uio_rw_t rw) put_page(p); } - +#endif vmem_free(uio->uio_dio.pages, uio->uio_dio.npages * sizeof (struct page *)); } -/* - * zfs_uio_iov_step() is just a modified version of the STEP function of Linux's - * iov_iter_get_pages(). - */ +#if defined(HAVE_PIN_USER_PAGES_UNLOCKED) static int -zfs_uio_iov_step(struct iovec v, zfs_uio_rw_t rw, zfs_uio_t *uio, - long *numpages) +zfs_uio_pin_user_pages(zfs_uio_t *uio, zfs_uio_rw_t rw) { - unsigned long addr = (unsigned long)(v.iov_base); - size_t len = v.iov_len; - unsigned long n = DIV_ROUND_UP(len, PAGE_SIZE); + long res; + size_t skip = uio->uio_skip; + size_t len = uio->uio_resid - skip; + unsigned int gup_flags = 0; + unsigned long addr; + unsigned long nr_pages; /* - * read returning FOLL_WRITE is due to the fact that we are stating - * that the kernel will have write access to the user pages. So, when a - * Direct I/O read request is issued, the kernel must write to the user - * pages. + * Kernel 6.2 introduced the FOLL_PCI_P2PDMA flag. This flag could + * possibly be used here in the future to allow for P2P operations with + * user pages. */ - long res = get_user_pages_unlocked( - P2ALIGN_TYPED(addr, PAGE_SIZE, unsigned long), n, - &uio->uio_dio.pages[uio->uio_dio.npages], - rw == UIO_READ ? FOLL_WRITE : 0); - if (res < 0) { - return (SET_ERROR(-res)); - } else if (len != (res * PAGE_SIZE)) { - return (SET_ERROR(EFAULT)); - } - - ASSERT3S(len, ==, res * PAGE_SIZE); - *numpages = res; - return (0); -} - -static int -zfs_uio_get_dio_pages_iov(zfs_uio_t *uio, zfs_uio_rw_t rw) -{ - const struct iovec *iovp = uio->uio_iov; - size_t skip = uio->uio_skip; - size_t len = uio->uio_resid - skip; + if (rw == UIO_READ) + gup_flags = FOLL_WRITE; - ASSERT(uio->uio_segflg != UIO_SYSSPACE); + if (len == 0) + return (0); +#if defined(HAVE_ITER_IS_UBUF) + if (iter_is_ubuf(uio->uio_iter)) { + nr_pages = DIV_ROUND_UP(len, PAGE_SIZE); + addr = (unsigned long)uio->uio_iter->ubuf + skip; + res = pin_user_pages_unlocked(addr, nr_pages, + &uio->uio_dio.pages[uio->uio_dio.npages], gup_flags); + if (res < 0) { + return (SET_ERROR(-res)); + } else if (len != (res * PAGE_SIZE)) { + uio->uio_dio.npages += res; + return (SET_ERROR(EFAULT)); + } + uio->uio_dio.npages += res; + return (0); + } +#endif + const struct iovec *iovp = zfs_uio_iter_iov(uio->uio_iter); for (int i = 0; i < uio->uio_iovcnt; i++) { - struct iovec iov; - long numpages = 0; - - if (iovp->iov_len == 0) { + size_t amt = iovp->iov_len - skip; + if (amt == 0) { iovp++; skip = 0; continue; } - iov.iov_len = MIN(len, iovp->iov_len - skip); - iov.iov_base = iovp->iov_base + skip; - int error = zfs_uio_iov_step(iov, rw, uio, &numpages); - if (error) - return (error); + addr = (unsigned long)iovp->iov_base + skip; + nr_pages = DIV_ROUND_UP(amt, PAGE_SIZE); + res = pin_user_pages_unlocked(addr, nr_pages, + &uio->uio_dio.pages[uio->uio_dio.npages], gup_flags); + if (res < 0) { + return (SET_ERROR(-res)); + } else if (amt != (res * PAGE_SIZE)) { + uio->uio_dio.npages += res; + return (SET_ERROR(EFAULT)); + } - uio->uio_dio.npages += numpages; - len -= iov.iov_len; + len -= amt; + uio->uio_dio.npages += res; skip = 0; iovp++; - } + }; ASSERT0(len); return (0); } -#if defined(HAVE_VFS_IOV_ITER) +#else static int zfs_uio_get_dio_pages_iov_iter(zfs_uio_t *uio, zfs_uio_rw_t rw) { - size_t skip = uio->uio_skip; + size_t start; size_t wanted = uio->uio_resid - uio->uio_skip; ssize_t rollback = 0; ssize_t cnt; unsigned maxpages = DIV_ROUND_UP(wanted, PAGE_SIZE); while (wanted) { -#if defined(HAVE_IOV_ITER_GET_PAGES2) - cnt = iov_iter_get_pages2(uio->uio_iter, - &uio->uio_dio.pages[uio->uio_dio.npages], - wanted, maxpages, &skip); -#else cnt = iov_iter_get_pages(uio->uio_iter, &uio->uio_dio.pages[uio->uio_dio.npages], - wanted, maxpages, &skip); -#endif + wanted, maxpages, &start); if (cnt < 0) { iov_iter_revert(uio->uio_iter, rollback); return (SET_ERROR(-cnt)); } + /* + * All Direct I/O operations must be page aligned. + */ + ASSERT(IS_P2ALIGNED(start, PAGE_SIZE)); uio->uio_dio.npages += DIV_ROUND_UP(cnt, PAGE_SIZE); rollback += cnt; wanted -= cnt; - skip = 0; -#if !defined(HAVE_IOV_ITER_GET_PAGES2) - /* - * iov_iter_get_pages2() advances the iov_iter on success. - */ iov_iter_advance(uio->uio_iter, cnt); -#endif } ASSERT3U(rollback, ==, uio->uio_resid - uio->uio_skip); @@ -688,7 +603,7 @@ zfs_uio_get_dio_pages_iov_iter(zfs_uio_t *uio, zfs_uio_rw_t rw) return (0); } -#endif /* HAVE_VFS_IOV_ITER */ +#endif /* HAVE_PIN_USER_PAGES_UNLOCKED */ /* * This function pins user pages. In the event that the user pages were not @@ -703,12 +618,11 @@ zfs_uio_get_dio_pages_alloc(zfs_uio_t *uio, zfs_uio_rw_t rw) long npages = DIV_ROUND_UP(uio->uio_resid, PAGE_SIZE); size_t size = npages * sizeof (struct page *); - if (uio->uio_segflg == UIO_USERSPACE) { - uio->uio_dio.pages = vmem_alloc(size, KM_SLEEP); - error = zfs_uio_get_dio_pages_iov(uio, rw); -#if defined(HAVE_VFS_IOV_ITER) - } else if (uio->uio_segflg == UIO_ITER) { + if (uio->uio_segflg == UIO_ITER) { uio->uio_dio.pages = vmem_alloc(size, KM_SLEEP); +#if defined(HAVE_PIN_USER_PAGES_UNLOCKED) + error = zfs_uio_pin_user_pages(uio, rw); +#else error = zfs_uio_get_dio_pages_iov_iter(uio, rw); #endif } else { @@ -718,17 +632,22 @@ zfs_uio_get_dio_pages_alloc(zfs_uio_t *uio, zfs_uio_rw_t rw) ASSERT3S(uio->uio_dio.npages, >=, 0); if (error) { +#if defined(HAVE_PIN_USER_PAGES_UNLOCKED) + unpin_user_pages(uio->uio_dio.pages, uio->uio_dio.npages); +#else for (long i = 0; i < uio->uio_dio.npages; i++) put_page(uio->uio_dio.pages[i]); +#endif vmem_free(uio->uio_dio.pages, size); return (error); } else { ASSERT3S(uio->uio_dio.npages, ==, npages); } - if (rw == UIO_WRITE) { +#if !defined(HAVE_PIN_USER_PAGES_UNLOCKED) + if (rw == UIO_WRITE) zfs_uio_dio_check_for_zero_page(uio); - } +#endif uio->uio_extflg |= UIO_DIRECT; diff --git a/module/os/linux/zfs/zfs_vfsops.c b/module/os/linux/zfs/zfs_vfsops.c index 3c53a8a315c3..b226fca147a5 100644 --- a/module/os/linux/zfs/zfs_vfsops.c +++ b/module/os/linux/zfs/zfs_vfsops.c @@ -1702,13 +1702,14 @@ zfs_vget(struct super_block *sb, struct inode **ipp, fid_t *fidp) /* A zero fid_gen means we are in the .zfs control directories */ if (fid_gen == 0 && (object == ZFSCTL_INO_ROOT || object == ZFSCTL_INO_SNAPDIR)) { - *ipp = zfsvfs->z_ctldir; - ASSERT(*ipp != NULL); - if (zfsvfs->z_show_ctldir == ZFS_SNAPDIR_DISABLED) { + zfs_exit(zfsvfs, FTAG); return (SET_ERROR(ENOENT)); } + *ipp = zfsvfs->z_ctldir; + ASSERT(*ipp != NULL); + if (object == ZFSCTL_INO_SNAPDIR) { VERIFY(zfsctl_root_lookup(*ipp, "snapshot", ipp, 0, kcred, NULL, NULL) == 0); diff --git a/module/os/linux/zfs/zpl_file.c b/module/os/linux/zfs/zpl_file.c index ff1370c543dc..42dfddc2717b 100644 --- a/module/os/linux/zfs/zpl_file.c +++ b/module/os/linux/zfs/zpl_file.c @@ -216,27 +216,6 @@ zpl_file_accessed(struct file *filp) } } -/* - * When HAVE_VFS_IOV_ITER is defined the iov_iter structure supports - * iovecs, kvevs, bvecs and pipes, plus all the required interfaces to - * manipulate the iov_iter are available. In which case the full iov_iter - * can be attached to the uio and correctly handled in the lower layers. - * Otherwise, for older kernels extract the iovec and pass it instead. - */ -static void -zpl_uio_init(zfs_uio_t *uio, struct kiocb *kiocb, struct iov_iter *to, - loff_t pos, ssize_t count, size_t skip) -{ -#if defined(HAVE_VFS_IOV_ITER) - zfs_uio_iov_iter_init(uio, to, pos, count, skip); -#else - 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); -#endif -} - static ssize_t zpl_iter_read(struct kiocb *kiocb, struct iov_iter *to) { @@ -246,7 +225,7 @@ zpl_iter_read(struct kiocb *kiocb, struct iov_iter *to) ssize_t count = iov_iter_count(to); zfs_uio_t uio; - zpl_uio_init(&uio, kiocb, to, kiocb->ki_pos, count, 0); + zfs_uio_iov_iter_init(&uio, to, kiocb->ki_pos, count, 0); crhold(cr); cookie = spl_fstrans_mark(); @@ -296,7 +275,8 @@ zpl_iter_write(struct kiocb *kiocb, struct iov_iter *from) if (ret) return (ret); - zpl_uio_init(&uio, kiocb, from, kiocb->ki_pos, count, from->iov_offset); + zfs_uio_iov_iter_init(&uio, from, kiocb->ki_pos, count, + from->iov_offset); crhold(cr); cookie = spl_fstrans_mark(); @@ -317,34 +297,18 @@ zpl_iter_write(struct kiocb *kiocb, struct iov_iter *from) } static ssize_t -zpl_direct_IO_impl(void) +zpl_direct_IO(struct kiocb *kiocb, struct iov_iter *iter) { /* * All O_DIRECT requests should be handled by - * zpl_{iter/aio}_{write/read}(). There is no way kernel generic code - * should call the direct_IO address_space_operations function. We set - * this code path to be fatal if it is executed. + * zpl_iter_write/read}(). There is no way kernel generic code should + * call the direct_IO address_space_operations function. We set this + * code path to be fatal if it is executed. */ PANIC(0); return (0); } -#if defined(HAVE_VFS_DIRECT_IO_ITER) -static ssize_t -zpl_direct_IO(struct kiocb *kiocb, struct iov_iter *iter) -{ - return (zpl_direct_IO_impl()); -} -#elif defined(HAVE_VFS_DIRECT_IO_ITER_OFFSET) -static ssize_t -zpl_direct_IO(struct kiocb *kiocb, struct iov_iter *iter, loff_t pos) -{ - return (zpl_direct_IO_impl()); -} -#else -#error "Unknown Direct I/O interface" -#endif - static loff_t zpl_llseek(struct file *filp, loff_t offset, int whence) { @@ -1104,14 +1068,12 @@ const struct file_operations zpl_file_operations = { .llseek = zpl_llseek, .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 .mmap = zpl_mmap, .fsync = zpl_fsync, .fallocate = zpl_fallocate, diff --git a/module/zcommon/simd_stat.c b/module/zcommon/simd_stat.c index 33c15140cdb9..d82a88ca9343 100644 --- a/module/zcommon/simd_stat.c +++ b/module/zcommon/simd_stat.c @@ -132,8 +132,10 @@ simd_stat_kstat_data(char *buf, size_t size, void *data) #if defined(__arm__) || defined(__aarch64__) off += SIMD_STAT_PRINT(simd_stat_kstat_payload, "kernel_neon", HAVE_KERNEL_NEON); +#if defined(CONFIG_KERNEL_MODE_NEON) off += SIMD_STAT_PRINT(simd_stat_kstat_payload, "kernel_mode_neon", CONFIG_KERNEL_MODE_NEON); +#endif /* CONFIG_KERNEL_MODE_NEON */ off += SIMD_STAT_PRINT(simd_stat_kstat_payload, "neon", zfs_neon_available()); off += SIMD_STAT_PRINT(simd_stat_kstat_payload, diff --git a/module/zcommon/zpool_prop.c b/module/zcommon/zpool_prop.c index a709679b9032..ea9eda4b316d 100644 --- a/module/zcommon/zpool_prop.c +++ b/module/zcommon/zpool_prop.c @@ -105,7 +105,7 @@ zpool_prop_init(void) PROP_READONLY, ZFS_TYPE_POOL, "", "FRAG", B_FALSE, sfeatures); zprop_register_number(ZPOOL_PROP_CAPACITY, "capacity", 0, PROP_READONLY, - ZFS_TYPE_POOL, "", "CAP", B_FALSE, sfeatures); + ZFS_TYPE_POOL, "", "CAP", B_FALSE, sfeatures); zprop_register_number(ZPOOL_PROP_GUID, "guid", 0, PROP_READONLY, ZFS_TYPE_POOL, "", "GUID", B_TRUE, sfeatures); zprop_register_number(ZPOOL_PROP_LOAD_GUID, "load_guid", 0, diff --git a/module/zfs/spa.c b/module/zfs/spa.c index b83c982c13fd..c9dfd7ac2e4d 100644 --- a/module/zfs/spa.c +++ b/module/zfs/spa.c @@ -8948,16 +8948,26 @@ spa_async_remove(spa_t *spa, vdev_t *vd) } static void -spa_async_fault_vdev(spa_t *spa, vdev_t *vd) +spa_async_fault_vdev(vdev_t *vd, boolean_t *suspend) { if (vd->vdev_fault_wanted) { + vdev_state_t newstate = VDEV_STATE_FAULTED; vd->vdev_fault_wanted = B_FALSE; - vdev_set_state(vd, B_TRUE, VDEV_STATE_FAULTED, - VDEV_AUX_ERR_EXCEEDED); - } + /* + * If this device has the only valid copy of the data, then + * back off and simply mark the vdev as degraded instead. + */ + if (!vd->vdev_top->vdev_islog && vd->vdev_aux == NULL && + vdev_dtl_required(vd)) { + newstate = VDEV_STATE_DEGRADED; + /* A required disk is missing so suspend the pool */ + *suspend = B_TRUE; + } + vdev_set_state(vd, B_TRUE, newstate, VDEV_AUX_ERR_EXCEEDED); + } for (int c = 0; c < vd->vdev_children; c++) - spa_async_fault_vdev(spa, vd->vdev_child[c]); + spa_async_fault_vdev(vd->vdev_child[c], suspend); } static void @@ -9049,8 +9059,11 @@ spa_async_thread(void *arg) */ if (tasks & SPA_ASYNC_FAULT_VDEV) { spa_vdev_state_enter(spa, SCL_NONE); - spa_async_fault_vdev(spa, spa->spa_root_vdev); + boolean_t suspend = B_FALSE; + spa_async_fault_vdev(spa->spa_root_vdev, &suspend); (void) spa_vdev_state_exit(spa, NULL, 0); + if (suspend) + zio_suspend(spa, NULL, ZIO_SUSPEND_IOERR); } /* diff --git a/module/zfs/vdev.c b/module/zfs/vdev.c index 9f0f1dee656c..d9c5871820ca 100644 --- a/module/zfs/vdev.c +++ b/module/zfs/vdev.c @@ -2041,6 +2041,7 @@ vdev_open(vdev_t *vd) vd->vdev_cant_read = B_FALSE; vd->vdev_cant_write = B_FALSE; vd->vdev_fault_wanted = B_FALSE; + vd->vdev_remove_wanted = B_FALSE; vd->vdev_min_asize = vdev_get_min_asize(vd); /* @@ -5969,7 +5970,7 @@ vdev_prop_set(vdev_t *vd, nvlist_t *innvl, nvlist_t *outnvl) goto end; } - if (vdev_prop_readonly(prop)) { + if (prop != VDEV_PROP_USERPROP && vdev_prop_readonly(prop)) { error = EROFS; goto end; } diff --git a/module/zfs/vdev_raidz.c b/module/zfs/vdev_raidz.c index e4487c485075..6103f780e6bc 100644 --- a/module/zfs/vdev_raidz.c +++ b/module/zfs/vdev_raidz.c @@ -3914,8 +3914,8 @@ raidz_reflow_read_done(zio_t *zio) if (atomic_dec_32_nv(&rra->rra_tbd) > 0) return; - rra->rra_tbd = rra->rra_writes; - for (uint64_t i = 0; i < rra->rra_writes; i++) + uint32_t writes = rra->rra_tbd = rra->rra_writes; + for (uint64_t i = 0; i < writes; i++) zio_nowait(rra->rra_zio[i]); } diff --git a/module/zfs/zap_micro.c b/module/zfs/zap_micro.c index 55b60006e58c..a9298d3e940e 100644 --- a/module/zfs/zap_micro.c +++ b/module/zfs/zap_micro.c @@ -54,14 +54,25 @@ * machinery to understand not to try to split a microzap block). * * If large_microzap is enabled, this value will be clamped to - * spa_maxblocksize(). If not, it will be clamped to SPA_OLD_MAXBLOCKSIZE. + * spa_maxblocksize(), up to 1M. If not, it will be clamped to + * SPA_OLD_MAXBLOCKSIZE. */ static int zap_micro_max_size = SPA_OLD_MAXBLOCKSIZE; +/* + * The 1M upper limit is necessary because the count of chunks in a microzap + * block is stored as a uint16_t (mze_chunkid). Each chunk is 64 bytes, and the + * first is used to store a header, so there are 32767 usable chunks, which is + * just under 2M. 1M is the largest power-2-rounded block size under 2M, so we + * must set the limit there. + */ +#define MZAP_MAX_SIZE (1048576) + uint64_t zap_get_micro_max_size(spa_t *spa) { - uint64_t maxsz = P2ROUNDUP(zap_micro_max_size, SPA_MINBLOCKSIZE); + uint64_t maxsz = MIN(MZAP_MAX_SIZE, + P2ROUNDUP(zap_micro_max_size, SPA_MINBLOCKSIZE)); if (maxsz <= SPA_OLD_MAXBLOCKSIZE) return (maxsz); if (spa_feature_is_enabled(spa, SPA_FEATURE_LARGE_MICROZAP)) @@ -2031,5 +2042,6 @@ EXPORT_SYMBOL(zap_cursor_init_serialized); EXPORT_SYMBOL(zap_get_stats); ZFS_MODULE_PARAM(zfs, , zap_micro_max_size, INT, ZMOD_RW, - "Maximum micro ZAP size, before converting to a fat ZAP, in bytes"); + "Maximum micro ZAP size before converting to a fat ZAP, " + "in bytes (max 1M)"); #endif diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index 6c15a5c472ea..8c8ed255e686 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -71,7 +71,7 @@ int zfs_bclone_enabled = 1; * a copy of the file and is therefore not the default. However, in certain * scenarios this behavior may be desirable so a tunable is provided. */ -static int zfs_bclone_wait_dirty = 0; +int zfs_bclone_wait_dirty = 0; /* * Enable Direct I/O. If this setting is 0, then all I/O requests will be diff --git a/module/zfs/zio.c b/module/zfs/zio.c index f4d7e57542a1..bd6752f00ac5 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -4606,13 +4606,16 @@ zio_vdev_io_assess(zio_t *zio) } /* - * If a cache flush returns ENOTSUP or ENOTTY, we know that no future + * If a cache flush returns ENOTSUP we know that no future * attempts will ever succeed. In this case we set a persistent - * boolean flag so that we don't bother with it in the future. + * boolean flag so that we don't bother with it in the future, and + * then we act like the flush succeeded. */ - if ((zio->io_error == ENOTSUP || zio->io_error == ENOTTY) && - zio->io_type == ZIO_TYPE_FLUSH && vd != NULL) + if (zio->io_error == ENOTSUP && zio->io_type == ZIO_TYPE_FLUSH && + vd != NULL) { vd->vdev_nowritecache = B_TRUE; + zio->io_error = 0; + } if (zio->io_error) zio->io_pipeline = ZIO_INTERLOCK_PIPELINE; diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c index fec595b2c4c5..14a6219d19cd 100644 --- a/module/zfs/zvol.c +++ b/module/zfs/zvol.c @@ -93,6 +93,7 @@ unsigned int zvol_volmode = ZFS_VOLMODE_GEOM; struct hlist_head *zvol_htable; static list_t zvol_state_list; krwlock_t zvol_state_lock; +extern int zfs_bclone_wait_dirty; typedef enum { ZVOL_ASYNC_REMOVE_MINORS, @@ -516,6 +517,285 @@ zvol_replay_write(void *arg1, void *arg2, boolean_t byteswap) return (error); } +/* + * Replay a TX_CLONE_RANGE ZIL transaction that didn't get committed + * after a system failure + */ +static int +zvol_replay_clone_range(void *arg1, void *arg2, boolean_t byteswap) +{ + zvol_state_t *zv = arg1; + lr_clone_range_t *lr = arg2; + objset_t *os = zv->zv_objset; + dmu_tx_t *tx; + int error; + uint64_t blksz; + uint64_t off; + uint64_t len; + + ASSERT3U(lr->lr_common.lrc_reclen, >=, sizeof (*lr)); + ASSERT3U(lr->lr_common.lrc_reclen, >=, offsetof(lr_clone_range_t, + lr_bps[lr->lr_nbps])); + + if (byteswap) + byteswap_uint64_array(lr, sizeof (*lr)); + + ASSERT(spa_feature_is_enabled(dmu_objset_spa(os), + SPA_FEATURE_BLOCK_CLONING)); + + off = lr->lr_offset; + len = lr->lr_length; + blksz = lr->lr_blksz; + + if ((off % blksz) != 0) { + return (SET_ERROR(EINVAL)); + } + + error = dnode_hold(os, ZVOL_OBJ, zv, &zv->zv_dn); + if (error != 0 || !zv->zv_dn) + return (error); + tx = dmu_tx_create(os); + dmu_tx_hold_clone_by_dnode(tx, zv->zv_dn, off, len); + error = dmu_tx_assign(tx, TXG_WAIT); + if (error != 0) { + dmu_tx_abort(tx); + goto out; + } + error = dmu_brt_clone(zv->zv_objset, ZVOL_OBJ, off, len, + tx, lr->lr_bps, lr->lr_nbps); + if (error != 0) { + dmu_tx_commit(tx); + goto out; + } + + /* + * zil_replaying() not only check if we are replaying ZIL, but also + * updates the ZIL header to record replay progress. + */ + VERIFY(zil_replaying(zv->zv_zilog, tx)); + dmu_tx_commit(tx); + +out: + dnode_rele(zv->zv_dn, zv); + zv->zv_dn = NULL; + return (error); +} + +int +zvol_clone_range(zvol_state_t *zv_src, uint64_t inoff, zvol_state_t *zv_dst, + uint64_t outoff, uint64_t len) +{ + zilog_t *zilog_dst; + zfs_locked_range_t *inlr, *outlr; + objset_t *inos, *outos; + dmu_tx_t *tx; + blkptr_t *bps; + size_t maxblocks; + int error = EINVAL; + + rw_enter(&zv_dst->zv_suspend_lock, RW_READER); + if (zv_dst->zv_zilog == NULL) { + rw_exit(&zv_dst->zv_suspend_lock); + rw_enter(&zv_dst->zv_suspend_lock, RW_WRITER); + if (zv_dst->zv_zilog == NULL) { + zv_dst->zv_zilog = zil_open(zv_dst->zv_objset, + zvol_get_data, &zv_dst->zv_kstat.dk_zil_sums); + zv_dst->zv_flags |= ZVOL_WRITTEN_TO; + VERIFY0((zv_dst->zv_zilog->zl_header->zh_flags & + ZIL_REPLAY_NEEDED)); + } + rw_downgrade(&zv_dst->zv_suspend_lock); + } + if (zv_src != zv_dst) + rw_enter(&zv_src->zv_suspend_lock, RW_READER); + + inos = zv_src->zv_objset; + outos = zv_dst->zv_objset; + + /* + * Sanity checks + */ + if (!spa_feature_is_enabled(dmu_objset_spa(outos), + SPA_FEATURE_BLOCK_CLONING)) { + error = EOPNOTSUPP; + goto out; + } + if (dmu_objset_spa(inos) != dmu_objset_spa(outos)) { + error = EXDEV; + goto out; + } + if (inos->os_encrypted != outos->os_encrypted) { + error = EXDEV; + goto out; + } + if (zv_src->zv_volblocksize != zv_dst->zv_volblocksize) { + error = EINVAL; + goto out; + } + if (inoff >= zv_src->zv_volsize || outoff >= zv_dst->zv_volsize) { + error = 0; + goto out; + } + + /* + * Do not read beyond boundary + */ + if (len > zv_src->zv_volsize - inoff) + len = zv_src->zv_volsize - inoff; + if (len > zv_dst->zv_volsize - outoff) + len = zv_dst->zv_volsize - outoff; + if (len == 0) { + error = 0; + goto out; + } + + /* + * No overlapping if we are cloning within the same file + */ + if (zv_src == zv_dst) { + if (inoff < outoff + len && outoff < inoff + len) { + error = EINVAL; + goto out; + } + } + + /* + * Offsets and length must be at block boundaries + */ + if ((inoff % zv_src->zv_volblocksize) != 0 || + (outoff % zv_dst->zv_volblocksize) != 0) { + error = EINVAL; + goto out; + } + + /* + * Length must be multiple of block size + */ + if ((len % zv_src->zv_volblocksize) != 0) { + error = EINVAL; + goto out; + } + + zilog_dst = zv_dst->zv_zilog; + maxblocks = zil_max_log_data(zilog_dst, sizeof (lr_clone_range_t)) / + sizeof (bps[0]); + bps = vmem_alloc(sizeof (bps[0]) * maxblocks, KM_SLEEP); + /* + * Maintain predictable lock order. + */ + if (zv_src < zv_dst || (zv_src == zv_dst && inoff < outoff)) { + inlr = zfs_rangelock_enter(&zv_src->zv_rangelock, inoff, len, + RL_READER); + outlr = zfs_rangelock_enter(&zv_dst->zv_rangelock, outoff, len, + RL_WRITER); + } else { + outlr = zfs_rangelock_enter(&zv_dst->zv_rangelock, outoff, len, + RL_WRITER); + inlr = zfs_rangelock_enter(&zv_src->zv_rangelock, inoff, len, + RL_READER); + } + + while (len > 0) { + uint64_t size, last_synced_txg; + size_t nbps = maxblocks; + size = MIN(zv_src->zv_volblocksize * maxblocks, len); + last_synced_txg = spa_last_synced_txg( + dmu_objset_spa(zv_src->zv_objset)); + error = dmu_read_l0_bps(zv_src->zv_objset, ZVOL_OBJ, inoff, + size, bps, &nbps); + if (error != 0) { + /* + * If we are trying to clone a block that was created + * in the current transaction group, the error will be + * EAGAIN here. Based on zfs_bclone_wait_dirty either + * return a shortened range to the caller so it can + * fallback, or wait for the next TXG and check again. + */ + if (error == EAGAIN && zfs_bclone_wait_dirty) { + txg_wait_synced(dmu_objset_pool + (zv_src->zv_objset), last_synced_txg + 1); + continue; + } + break; + } + + tx = dmu_tx_create(zv_dst->zv_objset); + dmu_tx_hold_clone_by_dnode(tx, zv_dst->zv_dn, outoff, size); + error = dmu_tx_assign(tx, TXG_WAIT); + if (error != 0) { + dmu_tx_abort(tx); + break; + } + error = dmu_brt_clone(zv_dst->zv_objset, ZVOL_OBJ, outoff, size, + tx, bps, nbps); + if (error != 0) { + dmu_tx_commit(tx); + break; + } + zvol_log_clone_range(zilog_dst, tx, TX_CLONE_RANGE, outoff, + size, zv_src->zv_volblocksize, bps, nbps); + dmu_tx_commit(tx); + inoff += size; + outoff += size; + len -= size; + } + vmem_free(bps, sizeof (bps[0]) * maxblocks); + zfs_rangelock_exit(outlr); + zfs_rangelock_exit(inlr); + if (error == 0 && zv_dst->zv_objset->os_sync == ZFS_SYNC_ALWAYS) { + zil_commit(zilog_dst, ZVOL_OBJ); + } +out: + if (zv_src != zv_dst) + rw_exit(&zv_src->zv_suspend_lock); + rw_exit(&zv_dst->zv_suspend_lock); + return (SET_ERROR(error)); +} + +/* + * Handles TX_CLONE_RANGE transactions. + */ +void +zvol_log_clone_range(zilog_t *zilog, dmu_tx_t *tx, int txtype, uint64_t off, + uint64_t len, uint64_t blksz, const blkptr_t *bps, size_t nbps) +{ + itx_t *itx; + lr_clone_range_t *lr; + uint64_t partlen, max_log_data; + size_t partnbps; + + if (zil_replaying(zilog, tx)) + return; + + max_log_data = zil_max_log_data(zilog, sizeof (lr_clone_range_t)); + + while (nbps > 0) { + partnbps = MIN(nbps, max_log_data / sizeof (bps[0])); + partlen = partnbps * blksz; + ASSERT3U(partlen, <, len + blksz); + partlen = MIN(partlen, len); + + itx = zil_itx_create(txtype, + sizeof (*lr) + sizeof (bps[0]) * partnbps); + lr = (lr_clone_range_t *)&itx->itx_lr; + lr->lr_foid = ZVOL_OBJ; + lr->lr_offset = off; + lr->lr_length = partlen; + lr->lr_blksz = blksz; + lr->lr_nbps = partnbps; + memcpy(lr->lr_bps, bps, sizeof (bps[0]) * partnbps); + + zil_itx_assign(zilog, itx, tx); + + bps += partnbps; + ASSERT3U(nbps, >=, partnbps); + nbps -= partnbps; + off += partlen; + ASSERT3U(len, >=, partlen); + len -= partlen; + } +} + static int zvol_replay_err(void *arg1, void *arg2, boolean_t byteswap) { @@ -540,7 +820,9 @@ zil_replay_func_t *const zvol_replay_vector[TX_MAX_TYPE] = { zvol_replay_write, /* TX_WRITE */ zvol_replay_truncate, /* TX_TRUNCATE */ zvol_replay_err, /* TX_SETATTR */ + zvol_replay_err, /* TX_ACL_V0 */ zvol_replay_err, /* TX_ACL */ + zvol_replay_err, /* TX_CREATE_ACL */ zvol_replay_err, /* TX_CREATE_ATTR */ zvol_replay_err, /* TX_CREATE_ACL_ATTR */ zvol_replay_err, /* TX_MKDIR_ACL */ @@ -550,7 +832,7 @@ zil_replay_func_t *const zvol_replay_vector[TX_MAX_TYPE] = { zvol_replay_err, /* TX_SETSAXATTR */ zvol_replay_err, /* TX_RENAME_EXCHANGE */ zvol_replay_err, /* TX_RENAME_WHITEOUT */ - zvol_replay_err, /* TX_CLONE_RANGE */ + zvol_replay_clone_range, /* TX_CLONE_RANGE */ }; /* diff --git a/rpm/generic/zfs-kmod.spec.in b/rpm/generic/zfs-kmod.spec.in index 30524474d1ac..7ed828bd0c9c 100644 --- a/rpm/generic/zfs-kmod.spec.in +++ b/rpm/generic/zfs-kmod.spec.in @@ -144,7 +144,9 @@ for kernel_version in %{?kernel_versions}; do %{debuginfo} \ %{?kernel_cc} \ %{?kernel_ld} \ - %{?kernel_llvm} + %{?kernel_llvm} \ + %{?kernel_cross_compile} \ + %{?kernel_arch} # Pre-6.10 kernel builds didn't need to copy over the source files to the # build directory. However we do need to do it though post-6.10 due to diff --git a/rpm/redhat/zfs-kmod.spec.in b/rpm/redhat/zfs-kmod.spec.in index 876c198c64de..a95bdf20f873 100644 --- a/rpm/redhat/zfs-kmod.spec.in +++ b/rpm/redhat/zfs-kmod.spec.in @@ -69,7 +69,9 @@ fi %{debuginfo} \ %{?kernel_cc} \ %{?kernel_ld} \ - %{?kernel_llvm} + %{?kernel_llvm} \ + %{?kernel_cross_compile} \ + %{?kernel_arch} make %{?_smp_mflags} # Module signing (modsign) diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 7d9cef83d2c6..ee8fb8717cec 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -79,7 +79,7 @@ CLEANFILES += %D%/common.sh -$(AM_V_at)echo "$$SCRIPTS_EXTRA_ENVIRONMENT" >>$@ ALL_LOCAL += scripts-all-local -scripts-all-local: %D%/common.sh +scripts-all-local: %D%/common.sh $(PROGRAMS) $(SCRIPTS) $(DATA) -SCRIPT_COMMON=$< $(srcdir)/%D%/zfs-tests.sh -c CLEAN_LOCAL += scripts-clean-local diff --git a/tests/runfiles/common.run b/tests/runfiles/common.run index a69d36df2f98..1d6f6d85200f 100644 --- a/tests/runfiles/common.run +++ b/tests/runfiles/common.run @@ -676,8 +676,8 @@ post = tags = ['functional', 'deadman'] [tests/functional/dedup] -tests = ['dedup_legacy_create', 'dedup_fdt_create', 'dedup_fdt_import', - 'dedup_legacy_create', 'dedup_legacy_import', 'dedup_legacy_fdt_upgrade', +tests = ['dedup_fdt_create', 'dedup_fdt_import', 'dedup_legacy_create', + 'dedup_legacy_import', 'dedup_legacy_fdt_upgrade', 'dedup_legacy_fdt_mixed', 'dedup_quota'] pre = post = diff --git a/tests/runfiles/linux.run b/tests/runfiles/linux.run index 76d07a6cc9c1..e55ec583d2cc 100644 --- a/tests/runfiles/linux.run +++ b/tests/runfiles/linux.run @@ -125,8 +125,8 @@ tests = ['auto_offline_001_pos', 'auto_online_001_pos', 'auto_online_002_pos', 'auto_replace_001_pos', 'auto_replace_002_pos', 'auto_spare_001_pos', 'auto_spare_002_pos', 'auto_spare_multiple', 'auto_spare_ashift', 'auto_spare_shared', 'decrypt_fault', 'decompress_fault', - 'fault_limits', 'scrub_after_resilver', 'suspend_resume_single', - 'zpool_status_-s'] + 'fault_limits', 'scrub_after_resilver', 'suspend_on_probe_errors', + 'suspend_resume_single', 'zpool_status_-s'] tags = ['functional', 'fault'] [tests/functional/features/large_dnode:Linux] diff --git a/tests/zfs-tests/include/blkdev.shlib b/tests/zfs-tests/include/blkdev.shlib index 51eff3023e73..5b505f925286 100644 --- a/tests/zfs-tests/include/blkdev.shlib +++ b/tests/zfs-tests/include/blkdev.shlib @@ -556,27 +556,15 @@ function list_file_blocks # input_file # 512B blocks for ease of use with dd. # typeset level vdev path offset length - if awk -n '' 2>/dev/null; then - # gawk needs -n to decode hex - AWK='awk -n' - else - AWK='awk' - fi sync_all_pools true - zdb -dddddd $ds $objnum | $AWK -v pad=$((4<<20)) -v bs=512 ' + zdb -dddddd $ds $objnum | awk ' /^$/ { looking = 0 } looking { level = $2 field = 3 while (split($field, dva, ":") == 3) { - # top level vdev id - vdev = int(dva[1]) - # offset + 4M label/boot pad in 512B blocks - offset = (int("0x"dva[2]) + pad) / bs - # length in 512B blocks - len = int("0x"dva[3]) / bs - print level, vdev, offset, len + print level, int(dva[1]), "0x"dva[2], "0x"dva[3] ++field } @@ -585,7 +573,8 @@ function list_file_blocks # input_file ' | \ while read level vdev offset length; do for path in ${VDEV_MAP[$vdev][@]}; do - echo "$level $path $offset $length" + echo "$level $path $(( ($offset + (4<<20)) / 512 ))" \ + "$(( $length / 512 ))" done done 2>/dev/null } diff --git a/tests/zfs-tests/tests/Makefile.am b/tests/zfs-tests/tests/Makefile.am index 67630cb564ae..bde33843098f 100644 --- a/tests/zfs-tests/tests/Makefile.am +++ b/tests/zfs-tests/tests/Makefile.am @@ -1531,6 +1531,7 @@ nobase_dist_datadir_zfs_tests_tests_SCRIPTS += \ functional/fault/decrypt_fault.ksh \ functional/fault/fault_limits.ksh \ functional/fault/scrub_after_resilver.ksh \ + functional/fault/suspend_on_probe_errors.ksh \ functional/fault/suspend_resume_single.ksh \ functional/fault/setup.ksh \ functional/fault/zpool_status_-s.ksh \ diff --git a/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_all_fail.ksh b/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_all_fail.ksh index d1103bddccbd..7b6c2ccdf660 100755 --- a/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_all_fail.ksh +++ b/tests/zfs-tests/tests/functional/cli_root/zfs_mount/zfs_mount_all_fail.ksh @@ -16,6 +16,7 @@ # # Copyright (c) 2017 by Delphix. All rights reserved. +# Copyright 2024 MNX Cloud, Inc. # . $STF_SUITE/include/libtest.shlib @@ -44,8 +45,9 @@ typeset fscount=10 function setup_all { # Create $fscount filesystems at the top level of $path - for ((i=0; i<$fscount; i++)); do + for ((i=0; i /sys/block/$sd/device/state" + fi + unload_scsi_debug + rm -f $DATA_FILE + for i in {0..$((FILE_VDEV_CNT - 1))}; do + log_must rm -f "$TEST_BASE_DIR/dev-$i" + done + log_must set_tunable32 SCAN_SUSPEND_PROGRESS 0 + zed_start +} + +log_onexit cleanup + +log_assert "VDEV probe errors for more disks than parity should suspend a pool" + +log_note "Stoping ZED process" +zed_stop +zpool events -c + +# Make a debug device that we can "unplug" and lose 4 drives at once +unload_scsi_debug +load_scsi_debug $DEV_SIZE_MB 1 1 1 '512b' +sd=$(get_debug_device) + +# Create 4 partitions that match the FILE_VDEV_SIZ +parted "/dev/${sd}" --script mklabel gpt +parted "/dev/${sd}" --script mkpart primary 0% 25% +parted "/dev/${sd}" --script mkpart primary 25% 50% +parted "/dev/${sd}" --script mkpart primary 50% 75% +parted "/dev/${sd}" --script mkpart primary 75% 100% +block_device_wait "/dev/${sd}" +blkdevs="/dev/${sd}1 /dev/${sd}2 /dev/${sd}3 /dev/${sd}4" + +# Create 8 file vdevs +typeset -a filedevs +for i in {0..$((FILE_VDEV_CNT - 1))}; do + device=$TEST_BASE_DIR/dev-$i + log_must truncate -s $FILE_VDEV_SIZ $device + # Use all but the last one for pool create + if [[ $i -lt "7" ]]; then + filedevs[${#filedevs[*]}+1]=$device + fi +done + +# Create a raidz-3 pool that we can pull 4 disks from +log_must zpool create -f $TESTPOOL raidz3 ${filedevs[@]} $blkdevs +sync_pool $TESTPOOL + +# Add some data to the pool +log_must zfs create $TESTPOOL/fs +MNTPOINT="$(get_prop mountpoint $TESTPOOL/fs)" +SECONDS=0 +log_must fill_fs $MNTPOINT 1 200 4096 10 Z +log_note "fill_fs took $SECONDS seconds" +sync_pool $TESTPOOL + +# Start a replacing vdev, but suspend the resilver +log_must set_tunable32 SCAN_SUSPEND_PROGRESS 1 +log_must zpool replace -f $TESTPOOL /dev/${sd}4 $TEST_BASE_DIR/dev-7 + +# Remove 4 disks all at once +log_must eval "echo offline > /sys/block/${sd}/device/state" + +log_must set_tunable32 SCAN_SUSPEND_PROGRESS 0 + +# Add some writes to drive the vdev probe errors +log_must dd if=/dev/urandom of=$MNTPOINT/writes bs=1M count=1 + +# Wait until sync starts, and the pool suspends +log_note "waiting for pool to suspend" +typeset -i tries=30 +until [[ $(cat /proc/spl/kstat/zfs/$TESTPOOL/state) == "SUSPENDED" ]] ; do + if ((tries-- == 0)); then + zpool status -s + log_fail "UNEXPECTED -- pool did not suspend" + fi + sleep 1 +done +log_note $(cat /proc/spl/kstat/zfs/$TESTPOOL/state) + +# Put the missing disks back into service +log_must eval "echo running > /sys/block/$sd/device/state" + +# Clear the vdev error states, which will reopen the vdevs and resume the pool +log_must zpool clear $TESTPOOL + +# Wait until the pool resumes +log_note "waiting for pool to resume" +tries=30 +until [[ $(cat /proc/spl/kstat/zfs/$TESTPOOL/state) != "SUSPENDED" ]] ; do + if ((tries-- == 0)); then + log_fail "pool did not resume" + fi + sleep 1 +done +log_must zpool wait -t resilver $TESTPOOL +sync_pool $TESTPOOL + +# Make sure a pool scrub comes back clean +log_must zpool scrub -w $TESTPOOL +log_must zpool status -v $TESTPOOL +log_must check_pool_status $TESTPOOL "errors" "No known data errors" + +log_pass "VDEV probe errors for more disks than parity should suspend a pool" diff --git a/tests/zfs-tests/tests/functional/mount/cleanup.ksh b/tests/zfs-tests/tests/functional/mount/cleanup.ksh index bd6b0e435ed1..0e88e2a1fc79 100755 --- a/tests/zfs-tests/tests/functional/mount/cleanup.ksh +++ b/tests/zfs-tests/tests/functional/mount/cleanup.ksh @@ -27,12 +27,14 @@ # # Copyright (c) 2013, 2016 by Delphix. All rights reserved. +# Copyright 2025 MNX Cloud, Inc. # . $STF_SUITE/include/libtest.shlib log_must destroy_pool $TESTPOOL -for dir in $TESTDIRS; do +for i in 1 2 3; do + dir=$TESTDIR.$i rm -rf $dir done diff --git a/tests/zfs-tests/tests/functional/pam/cleanup.ksh b/tests/zfs-tests/tests/functional/pam/cleanup.ksh index dbcb175ed069..bfb98cd30707 100755 --- a/tests/zfs-tests/tests/functional/pam/cleanup.ksh +++ b/tests/zfs-tests/tests/functional/pam/cleanup.ksh @@ -27,4 +27,4 @@ destroy_pool $TESTPOOL del_user ${username} del_user ${username}rec del_group pamtestgroup -log_must rm -rf "$runstatedir" $TESTDIRS +log_must rm -rf "$runstatedir" diff --git a/tests/zfs-tests/tests/functional/pool_checkpoint/checkpoint_discard_busy.ksh b/tests/zfs-tests/tests/functional/pool_checkpoint/checkpoint_discard_busy.ksh index 087aef9027ea..2bf5ab199e6e 100755 --- a/tests/zfs-tests/tests/functional/pool_checkpoint/checkpoint_discard_busy.ksh +++ b/tests/zfs-tests/tests/functional/pool_checkpoint/checkpoint_discard_busy.ksh @@ -42,8 +42,8 @@ log_unsupported "Skipping, issue https://github.com/openzfs/zfs/issues/12053" function test_cleanup { - # reset memory limit to 16M - set_tunable64 SPA_DISCARD_MEMORY_LIMIT 1000000 + # reset to original value + log_must restore_tunable SPA_DISCARD_MEMORY_LIMIT cleanup_nested_pools } @@ -69,6 +69,7 @@ log_onexit test_cleanup # map, we should have even more time to # verify this. # +log_must save_tunable SPA_DISCARD_MEMORY_LIMIT set_tunable64 SPA_DISCARD_MEMORY_LIMIT 128 log_must zpool checkpoint $NESTEDPOOL @@ -101,8 +102,8 @@ log_mustnot zpool checkpoint -d $NESTEDPOOL log_mustnot zpool remove $NESTEDPOOL $FILEDISK1 log_mustnot zpool reguid $NESTEDPOOL -# reset memory limit to 16M -set_tunable64 SPA_DISCARD_MEMORY_LIMIT 16777216 +# reset to original value +log_must restore_tunable SPA_DISCARD_MEMORY_LIMIT nested_wait_discard_finish diff --git a/tests/zfs-tests/tests/functional/raidz/raidz_expand_001_pos.ksh b/tests/zfs-tests/tests/functional/raidz/raidz_expand_001_pos.ksh index d4923fdb67d9..125b0e5411a3 100755 --- a/tests/zfs-tests/tests/functional/raidz/raidz_expand_001_pos.ksh +++ b/tests/zfs-tests/tests/functional/raidz/raidz_expand_001_pos.ksh @@ -200,13 +200,13 @@ log_must zpool create -f -o cachefile=none $TESTPOOL $raid ${disks[@]} log_must zfs set primarycache=metadata $TESTPOOL log_must zfs create $TESTPOOL/fs -log_must fill_fs /$TESTPOOL/fs 1 512 100 1024 R +log_must fill_fs /$TESTPOOL/fs 1 512 102400 1 R log_must zfs create -o compress=on $TESTPOOL/fs2 -log_must fill_fs /$TESTPOOL/fs2 1 512 100 1024 R +log_must fill_fs /$TESTPOOL/fs2 1 512 102400 1 R log_must zfs create -o compress=on -o recordsize=8k $TESTPOOL/fs3 -log_must fill_fs /$TESTPOOL/fs3 1 512 100 1024 R +log_must fill_fs /$TESTPOOL/fs3 1 512 102400 1 R log_must check_pool_status $TESTPOOL "errors" "No known data errors" diff --git a/tests/zfs-tests/tests/functional/raidz/raidz_expand_002_pos.ksh b/tests/zfs-tests/tests/functional/raidz/raidz_expand_002_pos.ksh index 56810aca099f..185316a7cb85 100755 --- a/tests/zfs-tests/tests/functional/raidz/raidz_expand_002_pos.ksh +++ b/tests/zfs-tests/tests/functional/raidz/raidz_expand_002_pos.ksh @@ -78,13 +78,13 @@ log_must zpool create -f $opts $pool $raid ${disks[1..$(($nparity+1))]} log_must zfs set primarycache=metadata $pool log_must zfs create $pool/fs -log_must fill_fs /$pool/fs 1 512 100 1024 R +log_must fill_fs /$pool/fs 1 512 102400 1 R log_must zfs create -o compress=on $pool/fs2 -log_must fill_fs /$pool/fs2 1 512 100 1024 R +log_must fill_fs /$pool/fs2 1 512 102400 1 R log_must zfs create -o compress=on -o recordsize=8k $pool/fs3 -log_must fill_fs /$pool/fs3 1 512 100 1024 R +log_must fill_fs /$pool/fs3 1 512 102400 1 R typeset pool_size=$(get_pool_prop size $pool) diff --git a/tests/zfs-tests/tests/functional/raidz/raidz_expand_003_neg.ksh b/tests/zfs-tests/tests/functional/raidz/raidz_expand_003_neg.ksh index 4d85c46897b8..a2eb87b1f722 100755 --- a/tests/zfs-tests/tests/functional/raidz/raidz_expand_003_neg.ksh +++ b/tests/zfs-tests/tests/functional/raidz/raidz_expand_003_neg.ksh @@ -92,7 +92,7 @@ log_must zpool destroy $pool log_must zpool create -f $opts $pool $raid ${disks[1..$(($devs-1))]} log_must zfs set primarycache=metadata $pool log_must zfs create $pool/fs -log_must fill_fs /$pool/fs 1 512 100 1024 R +log_must fill_fs /$pool/fs 1 512 102400 1 R allocated=$(zpool list -Hp -o allocated $pool) log_must set_tunable64 RAIDZ_EXPAND_MAX_REFLOW_BYTES $((allocated / 4)) log_must zpool attach $pool ${raid}-0 ${disks[$devs]} diff --git a/tests/zfs-tests/tests/functional/raidz/raidz_expand_003_pos.ksh b/tests/zfs-tests/tests/functional/raidz/raidz_expand_003_pos.ksh index 712b25261773..6f852c516ca4 100755 --- a/tests/zfs-tests/tests/functional/raidz/raidz_expand_003_pos.ksh +++ b/tests/zfs-tests/tests/functional/raidz/raidz_expand_003_pos.ksh @@ -94,10 +94,10 @@ opts="-o cachefile=none" log_must zpool create -f $opts $pool $raid ${disks[1..$(($nparity+1))]} log_must zfs create -o recordsize=8k $pool/fs -log_must fill_fs /$pool/fs 1 256 100 1024 R +log_must fill_fs /$pool/fs 1 256 102400 1 R log_must zfs create -o recordsize=128k $pool/fs2 -log_must fill_fs /$pool/fs2 1 256 100 1024 R +log_must fill_fs /$pool/fs2 1 256 102400 1 R for disk in ${disks[$(($nparity+2))..$devs]}; do log_must mkfile -n 400m /$pool/fs/file diff --git a/tests/zfs-tests/tests/functional/raidz/raidz_expand_004_pos.ksh b/tests/zfs-tests/tests/functional/raidz/raidz_expand_004_pos.ksh index 2be55dae4254..5056e4e4b1fd 100755 --- a/tests/zfs-tests/tests/functional/raidz/raidz_expand_004_pos.ksh +++ b/tests/zfs-tests/tests/functional/raidz/raidz_expand_004_pos.ksh @@ -81,10 +81,10 @@ log_must set_tunable32 SCRUB_AFTER_EXPAND 0 log_must zpool create -f $opts $pool $raid ${disks[1..$(($nparity+1))]} log_must zfs create -o recordsize=8k $pool/fs -log_must fill_fs /$pool/fs 1 128 100 1024 R +log_must fill_fs /$pool/fs 1 128 102400 1 R log_must zfs create -o recordsize=128k $pool/fs2 -log_must fill_fs /$pool/fs2 1 128 100 1024 R +log_must fill_fs /$pool/fs2 1 128 102400 1 R for disk in ${disks[$(($nparity+2))..$devs]}; do log_must zpool attach $pool ${raid}-0 $disk diff --git a/tests/zfs-tests/tests/functional/raidz/raidz_expand_005_pos.ksh b/tests/zfs-tests/tests/functional/raidz/raidz_expand_005_pos.ksh index 56ee3e9be67c..49b9f6c1d353 100755 --- a/tests/zfs-tests/tests/functional/raidz/raidz_expand_005_pos.ksh +++ b/tests/zfs-tests/tests/functional/raidz/raidz_expand_005_pos.ksh @@ -137,10 +137,10 @@ log_must zpool create -f $opts $pool $raid ${disks[1..$(($nparity+1))]} devices="${disks[1..$(($nparity+1))]}" log_must zfs create -o recordsize=8k $pool/fs -log_must fill_fs /$pool/fs 1 128 100 1024 R +log_must fill_fs /$pool/fs 1 128 102400 1 R log_must zfs create -o recordsize=128k $pool/fs2 -log_must fill_fs /$pool/fs2 1 128 100 1024 R +log_must fill_fs /$pool/fs2 1 128 102400 1 R for disk in ${disks[$(($nparity+2))..$devs]}; do # Set pause to some random value near halfway point diff --git a/tests/zfs-tests/tests/functional/redacted_send/redacted_panic.ksh b/tests/zfs-tests/tests/functional/redacted_send/redacted_panic.ksh index 032d1fb91a2e..a2438c2cd731 100755 --- a/tests/zfs-tests/tests/functional/redacted_send/redacted_panic.ksh +++ b/tests/zfs-tests/tests/functional/redacted_send/redacted_panic.ksh @@ -39,7 +39,7 @@ function cleanup log_onexit cleanup log_must zfs create -o recsize=8k $sendfs -log_must dd if=/dev/urandom of=/$sendfs/file bs=1024k count=2048 +log_must dd if=/dev/urandom of=/$sendfs/file bs=1024k count=1024 log_must zfs snapshot $sendfs@init log_must zfs clone $sendfs@init $clone log_must stride_dd -i /dev/urandom -o /$clone/file -b 8192 -s 2 -c 7226 diff --git a/tests/zfs-tests/tests/functional/redundancy/redundancy_draid.ksh b/tests/zfs-tests/tests/functional/redundancy/redundancy_draid.ksh index 8208d2b4a398..df113a98aa3c 100755 --- a/tests/zfs-tests/tests/functional/redundancy/redundancy_draid.ksh +++ b/tests/zfs-tests/tests/functional/redundancy/redundancy_draid.ksh @@ -223,13 +223,13 @@ for nparity in 1 2 3; do log_must zfs set primarycache=metadata $TESTPOOL log_must zfs create $TESTPOOL/fs - log_must fill_fs /$TESTPOOL/fs 1 512 100 1024 R + log_must fill_fs /$TESTPOOL/fs 1 512 102400 1 R log_must zfs create -o compress=on $TESTPOOL/fs2 - log_must fill_fs /$TESTPOOL/fs2 1 512 100 1024 R + log_must fill_fs /$TESTPOOL/fs2 1 512 102400 1 R log_must zfs create -o compress=on -o recordsize=8k $TESTPOOL/fs3 - log_must fill_fs /$TESTPOOL/fs3 1 512 100 1024 R + log_must fill_fs /$TESTPOOL/fs3 1 512 102400 1 R typeset pool_size=$(get_pool_prop size $TESTPOOL) diff --git a/tests/zfs-tests/tests/functional/redundancy/redundancy_draid_damaged1.ksh b/tests/zfs-tests/tests/functional/redundancy/redundancy_draid_damaged1.ksh index 110c69159eb1..50d7358411dc 100755 --- a/tests/zfs-tests/tests/functional/redundancy/redundancy_draid_damaged1.ksh +++ b/tests/zfs-tests/tests/functional/redundancy/redundancy_draid_damaged1.ksh @@ -119,13 +119,13 @@ for nparity in 1 2 3; do log_must zfs set primarycache=metadata $TESTPOOL log_must zfs create $TESTPOOL/fs - log_must fill_fs /$TESTPOOL/fs 1 512 100 1024 R + log_must fill_fs /$TESTPOOL/fs 1 512 102400 1 R log_must zfs create -o compress=on $TESTPOOL/fs2 - log_must fill_fs /$TESTPOOL/fs2 1 512 100 1024 R + log_must fill_fs /$TESTPOOL/fs2 1 512 102400 1 R log_must zfs create -o compress=on -o recordsize=8k $TESTPOOL/fs3 - log_must fill_fs /$TESTPOOL/fs3 1 512 100 1024 R + log_must fill_fs /$TESTPOOL/fs3 1 512 102400 1 R log_must zpool export $TESTPOOL log_must zpool import -o cachefile=none -d $dir $TESTPOOL diff --git a/tests/zfs-tests/tests/functional/redundancy/redundancy_draid_damaged2.ksh b/tests/zfs-tests/tests/functional/redundancy/redundancy_draid_damaged2.ksh index b0bb4ef84129..ad66f8633986 100755 --- a/tests/zfs-tests/tests/functional/redundancy/redundancy_draid_damaged2.ksh +++ b/tests/zfs-tests/tests/functional/redundancy/redundancy_draid_damaged2.ksh @@ -94,13 +94,13 @@ for nparity in 1 2 3; do # log_must zfs set primarycache=metadata $TESTPOOL log_must zfs create $TESTPOOL/fs - log_must fill_fs /$TESTPOOL/fs 1 256 10 1024 R + log_must fill_fs /$TESTPOOL/fs 1 256 10240 1 R log_must zfs create -o compress=on $TESTPOOL/fs2 - log_must fill_fs /$TESTPOOL/fs2 1 256 10 1024 R + log_must fill_fs /$TESTPOOL/fs2 1 256 10240 1 R log_must zfs create -o compress=on -o recordsize=8k $TESTPOOL/fs3 - log_must fill_fs /$TESTPOOL/fs3 1 256 10 1024 R + log_must fill_fs /$TESTPOOL/fs3 1 256 10240 1 R log_must zpool export $TESTPOOL log_must zpool import -o cachefile=none -d $dir $TESTPOOL diff --git a/tests/zfs-tests/tests/functional/redundancy/redundancy_raidz.ksh b/tests/zfs-tests/tests/functional/redundancy/redundancy_raidz.ksh index 83cacda84b09..7de35c947fec 100755 --- a/tests/zfs-tests/tests/functional/redundancy/redundancy_raidz.ksh +++ b/tests/zfs-tests/tests/functional/redundancy/redundancy_raidz.ksh @@ -223,13 +223,13 @@ for nparity in 1 2 3; do log_must zfs set primarycache=metadata $TESTPOOL log_must zfs create $TESTPOOL/fs - log_must fill_fs /$TESTPOOL/fs 1 512 100 1024 R + log_must fill_fs /$TESTPOOL/fs 1 512 102400 1 R log_must zfs create -o compress=on $TESTPOOL/fs2 - log_must fill_fs /$TESTPOOL/fs2 1 512 100 1024 R + log_must fill_fs /$TESTPOOL/fs2 1 512 102400 1 R log_must zfs create -o compress=on -o recordsize=8k $TESTPOOL/fs3 - log_must fill_fs /$TESTPOOL/fs3 1 512 100 1024 R + log_must fill_fs /$TESTPOOL/fs3 1 512 102400 1 R typeset pool_size=$(get_pool_prop size $TESTPOOL)