zfs: merge openzfs/zfs@62677576a (zfs-2.2-release) into stable/14

Notable upstream pull request merges:
 #15274 f7a07d76e Retire z_nr_znodes
 #15278 62677576a ZIL: Fix potential race on flush deferring
 #15279 11943656f Update the MOS directory on spa_upgrade_errlog()
 #15281 54c6fbd37 zed: Allow autoreplace and fault LEDs for removed vdevs

Obtained from:	OpenZFS
OpenZFS commit:	62677576a7
This commit is contained in:
Martin Matuska 2023-09-21 11:29:21 +02:00
commit 35e5fd1b28
29 changed files with 394 additions and 78 deletions

View file

@ -6,5 +6,5 @@ Release: rc4
Release-Tags: relext Release-Tags: relext
License: CDDL License: CDDL
Author: OpenZFS Author: OpenZFS
Linux-Maximum: 6.4 Linux-Maximum: 6.5
Linux-Minimum: 3.10 Linux-Minimum: 3.10

View file

@ -372,6 +372,7 @@ zfs_process_add(zpool_handle_t *zhp, nvlist_t *vdev, boolean_t labeled)
/* Only autoreplace bad disks */ /* Only autoreplace bad disks */
if ((vs->vs_state != VDEV_STATE_DEGRADED) && if ((vs->vs_state != VDEV_STATE_DEGRADED) &&
(vs->vs_state != VDEV_STATE_FAULTED) && (vs->vs_state != VDEV_STATE_FAULTED) &&
(vs->vs_state != VDEV_STATE_REMOVED) &&
(vs->vs_state != VDEV_STATE_CANT_OPEN)) { (vs->vs_state != VDEV_STATE_CANT_OPEN)) {
zed_log_msg(LOG_INFO, " not autoreplacing since disk isn't in " zed_log_msg(LOG_INFO, " not autoreplacing since disk isn't in "
"a bad state (currently %llu)", vs->vs_state); "a bad state (currently %llu)", vs->vs_state);

View file

@ -121,7 +121,7 @@ state_to_val()
{ {
state="$1" state="$1"
case "$state" in case "$state" in
FAULTED|DEGRADED|UNAVAIL) FAULTED|DEGRADED|UNAVAIL|REMOVED)
echo 1 echo 1
;; ;;
ONLINE) ONLINE)

View file

@ -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 <linux/fs.h>
#include <linux/blkdev.h>
], [
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_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], [ ZFS_LINUX_TEST_RESULT([blkdev_get_by_path], [
AC_MSG_RESULT(yes) 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 <linux/fs.h>
#include <linux/blkdev.h>
], [
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 <linux/fs.h>
#include <linux/blkdev.h>
], [
struct block_device *bdev = NULL;
void *holder = NULL;
blkdev_put(bdev, holder);
])
])
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_PUT], [ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_PUT], [
AC_MSG_CHECKING([whether blkdev_put() exists]) AC_MSG_CHECKING([whether blkdev_put() exists])
ZFS_LINUX_TEST_RESULT([blkdev_put], [ ZFS_LINUX_TEST_RESULT([blkdev_put], [
AC_MSG_RESULT(yes) 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], [ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [
ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH 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
ZFS_AC_KERNEL_SRC_BLKDEV_PUT_HOLDER
ZFS_AC_KERNEL_SRC_BLKDEV_REREAD_PART ZFS_AC_KERNEL_SRC_BLKDEV_REREAD_PART
ZFS_AC_KERNEL_SRC_BLKDEV_INVALIDATE_BDEV ZFS_AC_KERNEL_SRC_BLKDEV_INVALIDATE_BDEV
ZFS_AC_KERNEL_SRC_BLKDEV_LOOKUP_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_PART_TO_DEV
ZFS_AC_KERNEL_SRC_BLKDEV_DISK_CHECK_MEDIA_CHANGE ZFS_AC_KERNEL_SRC_BLKDEV_DISK_CHECK_MEDIA_CHANGE
ZFS_AC_KERNEL_SRC_BLKDEV_BLK_STS_RESV_CONFLICT ZFS_AC_KERNEL_SRC_BLKDEV_BLK_STS_RESV_CONFLICT
ZFS_AC_KERNEL_SRC_BLKDEV_BLK_MODE_T
]) ])
AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [ 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_PART_TO_DEV
ZFS_AC_KERNEL_BLKDEV_DISK_CHECK_MEDIA_CHANGE ZFS_AC_KERNEL_BLKDEV_DISK_CHECK_MEDIA_CHANGE
ZFS_AC_KERNEL_BLKDEV_BLK_STS_RESV_CONFLICT ZFS_AC_KERNEL_BLKDEV_BLK_STS_RESV_CONFLICT
ZFS_AC_KERNEL_BLKDEV_BLK_MODE_T
]) ])

View file

@ -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 <linux/blkdev.h>
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_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], [ ZFS_LINUX_TEST_RESULT([block_device_operations_release_void], [
AC_MSG_RESULT(yes) 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], [ 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_CHECK_EVENTS
ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID 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 ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK
]) ])

View file

@ -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 <linux/fs.h>
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)
])
])

View file

@ -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 <linux/sysctl.h>
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])
])
])

View file

@ -6,8 +6,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_IOV_ITER], [
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/uio.h> #include <linux/uio.h>
],[ ],[
int type __attribute__ ((unused)) = int type __attribute__ ((unused)) = ITER_KVEC;
ITER_IOVEC | ITER_KVEC | ITER_BVEC | ITER_PIPE;
]) ])
ZFS_LINUX_TEST_SRC([iov_iter_advance], [ 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 }; struct iov_iter iter = { 0 };
__attribute__((unused)) enum iter_type i = iov_iter_type(&iter); __attribute__((unused)) enum iter_type i = iov_iter_type(&iter);
]) ])
ZFS_LINUX_TEST_SRC([iter_iov], [
#include <linux/fs.h>
#include <linux/uio.h>
],[
struct iov_iter iter = { 0 };
__attribute__((unused)) const struct iovec *iov = iter_iov(&iter);
])
]) ])
AC_DEFUN([ZFS_AC_KERNEL_VFS_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, AC_DEFINE(HAVE_VFS_IOV_ITER, 1,
[All required iov_iter interfaces are available]) [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)
])
]) ])

View file

@ -160,6 +160,8 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
ZFS_AC_KERNEL_SRC_FILEMAP ZFS_AC_KERNEL_SRC_FILEMAP
ZFS_AC_KERNEL_SRC_WRITEPAGE_T ZFS_AC_KERNEL_SRC_WRITEPAGE_T
ZFS_AC_KERNEL_SRC_RECLAIMED ZFS_AC_KERNEL_SRC_RECLAIMED
ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_TABLE
ZFS_AC_KERNEL_SRC_COPY_SPLICE_READ
case "$host_cpu" in case "$host_cpu" in
powerpc*) powerpc*)
ZFS_AC_KERNEL_SRC_CPU_HAS_FEATURE 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_FILEMAP
ZFS_AC_KERNEL_WRITEPAGE_T ZFS_AC_KERNEL_WRITEPAGE_T
ZFS_AC_KERNEL_RECLAIMED ZFS_AC_KERNEL_RECLAIMED
ZFS_AC_KERNEL_REGISTER_SYSCTL_TABLE
ZFS_AC_KERNEL_COPY_SPLICE_READ
case "$host_cpu" in case "$host_cpu" in
powerpc*) powerpc*)
ZFS_AC_KERNEL_CPU_HAS_FEATURE ZFS_AC_KERNEL_CPU_HAS_FEATURE

View file

@ -93,7 +93,6 @@ struct zfsvfs {
zfs_teardown_lock_t z_teardown_lock; zfs_teardown_lock_t z_teardown_lock;
zfs_teardown_inactive_lock_t z_teardown_inactive_lock; zfs_teardown_inactive_lock_t z_teardown_inactive_lock;
list_t z_all_znodes; /* all vnodes in the fs */ 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 */ kmutex_t z_znodes_lock; /* lock for z_all_znodes */
struct zfsctl_root *z_ctldir; /* .zfs directory pointer */ struct zfsctl_root *z_ctldir; /* .zfs directory pointer */
boolean_t z_show_ctldir; /* expose .zfs in the root dir */ boolean_t z_show_ctldir; /* expose .zfs in the root dir */

View file

@ -347,6 +347,7 @@ zfs_check_media_change(struct block_device *bdev)
#define vdev_bdev_reread_part(bdev) zfs_check_media_change(bdev) #define vdev_bdev_reread_part(bdev) zfs_check_media_change(bdev)
#elif defined(HAVE_DISK_CHECK_MEDIA_CHANGE) #elif defined(HAVE_DISK_CHECK_MEDIA_CHANGE)
#define vdev_bdev_reread_part(bdev) disk_check_media_change(bdev->bd_disk) #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 #else
/* /*
* This is encountered if check_disk_change() and bdev_check_media_change() * 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 #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. * Kernels without bio_set_op_attrs use bi_rw for the bio flags.
*/ */

View file

@ -173,4 +173,16 @@ zfs_uio_iov_iter_init(zfs_uio_t *uio, struct iov_iter *iter, offset_t offset,
} }
#endif #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 */ #endif /* SPL_UIO_H */

View file

@ -105,7 +105,6 @@ struct zfsvfs {
rrmlock_t z_teardown_lock; rrmlock_t z_teardown_lock;
krwlock_t z_teardown_inactive_lock; krwlock_t z_teardown_inactive_lock;
list_t z_all_znodes; /* all znodes in the fs */ 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_rollback_time; /* last online rollback time */
unsigned long z_snap_defer_time; /* last snapshot unmount deferral */ unsigned long z_snap_defer_time; /* last snapshot unmount deferral */
kmutex_t z_znodes_lock; /* lock for z_all_znodes */ kmutex_t z_znodes_lock; /* lock for z_all_znodes */

View file

@ -203,11 +203,9 @@ For more information, see the
section. section.
.El .El
.Pp .Pp
Virtual devices cannot be nested, so a mirror or raidz virtual device can only Virtual devices cannot be nested arbitrarily.
contain files or disks. A mirror, raidz or draid virtual device can only be created with files or disks.
Mirrors of mirrors Mirrors of mirrors or other such combinations are not allowed.
.Pq or other combinations
are not allowed.
.Pp .Pp
A pool can have any number of virtual devices at the top of the configuration A pool can have any number of virtual devices at the top of the configuration
.Po known as .Po known as

View file

@ -168,4 +168,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 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: 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}'

View file

@ -1158,7 +1158,6 @@ zfsvfs_free(zfsvfs_t *zfsvfs)
mutex_destroy(&zfsvfs->z_znodes_lock); mutex_destroy(&zfsvfs->z_znodes_lock);
mutex_destroy(&zfsvfs->z_lock); mutex_destroy(&zfsvfs->z_lock);
ASSERT3U(zfsvfs->z_nr_znodes, ==, 0);
list_destroy(&zfsvfs->z_all_znodes); list_destroy(&zfsvfs->z_all_znodes);
ZFS_TEARDOWN_DESTROY(zfsvfs); ZFS_TEARDOWN_DESTROY(zfsvfs);
ZFS_TEARDOWN_INACTIVE_DESTROY(zfsvfs); ZFS_TEARDOWN_INACTIVE_DESTROY(zfsvfs);
@ -1562,12 +1561,11 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
* may add the parents of dir-based xattrs to the taskq * may add the parents of dir-based xattrs to the taskq
* so we want to wait for these. * so we want to wait for these.
* *
* We can safely read z_nr_znodes without locking because the * We can safely check z_all_znodes for being empty because the
* VFS has already blocked operations which add to the * VFS has already blocked operations which add to it.
* z_all_znodes list and thus increment z_nr_znodes.
*/ */
int round = 0; int round = 0;
while (zfsvfs->z_nr_znodes > 0) { while (!list_is_empty(&zfsvfs->z_all_znodes)) {
taskq_wait_outstanding(dsl_pool_zrele_taskq( taskq_wait_outstanding(dsl_pool_zrele_taskq(
dmu_objset_pool(zfsvfs->z_os)), 0); dmu_objset_pool(zfsvfs->z_os)), 0);
if (++round > 1 && !unmounting) if (++round > 1 && !unmounting)

View file

@ -537,7 +537,6 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
mutex_enter(&zfsvfs->z_znodes_lock); mutex_enter(&zfsvfs->z_znodes_lock);
list_insert_tail(&zfsvfs->z_all_znodes, zp); list_insert_tail(&zfsvfs->z_all_znodes, zp);
zfsvfs->z_nr_znodes++;
zp->z_zfsvfs = zfsvfs; zp->z_zfsvfs = zfsvfs;
mutex_exit(&zfsvfs->z_znodes_lock); mutex_exit(&zfsvfs->z_znodes_lock);
@ -1286,7 +1285,6 @@ zfs_znode_free(znode_t *zp)
mutex_enter(&zfsvfs->z_znodes_lock); mutex_enter(&zfsvfs->z_znodes_lock);
POINTER_INVALIDATE(&zp->z_zfsvfs); POINTER_INVALIDATE(&zp->z_zfsvfs);
list_remove(&zfsvfs->z_all_znodes, zp); list_remove(&zfsvfs->z_all_znodes, zp);
zfsvfs->z_nr_znodes--;
mutex_exit(&zfsvfs->z_znodes_lock); mutex_exit(&zfsvfs->z_znodes_lock);
#if __FreeBSD_version >= 1300139 #if __FreeBSD_version >= 1300139

View file

@ -47,6 +47,10 @@ static unsigned long table_min = 0;
static unsigned long table_max = ~0; static unsigned long table_max = ~0;
static struct ctl_table_header *spl_header = NULL; 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 = NULL;
static struct proc_dir_entry *proc_spl_kmem = NULL; static struct proc_dir_entry *proc_spl_kmem = NULL;
static struct proc_dir_entry *proc_spl_kmem_slab = NULL; static struct proc_dir_entry *proc_spl_kmem_slab = NULL;
@ -624,6 +628,7 @@ static struct ctl_table spl_table[] = {
.mode = 0644, .mode = 0644,
.proc_handler = &proc_dohostid, .proc_handler = &proc_dohostid,
}, },
#ifdef HAVE_REGISTER_SYSCTL_TABLE
{ {
.procname = "kmem", .procname = "kmem",
.mode = 0555, .mode = 0555,
@ -634,9 +639,11 @@ static struct ctl_table spl_table[] = {
.mode = 0555, .mode = 0555,
.child = spl_kstat_table, .child = spl_kstat_table,
}, },
#endif
{}, {},
}; };
#ifdef HAVE_REGISTER_SYSCTL_TABLE
static struct ctl_table spl_dir[] = { static struct ctl_table spl_dir[] = {
{ {
.procname = "spl", .procname = "spl",
@ -648,21 +655,64 @@ static struct ctl_table spl_dir[] = {
static struct ctl_table spl_root[] = { static struct ctl_table spl_root[] = {
{ {
.procname = "kernel", .procname = "kernel",
.mode = 0555, .mode = 0555,
.child = spl_dir, .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 int
spl_proc_init(void) spl_proc_init(void)
{ {
int rc = 0; int rc = 0;
#ifdef HAVE_REGISTER_SYSCTL_TABLE
spl_header = register_sysctl_table(spl_root); spl_header = register_sysctl_table(spl_root);
if (spl_header == NULL) if (spl_header == NULL)
return (-EUNATCH); 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); proc_spl = proc_mkdir("spl", NULL);
if (proc_spl == NULL) { if (proc_spl == NULL) {
@ -703,15 +753,8 @@ spl_proc_init(void)
goto out; goto out;
} }
out: out:
if (rc) { if (rc)
remove_proc_entry("kstat", proc_spl); spl_proc_cleanup();
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);
}
return (rc); return (rc);
} }
@ -719,13 +762,5 @@ out:
void void
spl_proc_fini(void) spl_proc_fini(void)
{ {
remove_proc_entry("kstat", proc_spl); spl_proc_cleanup();
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);
} }

View file

@ -80,9 +80,22 @@ typedef struct dio_request {
static unsigned int zfs_vdev_failfast_mask = 1; static unsigned int zfs_vdev_failfast_mask = 1;
#ifdef HAVE_BLK_MODE_T
static blk_mode_t
#else
static fmode_t static fmode_t
#endif
vdev_bdev_mode(spa_mode_t spa_mode) 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; fmode_t mode = 0;
if (spa_mode & SPA_MODE_READ) if (spa_mode & SPA_MODE_READ)
@ -90,6 +103,7 @@ vdev_bdev_mode(spa_mode_t spa_mode)
if (spa_mode & SPA_MODE_WRITE) if (spa_mode & SPA_MODE_WRITE)
mode |= FMODE_WRITE; mode |= FMODE_WRITE;
#endif
return (mode); 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 static int
vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize, vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize,
uint64_t *logical_ashift, uint64_t *physical_ashift) uint64_t *logical_ashift, uint64_t *physical_ashift)
{ {
struct block_device *bdev; 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)); fmode_t mode = vdev_bdev_mode(spa_mode(v->vdev_spa));
#endif
hrtime_t timeout = MSEC2NSEC(zfs_vdev_open_timeout_ms); hrtime_t timeout = MSEC2NSEC(zfs_vdev_open_timeout_ms);
vdev_disk_t *vd; 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; reread_part = B_TRUE;
} }
blkdev_put(bdev, mode | FMODE_EXCL); vdev_blkdev_put(bdev, mode, zfs_vdev_holder);
} }
if (reread_part) { if (reread_part) {
bdev = blkdev_get_by_path(disk_name, mode | FMODE_EXCL, bdev = vdev_blkdev_get_by_path(disk_name, mode,
zfs_vdev_holder); zfs_vdev_holder, NULL);
if (!IS_ERR(bdev)) { if (!IS_ERR(bdev)) {
int error = vdev_bdev_reread_part(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) { if (error == 0) {
timeout = MSEC2NSEC( timeout = MSEC2NSEC(
zfs_vdev_open_timeout_ms * 2); 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(); hrtime_t start = gethrtime();
bdev = ERR_PTR(-ENXIO); bdev = ERR_PTR(-ENXIO);
while (IS_ERR(bdev) && ((gethrtime() - start) < timeout)) { while (IS_ERR(bdev) && ((gethrtime() - start) < timeout)) {
bdev = blkdev_get_by_path(v->vdev_path, mode | FMODE_EXCL, bdev = vdev_blkdev_get_by_path(v->vdev_path, mode,
zfs_vdev_holder); zfs_vdev_holder, NULL);
if (unlikely(PTR_ERR(bdev) == -ENOENT)) { if (unlikely(PTR_ERR(bdev) == -ENOENT)) {
/* /*
* There is no point of waiting since device is removed * There is no point of waiting since device is removed
@ -382,8 +431,8 @@ vdev_disk_close(vdev_t *v)
return; return;
if (vd->vd_bdev != NULL) { if (vd->vd_bdev != NULL) {
blkdev_put(vd->vd_bdev, vdev_blkdev_put(vd->vd_bdev, spa_mode(v->vdev_spa),
vdev_bdev_mode(spa_mode(v->vdev_spa)) | FMODE_EXCL); zfs_vdev_holder);
} }
rw_destroy(&vd->vd_lock); rw_destroy(&vd->vd_lock);

View file

@ -537,7 +537,6 @@ zfsctl_inode_alloc(zfsvfs_t *zfsvfs, uint64_t id,
mutex_enter(&zfsvfs->z_znodes_lock); mutex_enter(&zfsvfs->z_znodes_lock);
list_insert_tail(&zfsvfs->z_all_znodes, zp); list_insert_tail(&zfsvfs->z_all_znodes, zp);
zfsvfs->z_nr_znodes++;
membar_producer(); membar_producer();
mutex_exit(&zfsvfs->z_znodes_lock); mutex_exit(&zfsvfs->z_znodes_lock);

View file

@ -1330,12 +1330,11 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
* may add the parents of dir-based xattrs to the taskq * may add the parents of dir-based xattrs to the taskq
* so we want to wait for these. * so we want to wait for these.
* *
* We can safely read z_nr_znodes without locking because the * We can safely check z_all_znodes for being empty because the
* VFS has already blocked operations which add to the * VFS has already blocked operations which add to it.
* z_all_znodes list and thus increment z_nr_znodes.
*/ */
int round = 0; int round = 0;
while (zfsvfs->z_nr_znodes > 0) { while (!list_is_empty(&zfsvfs->z_all_znodes)) {
taskq_wait_outstanding(dsl_pool_zrele_taskq( taskq_wait_outstanding(dsl_pool_zrele_taskq(
dmu_objset_pool(zfsvfs->z_os)), 0); dmu_objset_pool(zfsvfs->z_os)), 0);
if (++round > 1 && !unmounting) if (++round > 1 && !unmounting)

View file

@ -186,7 +186,7 @@ zfs_open(struct inode *ip, int mode, int flag, cred_t *cr)
return (error); return (error);
/* Honor ZFS_APPENDONLY file attribute */ /* 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)) { ((flag & O_APPEND) == 0)) {
zfs_exit(zfsvfs, FTAG); zfs_exit(zfsvfs, FTAG);
return (SET_ERROR(EPERM)); return (SET_ERROR(EPERM));

View file

@ -390,7 +390,6 @@ zfs_inode_destroy(struct inode *ip)
mutex_enter(&zfsvfs->z_znodes_lock); mutex_enter(&zfsvfs->z_znodes_lock);
if (list_link_active(&zp->z_link_node)) { if (list_link_active(&zp->z_link_node)) {
list_remove(&zfsvfs->z_all_znodes, zp); list_remove(&zfsvfs->z_all_znodes, zp);
zfsvfs->z_nr_znodes--;
} }
mutex_exit(&zfsvfs->z_znodes_lock); 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); mutex_enter(&zfsvfs->z_znodes_lock);
list_insert_tail(&zfsvfs->z_all_znodes, zp); list_insert_tail(&zfsvfs->z_all_znodes, zp);
zfsvfs->z_nr_znodes++;
mutex_exit(&zfsvfs->z_znodes_lock); mutex_exit(&zfsvfs->z_znodes_lock);
if (links > 0) if (links > 0)

View file

@ -42,7 +42,7 @@
static int static int
zpl_common_open(struct inode *ip, struct file *filp) 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 (-EACCES);
return (generic_file_open(ip, filp)); return (generic_file_open(ip, filp));

View file

@ -301,15 +301,10 @@ zpl_uio_init(zfs_uio_t *uio, struct kiocb *kiocb, struct iov_iter *to,
#if defined(HAVE_VFS_IOV_ITER) #if defined(HAVE_VFS_IOV_ITER)
zfs_uio_iov_iter_init(uio, to, pos, count, skip); zfs_uio_iov_iter_init(uio, to, pos, count, skip);
#else #else
#ifdef HAVE_IOV_ITER_TYPE zfs_uio_iovec_init(uio, zfs_uio_iter_iov(to), to->nr_segs, pos,
zfs_uio_iovec_init(uio, to->iov, to->nr_segs, pos, zfs_uio_iov_iter_type(to) & ITER_KVEC ?
iov_iter_type(to) & ITER_KVEC ? UIO_SYSSPACE : UIO_USERSPACE, UIO_SYSSPACE : UIO_USERSPACE,
count, skip); 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 #endif
} }
@ -1328,7 +1323,11 @@ const struct file_operations zpl_file_operations = {
.read_iter = zpl_iter_read, .read_iter = zpl_iter_read,
.write_iter = zpl_iter_write, .write_iter = zpl_iter_write,
#ifdef HAVE_VFS_IOV_ITER #ifdef HAVE_VFS_IOV_ITER
#ifdef HAVE_COPY_SPLICE_READ
.splice_read = copy_splice_read,
#else
.splice_read = generic_file_splice_read, .splice_read = generic_file_splice_read,
#endif
.splice_write = iter_file_splice_write, .splice_write = iter_file_splice_write,
#endif #endif
#else #else

View file

@ -671,7 +671,11 @@ zvol_request(struct request_queue *q, struct bio *bio)
} }
static int 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) zvol_open(struct block_device *bdev, fmode_t flag)
#endif
{ {
zvol_state_t *zv; zvol_state_t *zv;
int error = 0; int error = 0;
@ -686,10 +690,14 @@ retry:
/* /*
* Obtain a copy of private_data under the zvol_state_lock to make * Obtain a copy of private_data under the zvol_state_lock to make
* sure that either the result of zvol free code path setting * 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. * 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; zv = bdev->bd_disk->private_data;
#endif
if (zv == NULL) { if (zv == NULL) {
rw_exit(&zvol_state_lock); rw_exit(&zvol_state_lock);
return (SET_ERROR(-ENXIO)); return (SET_ERROR(-ENXIO));
@ -769,14 +777,15 @@ retry:
} }
} }
error = -zvol_first_open(zv, !(flag & FMODE_WRITE)); error = -zvol_first_open(zv, !(blk_mode_is_open_write(flag)));
if (drop_namespace) if (drop_namespace)
mutex_exit(&spa_namespace_lock); mutex_exit(&spa_namespace_lock);
} }
if (error == 0) { 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) if (zv->zv_open_count == 0)
zvol_last_close(zv); zvol_last_close(zv);
@ -791,14 +800,25 @@ retry:
rw_exit(&zv->zv_suspend_lock); rw_exit(&zv->zv_suspend_lock);
if (error == 0) if (error == 0)
#ifdef HAVE_BLK_MODE_T
disk_check_media_change(disk);
#else
zfs_check_media_change(bdev); zfs_check_media_change(bdev);
#endif
return (error); return (error);
} }
static void 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; zvol_state_t *zv;
boolean_t drop_suspend = B_TRUE; boolean_t drop_suspend = B_TRUE;

View file

@ -930,12 +930,21 @@ spa_upgrade_errlog(spa_t *spa, dmu_tx_t *tx)
if (spa->spa_errlog_last != 0) { if (spa->spa_errlog_last != 0) {
sync_upgrade_errlog(spa, spa->spa_errlog_last, &newobj, tx); sync_upgrade_errlog(spa, spa->spa_errlog_last, &newobj, tx);
spa->spa_errlog_last = newobj; 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) { if (spa->spa_errlog_scrub != 0) {
sync_upgrade_errlog(spa, spa->spa_errlog_scrub, &newobj, tx); sync_upgrade_errlog(spa, spa->spa_errlog_scrub, &newobj, tx);
spa->spa_errlog_scrub = newobj; 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); mutex_exit(&spa->spa_errlog_lock);
} }

View file

@ -1550,7 +1550,16 @@ zil_lwb_write_done(zio_t *zio)
lwb->lwb_state = LWB_STATE_WRITE_DONE; lwb->lwb_state = LWB_STATE_WRITE_DONE;
lwb->lwb_child_zio = NULL; lwb->lwb_child_zio = NULL;
lwb->lwb_write_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); nlwb = list_next(&zilog->zl_lwb_list, lwb);
if (nlwb && nlwb->lwb_state != LWB_STATE_ISSUED)
nlwb = NULL;
mutex_exit(&zilog->zl_lock); mutex_exit(&zilog->zl_lock);
if (avl_numnodes(t) == 0) if (avl_numnodes(t) == 0)

View file

@ -204,11 +204,11 @@ function histo_check_test_pool
# 4096 blocksize count for asize. For verification we stick # 4096 blocksize count for asize. For verification we stick
# to just lsize counts. # to just lsize counts.
# #
# The max_variance is hard-coded here at 12% to leave us some # Variances are expected since this test does not account for
# margin. Testing has shown this normally to be in the range # metadata. The hardcoded limit here is empirical and should
# of 2%-8%, but it may be as large as 11%. # not be construed as deterministic.
################### ###################
let max_variance=12 let max_variance=15
let fail_value=0 let fail_value=0
let error_count=0 let error_count=0
log_note "Comparisons for ${pool}" log_note "Comparisons for ${pool}"