aboutsummaryrefslogtreecommitdiffstats
path: root/module/os
diff options
context:
space:
mode:
Diffstat (limited to 'module/os')
-rw-r--r--module/os/freebsd/spl/spl_kstat.c289
-rw-r--r--module/os/freebsd/spl/spl_procfs_list.c86
-rw-r--r--module/os/freebsd/spl/spl_taskq.c4
-rw-r--r--module/os/freebsd/zfs/kmod_core.c4
-rw-r--r--module/os/freebsd/zfs/sysctl_os.c17
-rw-r--r--module/os/freebsd/zfs/zfs_ioctl_compat.c4
-rw-r--r--module/os/freebsd/zfs/zfs_vfsops.c4
-rw-r--r--module/os/freebsd/zfs/zio_crypt.c221
-rw-r--r--module/os/linux/spl/spl-procfs-list.c22
-rw-r--r--module/os/linux/zfs/vdev_disk.c10
-rw-r--r--module/os/linux/zfs/zfs_debug.c1
11 files changed, 389 insertions, 273 deletions
diff --git a/module/os/freebsd/spl/spl_kstat.c b/module/os/freebsd/spl/spl_kstat.c
index df2da2d602b6..4cc77e20a4eb 100644
--- a/module/os/freebsd/spl/spl_kstat.c
+++ b/module/os/freebsd/spl/spl_kstat.c
@@ -55,6 +55,17 @@ __kstat_set_raw_ops(kstat_t *ksp,
ksp->ks_raw_ops.addr = addr;
}
+void
+__kstat_set_seq_raw_ops(kstat_t *ksp,
+ int (*headers)(struct seq_file *f),
+ int (*data)(char *buf, size_t size, void *data),
+ void *(*addr)(kstat_t *ksp, loff_t index))
+{
+ ksp->ks_raw_ops.seq_headers = headers;
+ ksp->ks_raw_ops.data = data;
+ ksp->ks_raw_ops.addr = addr;
+}
+
static int
kstat_default_update(kstat_t *ksp, int rw)
{
@@ -160,7 +171,7 @@ kstat_sysctl_raw(SYSCTL_HANDLER_ARGS)
void *data;
kstat_t *ksp = arg1;
void *(*addr_op)(kstat_t *ksp, loff_t index);
- int n, rc = 0;
+ int n, has_header, rc = 0;
sb = sbuf_new_auto();
if (sb == NULL)
@@ -180,14 +191,25 @@ kstat_sysctl_raw(SYSCTL_HANDLER_ARGS)
ksp->ks_raw_buf = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
n = 0;
+ has_header = (ksp->ks_raw_ops.headers ||
+ ksp->ks_raw_ops.seq_headers);
+
restart_headers:
if (ksp->ks_raw_ops.headers) {
rc = ksp->ks_raw_ops.headers(
ksp->ks_raw_buf, ksp->ks_raw_bufsize);
+ } else if (ksp->ks_raw_ops.seq_headers) {
+ struct seq_file f;
+
+ f.sf_buf = ksp->ks_raw_buf;
+ f.sf_size = ksp->ks_raw_bufsize;
+ rc = ksp->ks_raw_ops.seq_headers(&f);
+ }
+ if (has_header) {
if (rc == ENOMEM && !kstat_resize_raw(ksp))
goto restart_headers;
if (rc == 0)
- sbuf_printf(sb, "%s", ksp->ks_raw_buf);
+ sbuf_printf(sb, "\n%s", ksp->ks_raw_buf);
}
while ((data = addr_op(ksp, n)) != NULL) {
@@ -220,16 +242,21 @@ kstat_t *
__kstat_create(const char *module, int instance, const char *name,
const char *class, uchar_t ks_type, uint_t ks_ndata, uchar_t flags)
{
+ char buf[KSTAT_STRLEN];
struct sysctl_oid *root;
kstat_t *ksp;
+ char *pool;
KASSERT(instance == 0, ("instance=%d", instance));
if ((ks_type == KSTAT_TYPE_INTR) || (ks_type == KSTAT_TYPE_IO))
ASSERT(ks_ndata == 1);
+ if (class == NULL)
+ class = "misc";
+
/*
- * Allocate the main structure. We don't need to copy module/class/name
- * stuff in here, because it is only used for sysctl node creation
+ * Allocate the main structure. We don't need to keep a copy of
+ * module in here, because it is only used for sysctl node creation
* done in this function.
*/
ksp = malloc(sizeof (*ksp), M_KSTAT, M_WAITOK|M_ZERO);
@@ -237,8 +264,8 @@ __kstat_create(const char *module, int instance, const char *name,
ksp->ks_crtime = gethrtime();
ksp->ks_snaptime = ksp->ks_crtime;
ksp->ks_instance = instance;
- strncpy(ksp->ks_name, name, KSTAT_STRLEN);
- strncpy(ksp->ks_class, class, KSTAT_STRLEN);
+ (void) strlcpy(ksp->ks_name, name, KSTAT_STRLEN);
+ (void) strlcpy(ksp->ks_class, class, KSTAT_STRLEN);
ksp->ks_type = ks_type;
ksp->ks_flags = flags;
ksp->ks_update = kstat_default_update;
@@ -247,28 +274,28 @@ __kstat_create(const char *module, int instance, const char *name,
ksp->ks_lock = &ksp->ks_private_lock;
switch (ksp->ks_type) {
- case KSTAT_TYPE_RAW:
- ksp->ks_ndata = 1;
- ksp->ks_data_size = ks_ndata;
- break;
- case KSTAT_TYPE_NAMED:
- ksp->ks_ndata = ks_ndata;
- ksp->ks_data_size = ks_ndata * sizeof (kstat_named_t);
- break;
- case KSTAT_TYPE_INTR:
- ksp->ks_ndata = ks_ndata;
- ksp->ks_data_size = ks_ndata * sizeof (kstat_intr_t);
- break;
- case KSTAT_TYPE_IO:
- ksp->ks_ndata = ks_ndata;
- ksp->ks_data_size = ks_ndata * sizeof (kstat_io_t);
- break;
- case KSTAT_TYPE_TIMER:
- ksp->ks_ndata = ks_ndata;
- ksp->ks_data_size = ks_ndata * sizeof (kstat_timer_t);
- break;
- default:
- panic("Undefined kstat type %d\n", ksp->ks_type);
+ case KSTAT_TYPE_RAW:
+ ksp->ks_ndata = 1;
+ ksp->ks_data_size = ks_ndata;
+ break;
+ case KSTAT_TYPE_NAMED:
+ ksp->ks_ndata = ks_ndata;
+ ksp->ks_data_size = ks_ndata * sizeof (kstat_named_t);
+ break;
+ case KSTAT_TYPE_INTR:
+ ksp->ks_ndata = ks_ndata;
+ ksp->ks_data_size = ks_ndata * sizeof (kstat_intr_t);
+ break;
+ case KSTAT_TYPE_IO:
+ ksp->ks_ndata = ks_ndata;
+ ksp->ks_data_size = ks_ndata * sizeof (kstat_io_t);
+ break;
+ case KSTAT_TYPE_TIMER:
+ ksp->ks_ndata = ks_ndata;
+ ksp->ks_data_size = ks_ndata * sizeof (kstat_timer_t);
+ break;
+ default:
+ panic("Undefined kstat type %d\n", ksp->ks_type);
}
if (ksp->ks_flags & KSTAT_FLAG_VIRTUAL) {
@@ -280,10 +307,22 @@ __kstat_create(const char *module, int instance, const char *name,
ksp = NULL;
}
}
+
+ /*
+ * Some kstats use a module name like "zfs/poolname" to distinguish a
+ * set of kstats belonging to a specific pool. Split on '/' to add an
+ * extra node for the pool name if needed.
+ */
+ (void) strlcpy(buf, module, KSTAT_STRLEN);
+ module = buf;
+ pool = strchr(module, '/');
+ if (pool != NULL)
+ *pool++ = '\0';
+
/*
* Create sysctl tree for those statistics:
*
- * kstat.<module>.<class>.<name>.
+ * kstat.<module>[.<pool>].<class>.<name>
*/
sysctl_ctx_init(&ksp->ks_sysctl_ctx);
root = SYSCTL_ADD_NODE(&ksp->ks_sysctl_ctx,
@@ -295,11 +334,26 @@ __kstat_create(const char *module, int instance, const char *name,
free(ksp, M_KSTAT);
return (NULL);
}
+ if (pool != NULL) {
+ root = SYSCTL_ADD_NODE(&ksp->ks_sysctl_ctx,
+ SYSCTL_CHILDREN(root), OID_AUTO, pool, CTLFLAG_RW, 0, "");
+ if (root == NULL) {
+ printf("%s: Cannot create kstat.%s.%s tree!\n",
+ __func__, module, pool);
+ sysctl_ctx_free(&ksp->ks_sysctl_ctx);
+ free(ksp, M_KSTAT);
+ return (NULL);
+ }
+ }
root = SYSCTL_ADD_NODE(&ksp->ks_sysctl_ctx, SYSCTL_CHILDREN(root),
OID_AUTO, class, CTLFLAG_RW, 0, "");
if (root == NULL) {
- printf("%s: Cannot create kstat.%s.%s tree!\n", __func__,
- module, class);
+ if (pool != NULL)
+ printf("%s: Cannot create kstat.%s.%s.%s tree!\n",
+ __func__, module, pool, class);
+ else
+ printf("%s: Cannot create kstat.%s.%s tree!\n",
+ __func__, module, class);
sysctl_ctx_free(&ksp->ks_sysctl_ctx);
free(ksp, M_KSTAT);
return (NULL);
@@ -309,8 +363,13 @@ __kstat_create(const char *module, int instance, const char *name,
SYSCTL_CHILDREN(root),
OID_AUTO, name, CTLFLAG_RW, 0, "");
if (root == NULL) {
- printf("%s: Cannot create kstat.%s.%s.%s tree!\n",
- __func__, module, class, name);
+ if (pool != NULL)
+ printf("%s: Cannot create kstat.%s.%s.%s.%s "
+ "tree!\n", __func__, module, pool, class,
+ name);
+ else
+ printf("%s: Cannot create kstat.%s.%s.%s "
+ "tree!\n", __func__, module, class, name);
sysctl_ctx_free(&ksp->ks_sysctl_ctx);
free(ksp, M_KSTAT);
return (NULL);
@@ -342,64 +401,62 @@ kstat_install_named(kstat_t *ksp)
namelast = ksent->name;
}
switch (typelast) {
- case KSTAT_DATA_CHAR:
- /* Not Implemented */
- break;
- case KSTAT_DATA_INT32:
- SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
- SYSCTL_CHILDREN(ksp->ks_sysctl_root),
- OID_AUTO, namelast,
- CTLTYPE_S32 | CTLFLAG_RD, ksp, i,
- kstat_sysctl, "I", namelast);
- break;
- case KSTAT_DATA_UINT32:
- SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
- SYSCTL_CHILDREN(ksp->ks_sysctl_root),
- OID_AUTO, namelast,
- CTLTYPE_U32 | CTLFLAG_RD, ksp, i,
- kstat_sysctl, "IU", namelast);
- break;
- case KSTAT_DATA_INT64:
- SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
- SYSCTL_CHILDREN(ksp->ks_sysctl_root),
- OID_AUTO, namelast,
- CTLTYPE_S64 | CTLFLAG_RD, ksp, i,
- kstat_sysctl, "Q", namelast);
- break;
- case KSTAT_DATA_UINT64:
- SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
- SYSCTL_CHILDREN(ksp->ks_sysctl_root),
- OID_AUTO, namelast,
- CTLTYPE_U64 | CTLFLAG_RD, ksp, i,
- kstat_sysctl, "QU", namelast);
- break;
- case KSTAT_DATA_LONG:
- SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
- SYSCTL_CHILDREN(ksp->ks_sysctl_root),
- OID_AUTO, namelast,
- CTLTYPE_LONG | CTLFLAG_RD, ksp, i,
- kstat_sysctl, "L", namelast);
- break;
- case KSTAT_DATA_ULONG:
- SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
- SYSCTL_CHILDREN(ksp->ks_sysctl_root),
- OID_AUTO, namelast,
- CTLTYPE_ULONG | CTLFLAG_RD, ksp, i,
- kstat_sysctl, "LU", namelast);
- break;
- case KSTAT_DATA_STRING:
- SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
- SYSCTL_CHILDREN(ksp->ks_sysctl_root),
- OID_AUTO, namelast,
- CTLTYPE_STRING | CTLFLAG_RD, ksp, i,
- kstat_sysctl_string, "A", namelast);
- break;
- default:
- panic("unsupported type: %d", typelast);
+ case KSTAT_DATA_CHAR:
+ /* Not Implemented */
+ break;
+ case KSTAT_DATA_INT32:
+ SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
+ SYSCTL_CHILDREN(ksp->ks_sysctl_root),
+ OID_AUTO, namelast,
+ CTLTYPE_S32 | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ ksp, i, kstat_sysctl, "I", namelast);
+ break;
+ case KSTAT_DATA_UINT32:
+ SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
+ SYSCTL_CHILDREN(ksp->ks_sysctl_root),
+ OID_AUTO, namelast,
+ CTLTYPE_U32 | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ ksp, i, kstat_sysctl, "IU", namelast);
+ break;
+ case KSTAT_DATA_INT64:
+ SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
+ SYSCTL_CHILDREN(ksp->ks_sysctl_root),
+ OID_AUTO, namelast,
+ CTLTYPE_S64 | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ ksp, i, kstat_sysctl, "Q", namelast);
+ break;
+ case KSTAT_DATA_UINT64:
+ SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
+ SYSCTL_CHILDREN(ksp->ks_sysctl_root),
+ OID_AUTO, namelast,
+ CTLTYPE_U64 | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ ksp, i, kstat_sysctl, "QU", namelast);
+ break;
+ case KSTAT_DATA_LONG:
+ SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
+ SYSCTL_CHILDREN(ksp->ks_sysctl_root),
+ OID_AUTO, namelast,
+ CTLTYPE_LONG | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ ksp, i, kstat_sysctl, "L", namelast);
+ break;
+ case KSTAT_DATA_ULONG:
+ SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
+ SYSCTL_CHILDREN(ksp->ks_sysctl_root),
+ OID_AUTO, namelast,
+ CTLTYPE_ULONG | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ ksp, i, kstat_sysctl, "LU", namelast);
+ break;
+ case KSTAT_DATA_STRING:
+ SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
+ SYSCTL_CHILDREN(ksp->ks_sysctl_root),
+ OID_AUTO, namelast,
+ CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ ksp, i, kstat_sysctl_string, "A", namelast);
+ break;
+ default:
+ panic("unsupported type: %d", typelast);
}
-
}
-
}
void
@@ -411,39 +468,37 @@ kstat_install(kstat_t *ksp)
VERIFY(ksp->ks_type == KSTAT_TYPE_RAW);
switch (ksp->ks_type) {
- case KSTAT_TYPE_NAMED:
- return (kstat_install_named(ksp));
- break;
- case KSTAT_TYPE_RAW:
- if (ksp->ks_raw_ops.data) {
- root = SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
- SYSCTL_CHILDREN(ksp->ks_sysctl_root),
- OID_AUTO, ksp->ks_name,
- CTLTYPE_STRING | CTLFLAG_RD, ksp, 0,
- kstat_sysctl_raw, "A", ksp->ks_name);
- } else {
- root = SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
- SYSCTL_CHILDREN(ksp->ks_sysctl_root),
- OID_AUTO, ksp->ks_name,
- CTLTYPE_OPAQUE | CTLFLAG_RD, ksp, 0,
- kstat_sysctl_raw, "", ksp->ks_name);
- }
- VERIFY(root != NULL);
- break;
- case KSTAT_TYPE_IO:
+ case KSTAT_TYPE_NAMED:
+ return (kstat_install_named(ksp));
+ case KSTAT_TYPE_RAW:
+ if (ksp->ks_raw_ops.data) {
root = SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
SYSCTL_CHILDREN(ksp->ks_sysctl_root),
OID_AUTO, ksp->ks_name,
- CTLTYPE_STRING | CTLFLAG_RD, ksp, 0,
- kstat_sysctl_io, "A", ksp->ks_name);
- break;
- case KSTAT_TYPE_TIMER:
- case KSTAT_TYPE_INTR:
- default:
- panic("unsupported kstat type %d\n", ksp->ks_type);
+ CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ ksp, 0, kstat_sysctl_raw, "A", ksp->ks_name);
+ } else {
+ root = SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
+ SYSCTL_CHILDREN(ksp->ks_sysctl_root),
+ OID_AUTO, ksp->ks_name,
+ CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ ksp, 0, kstat_sysctl_raw, "", ksp->ks_name);
+ }
+ break;
+ case KSTAT_TYPE_IO:
+ root = SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
+ SYSCTL_CHILDREN(ksp->ks_sysctl_root),
+ OID_AUTO, ksp->ks_name,
+ CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE,
+ ksp, 0, kstat_sysctl_io, "A", ksp->ks_name);
+ break;
+ case KSTAT_TYPE_TIMER:
+ case KSTAT_TYPE_INTR:
+ default:
+ panic("unsupported kstat type %d\n", ksp->ks_type);
}
+ VERIFY(root != NULL);
ksp->ks_sysctl_root = root;
-
}
void
diff --git a/module/os/freebsd/spl/spl_procfs_list.c b/module/os/freebsd/spl/spl_procfs_list.c
index 7b4ae9d0e357..e8448ce00686 100644
--- a/module/os/freebsd/spl/spl_procfs_list.c
+++ b/module/os/freebsd/spl/spl_procfs_list.c
@@ -32,12 +32,74 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/procfs_list.h>
+typedef struct procfs_list_iter {
+ procfs_list_t *pli_pl;
+ void *pli_elt;
+} pli_t;
+
void
-seq_printf(struct seq_file *m, const char *fmt, ...)
-{}
+seq_printf(struct seq_file *f, const char *fmt, ...)
+{
+ va_list adx;
+
+ va_start(adx, fmt);
+ (void) vsnprintf(f->sf_buf, f->sf_size, fmt, adx);
+ va_end(adx);
+}
+
+static int
+procfs_list_update(kstat_t *ksp, int rw)
+{
+ procfs_list_t *pl = ksp->ks_private;
+
+ if (rw == KSTAT_WRITE)
+ pl->pl_clear(pl);
+
+ return (0);
+}
+
+static int
+procfs_list_data(char *buf, size_t size, void *data)
+{
+ pli_t *p;
+ void *elt;
+ procfs_list_t *pl;
+ struct seq_file f;
+
+ p = data;
+ pl = p->pli_pl;
+ elt = p->pli_elt;
+ free(p, M_TEMP);
+ f.sf_buf = buf;
+ f.sf_size = size;
+ return (pl->pl_show(&f, elt));
+}
+
+static void *
+procfs_list_addr(kstat_t *ksp, loff_t n)
+{
+ procfs_list_t *pl = ksp->ks_private;
+ void *elt = ksp->ks_private1;
+ pli_t *p = NULL;
+
+
+ if (n == 0)
+ ksp->ks_private1 = list_head(&pl->pl_list);
+ else if (elt)
+ ksp->ks_private1 = list_next(&pl->pl_list, elt);
+
+ if (ksp->ks_private1) {
+ p = malloc(sizeof (*p), M_TEMP, M_WAITOK);
+ p->pli_pl = pl;
+ p->pli_elt = ksp->ks_private1;
+ }
+
+ return (p);
+}
void
procfs_list_install(const char *module,
+ const char *submodule,
const char *name,
mode_t mode,
procfs_list_t *procfs_list,
@@ -46,12 +108,31 @@ procfs_list_install(const char *module,
int (*clear)(procfs_list_t *procfs_list),
size_t procfs_list_node_off)
{
+ kstat_t *procfs_kstat;
+
mutex_init(&procfs_list->pl_lock, NULL, MUTEX_DEFAULT, NULL);
list_create(&procfs_list->pl_list,
procfs_list_node_off + sizeof (procfs_list_node_t),
procfs_list_node_off + offsetof(procfs_list_node_t, pln_link));
+ procfs_list->pl_show = show;
+ procfs_list->pl_show_header = show_header;
+ procfs_list->pl_clear = clear;
procfs_list->pl_next_id = 1;
procfs_list->pl_node_offset = procfs_list_node_off;
+
+ procfs_kstat = kstat_create(module, 0, name, submodule,
+ KSTAT_TYPE_RAW, 0, KSTAT_FLAG_VIRTUAL);
+
+ if (procfs_kstat) {
+ procfs_kstat->ks_lock = &procfs_list->pl_lock;
+ procfs_kstat->ks_ndata = UINT32_MAX;
+ procfs_kstat->ks_private = procfs_list;
+ procfs_kstat->ks_update = procfs_list_update;
+ kstat_set_seq_raw_ops(procfs_kstat, show_header,
+ procfs_list_data, procfs_list_addr);
+ kstat_install(procfs_kstat);
+ procfs_list->pl_private = procfs_kstat;
+ }
}
void
@@ -62,6 +143,7 @@ void
procfs_list_destroy(procfs_list_t *procfs_list)
{
ASSERT(list_is_empty(&procfs_list->pl_list));
+ kstat_delete(procfs_list->pl_private);
list_destroy(&procfs_list->pl_list);
mutex_destroy(&procfs_list->pl_lock);
}
diff --git a/module/os/freebsd/spl/spl_taskq.c b/module/os/freebsd/spl/spl_taskq.c
index 049e889cf304..cc025de959e3 100644
--- a/module/os/freebsd/spl/spl_taskq.c
+++ b/module/os/freebsd/spl/spl_taskq.c
@@ -169,6 +169,10 @@ taskq_tsd_set(void *context)
{
taskq_t *tq = context;
+#if defined(__amd64__) || defined(__i386__) || defined(__aarch64__)
+ if (context != NULL && tsd_get(taskq_tsd) == NULL)
+ fpu_kern_thread(FPU_KERN_NORMAL);
+#endif
tsd_set(taskq_tsd, tq);
}
diff --git a/module/os/freebsd/zfs/kmod_core.c b/module/os/freebsd/zfs/kmod_core.c
index 4c696129857a..3a13271aac6f 100644
--- a/module/os/freebsd/zfs/kmod_core.c
+++ b/module/os/freebsd/zfs/kmod_core.c
@@ -86,6 +86,7 @@ __FBSDID("$FreeBSD$");
#include <sys/zio_checksum.h>
#include <sys/vdev_removal.h>
#include <sys/dsl_crypt.h>
+#include <sys/zfs_context.h>
#include <sys/zfs_ioctl_compat.h>
#include <sys/zfs_ioctl_impl.h>
@@ -98,7 +99,7 @@ __FBSDID("$FreeBSD$");
SYSCTL_DECL(_vfs_zfs);
SYSCTL_DECL(_vfs_zfs_vdev);
-
+extern uint_t rrw_tsd_key;
static int zfs_version_ioctl = ZFS_IOCVER_OZFS;
SYSCTL_DECL(_vfs_zfs_version);
SYSCTL_INT(_vfs_zfs_version, OID_AUTO, ioctl, CTLFLAG_RD, &zfs_version_ioctl,
@@ -180,6 +181,7 @@ out:
if (zcl)
kmem_free(zcl, sizeof (zfs_cmd_legacy_t));
kmem_free(zc, sizeof (zfs_cmd_t));
+ MPASS(tsd_get(rrw_tsd_key) == NULL);
return (error);
}
diff --git a/module/os/freebsd/zfs/sysctl_os.c b/module/os/freebsd/zfs/sysctl_os.c
index b3cb7e7e4374..c9b350a540ea 100644
--- a/module/os/freebsd/zfs/sysctl_os.c
+++ b/module/os/freebsd/zfs/sysctl_os.c
@@ -243,8 +243,9 @@ sysctl_vfs_zfs_arc_no_grow_shift(SYSCTL_HANDLER_ARGS)
return (0);
}
-SYSCTL_PROC(_vfs_zfs, OID_AUTO, arc_no_grow_shift, CTLTYPE_U32 | CTLFLAG_RWTUN,
- 0, sizeof (uint32_t), sysctl_vfs_zfs_arc_no_grow_shift, "U",
+SYSCTL_PROC(_vfs_zfs, OID_AUTO, arc_no_grow_shift,
+ CTLTYPE_U32 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE, 0, sizeof (uint32_t),
+ sysctl_vfs_zfs_arc_no_grow_shift, "U",
"log2(fraction of ARC which must be free to allow growing)");
int
@@ -275,10 +276,12 @@ param_set_arc_int(SYSCTL_HANDLER_ARGS)
return (0);
}
-SYSCTL_PROC(_vfs_zfs, OID_AUTO, arc_min, CTLTYPE_ULONG | CTLFLAG_RWTUN,
+SYSCTL_PROC(_vfs_zfs, OID_AUTO, arc_min,
+ CTLTYPE_ULONG | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
&zfs_arc_min, sizeof (zfs_arc_min), param_set_arc_long, "LU",
"min arc size (LEGACY)");
-SYSCTL_PROC(_vfs_zfs, OID_AUTO, arc_max, CTLTYPE_ULONG | CTLFLAG_RWTUN,
+SYSCTL_PROC(_vfs_zfs, OID_AUTO, arc_max,
+ CTLTYPE_ULONG | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
&zfs_arc_max, sizeof (zfs_arc_max), param_set_arc_long, "LU",
"max arc size (LEGACY)");
@@ -558,11 +561,13 @@ param_set_max_auto_ashift(SYSCTL_HANDLER_ARGS)
return (0);
}
-SYSCTL_PROC(_vfs_zfs, OID_AUTO, min_auto_ashift, CTLTYPE_U64 | CTLFLAG_RWTUN,
+SYSCTL_PROC(_vfs_zfs, OID_AUTO, min_auto_ashift,
+ CTLTYPE_U64 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
&zfs_vdev_min_auto_ashift, sizeof (zfs_vdev_min_auto_ashift),
param_set_min_auto_ashift, "QU",
"Min ashift used when creating new top-level vdev. (LEGACY)");
-SYSCTL_PROC(_vfs_zfs, OID_AUTO, max_auto_ashift, CTLTYPE_U64 | CTLFLAG_RWTUN,
+SYSCTL_PROC(_vfs_zfs, OID_AUTO, max_auto_ashift,
+ CTLTYPE_U64 | CTLFLAG_RWTUN | CTLFLAG_MPSAFE,
&zfs_vdev_max_auto_ashift, sizeof (zfs_vdev_max_auto_ashift),
param_set_max_auto_ashift, "QU",
"Max ashift used when optimizing for logical -> physical sector size on "
diff --git a/module/os/freebsd/zfs/zfs_ioctl_compat.c b/module/os/freebsd/zfs/zfs_ioctl_compat.c
index 8dec8644c06e..81967bed73f9 100644
--- a/module/os/freebsd/zfs/zfs_ioctl_compat.c
+++ b/module/os/freebsd/zfs/zfs_ioctl_compat.c
@@ -322,8 +322,10 @@ zfs_ioctl_ozfs_to_legacy(int request)
if (request > ZFS_IOC_LAST)
return (-1);
- if (request > ZFS_IOC_PLATFORM)
+ if (request > ZFS_IOC_PLATFORM) {
+ request -= ZFS_IOC_PLATFORM + 1;
return (zfs_ioctl_ozfs_to_legacy_platform_[request]);
+ }
if (request >= sizeof (zfs_ioctl_ozfs_to_legacy_common_)/sizeof (long))
return (-1);
return (zfs_ioctl_ozfs_to_legacy_common_[request]);
diff --git a/module/os/freebsd/zfs/zfs_vfsops.c b/module/os/freebsd/zfs/zfs_vfsops.c
index 77812ca8d400..ec8303283414 100644
--- a/module/os/freebsd/zfs/zfs_vfsops.c
+++ b/module/os/freebsd/zfs/zfs_vfsops.c
@@ -1532,8 +1532,12 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
* 'z_parent' is self referential for non-snapshots.
*/
#ifdef FREEBSD_NAMECACHE
+#if __FreeBSD_version >= 1300117
+ cache_purgevfs(zfsvfs->z_parent->z_vfs);
+#else
cache_purgevfs(zfsvfs->z_parent->z_vfs, true);
#endif
+#endif
}
/*
diff --git a/module/os/freebsd/zfs/zio_crypt.c b/module/os/freebsd/zfs/zio_crypt.c
index d89ef80edd66..fb88bc325d3c 100644
--- a/module/os/freebsd/zfs/zio_crypt.c
+++ b/module/os/freebsd/zfs/zio_crypt.c
@@ -1234,8 +1234,7 @@ zio_crypt_do_indirect_mac_checksum_abd(boolean_t generate, abd_t *abd,
* accommodate some of the drivers, the authbuf needs to be logically before
* the data. This means that we need to copy the source to the destination,
* and set up an extra iovec_t at the beginning to handle the authbuf.
- * It also means we'll only return one uio_t, which we do via the clumsy
- * ifdef in the function declaration.
+ * It also means we'll only return one uio_t.
*/
/* ARGSUSED */
@@ -1245,52 +1244,46 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
uio_t *out_uio, uint_t *enc_len, uint8_t **authbuf, uint_t *auth_len,
boolean_t *no_crypt)
{
- int ret;
- uint64_t txtype, lr_len;
- uint_t nr_src, nr_dst, crypt_len;
- uint_t aad_len = 0, nr_iovecs = 0, total_len = 0;
- iovec_t *src_iovecs = NULL, *dst_iovecs = NULL;
+ uint8_t *aadbuf = zio_buf_alloc(datalen);
uint8_t *src, *dst, *slrp, *dlrp, *blkend, *aadp;
+ iovec_t *dst_iovecs;
zil_chain_t *zilc;
lr_t *lr;
- uint8_t *aadbuf = zio_buf_alloc(datalen);
+ uint64_t txtype, lr_len;
+ uint_t crypt_len, nr_iovecs, vec;
+ uint_t aad_len = 0, total_len = 0;
- /* cipherbuf always needs an extra iovec for the MAC */
if (encrypt) {
src = plainbuf;
dst = cipherbuf;
- nr_src = 0;
- nr_dst = 1;
} else {
src = cipherbuf;
dst = plainbuf;
- nr_src = 1;
- nr_dst = 0;
}
-
- /*
- * We need at least two iovecs -- one for the AAD,
- * one for the MAC.
- */
bcopy(src, dst, datalen);
- nr_dst = 2;
- /* find the start and end record of the log block */
+ /* Find the start and end record of the log block. */
zilc = (zil_chain_t *)src;
slrp = src + sizeof (zil_chain_t);
aadp = aadbuf;
blkend = src + ((byteswap) ? BSWAP_64(zilc->zc_nused) : zilc->zc_nused);
- /* calculate the number of encrypted iovecs we will need */
+ /*
+ * Calculate the number of encrypted iovecs we will need.
+ */
+
+ /* We need at least two iovecs -- one for the AAD, one for the MAC. */
+ nr_iovecs = 2;
+
for (; slrp < blkend; slrp += lr_len) {
lr = (lr_t *)slrp;
- if (!byteswap) {
- txtype = lr->lrc_txtype;
- lr_len = lr->lrc_reclen;
- } else {
+ if (byteswap) {
txtype = BSWAP_64(lr->lrc_txtype);
lr_len = BSWAP_64(lr->lrc_reclen);
+ } else {
+ txtype = lr->lrc_txtype;
+ lr_len = lr->lrc_reclen;
}
nr_iovecs++;
@@ -1298,27 +1291,7 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
nr_iovecs++;
}
- nr_src = 0;
- nr_dst += nr_iovecs;
-
- /* allocate the iovec arrays */
- if (nr_src != 0) {
- src_iovecs = kmem_alloc(nr_src * sizeof (iovec_t), KM_SLEEP);
- if (src_iovecs == NULL) {
- ret = SET_ERROR(ENOMEM);
- goto error;
- }
- bzero(src_iovecs, nr_src * sizeof (iovec_t));
- }
-
- if (nr_dst != 0) {
- dst_iovecs = kmem_alloc(nr_dst * sizeof (iovec_t), KM_SLEEP);
- if (dst_iovecs == NULL) {
- ret = SET_ERROR(ENOMEM);
- goto error;
- }
- bzero(dst_iovecs, nr_dst * sizeof (iovec_t));
- }
+ dst_iovecs = kmem_alloc(nr_iovecs * sizeof (iovec_t), KM_SLEEP);
/*
* Copy the plain zil header over and authenticate everything except
@@ -1326,18 +1299,20 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
* the embedded checksum will not have been calculated yet, so we don't
* authenticate that.
*/
- bcopy(src, dst, sizeof (zil_chain_t));
bcopy(src, aadp, sizeof (zil_chain_t) - sizeof (zio_eck_t));
aadp += sizeof (zil_chain_t) - sizeof (zio_eck_t);
aad_len += sizeof (zil_chain_t) - sizeof (zio_eck_t);
- /* loop over records again, filling in iovecs */
- /* The first one will contain the authbuf */
- nr_iovecs = 1;
-
slrp = src + sizeof (zil_chain_t);
dlrp = dst + sizeof (zil_chain_t);
+ /*
+ * Loop over records again, filling in iovecs.
+ */
+
+ /* The first iovec will contain the authbuf. */
+ vec = 1;
+
for (; slrp < blkend; slrp += lr_len, dlrp += lr_len) {
lr = (lr_t *)slrp;
@@ -1355,8 +1330,6 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
aadp += sizeof (lr_t);
aad_len += sizeof (lr_t);
- ASSERT3P(dst_iovecs, !=, NULL);
-
/*
* If this is a TX_WRITE record we want to encrypt everything
* except the bp if exists. If the bp does exist we want to
@@ -1365,9 +1338,9 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
if (txtype == TX_WRITE) {
crypt_len = sizeof (lr_write_t) -
sizeof (lr_t) - sizeof (blkptr_t);
- dst_iovecs[nr_iovecs].iov_base = (char *)dlrp +
+ dst_iovecs[vec].iov_base = (char *)dlrp +
sizeof (lr_t);
- dst_iovecs[nr_iovecs].iov_len = crypt_len;
+ dst_iovecs[vec].iov_len = crypt_len;
/* copy the bp now since it will not be encrypted */
bcopy(slrp + sizeof (lr_write_t) - sizeof (blkptr_t),
@@ -1377,56 +1350,45 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf,
aadp, sizeof (blkptr_t));
aadp += sizeof (blkptr_t);
aad_len += sizeof (blkptr_t);
- nr_iovecs++;
+ vec++;
total_len += crypt_len;
if (lr_len != sizeof (lr_write_t)) {
crypt_len = lr_len - sizeof (lr_write_t);
- dst_iovecs[nr_iovecs].iov_base = (char *)
+ dst_iovecs[vec].iov_base = (char *)
dlrp + sizeof (lr_write_t);
- dst_iovecs[nr_iovecs].iov_len = crypt_len;
- nr_iovecs++;
+ dst_iovecs[vec].iov_len = crypt_len;
+ vec++;
total_len += crypt_len;
}
} else {
crypt_len = lr_len - sizeof (lr_t);
- dst_iovecs[nr_iovecs].iov_base = (char *)dlrp +
+ dst_iovecs[vec].iov_base = (char *)dlrp +
sizeof (lr_t);
- dst_iovecs[nr_iovecs].iov_len = crypt_len;
- nr_iovecs++;
+ dst_iovecs[vec].iov_len = crypt_len;
+ vec++;
total_len += crypt_len;
}
}
- *no_crypt = (nr_iovecs == 0);
- *enc_len = total_len;
- *authbuf = aadbuf;
- *auth_len = aad_len;
+ /* The last iovec will contain the MAC. */
+ ASSERT3U(vec, ==, nr_iovecs - 1);
+
+ /* AAD */
dst_iovecs[0].iov_base = aadbuf;
dst_iovecs[0].iov_len = aad_len;
+ /* MAC */
+ dst_iovecs[vec].iov_base = 0;
+ dst_iovecs[vec].iov_len = 0;
+ *no_crypt = (vec == 1);
+ *enc_len = total_len;
+ *authbuf = aadbuf;
+ *auth_len = aad_len;
out_uio->uio_iov = dst_iovecs;
- out_uio->uio_iovcnt = nr_dst;
+ out_uio->uio_iovcnt = nr_iovecs;
return (0);
-
-error:
- zio_buf_free(aadbuf, datalen);
- if (src_iovecs != NULL)
- kmem_free(src_iovecs, nr_src * sizeof (iovec_t));
- if (dst_iovecs != NULL)
- kmem_free(dst_iovecs, nr_dst * sizeof (iovec_t));
-
- *enc_len = 0;
- *authbuf = NULL;
- *auth_len = 0;
- *no_crypt = B_FALSE;
- puio->uio_iov = NULL;
- puio->uio_iovcnt = 0;
- out_uio->uio_iov = NULL;
- out_uio->uio_iovcnt = 0;
-
- return (ret);
}
/*
@@ -1438,29 +1400,22 @@ zio_crypt_init_uios_dnode(boolean_t encrypt, uint64_t version,
uio_t *puio, uio_t *out_uio, uint_t *enc_len, uint8_t **authbuf,
uint_t *auth_len, boolean_t *no_crypt)
{
- int ret;
- uint_t nr_src, nr_dst, crypt_len;
- uint_t aad_len = 0, nr_iovecs = 0, total_len = 0;
- uint_t i, j, max_dnp = datalen >> DNODE_SHIFT;
- iovec_t *src_iovecs = NULL, *dst_iovecs = NULL;
+ uint8_t *aadbuf = zio_buf_alloc(datalen);
uint8_t *src, *dst, *aadp;
dnode_phys_t *dnp, *adnp, *sdnp, *ddnp;
- uint8_t *aadbuf = zio_buf_alloc(datalen);
+ iovec_t *dst_iovecs;
+ uint_t nr_iovecs, crypt_len, vec;
+ uint_t aad_len = 0, total_len = 0;
+ uint_t i, j, max_dnp = datalen >> DNODE_SHIFT;
if (encrypt) {
src = plainbuf;
dst = cipherbuf;
- nr_src = 0;
- nr_dst = 1;
} else {
src = cipherbuf;
dst = plainbuf;
- nr_src = 1;
- nr_dst = 0;
}
-
bcopy(src, dst, datalen);
- nr_dst = 2;
sdnp = (dnode_phys_t *)src;
ddnp = (dnode_phys_t *)dst;
@@ -1470,6 +1425,10 @@ zio_crypt_init_uios_dnode(boolean_t encrypt, uint64_t version,
* Count the number of iovecs we will need to do the encryption by
* counting the number of bonus buffers that need to be encrypted.
*/
+
+ /* We need at least two iovecs -- one for the AAD, one for the MAC. */
+ nr_iovecs = 2;
+
for (i = 0; i < max_dnp; i += sdnp[i].dn_extra_slots + 1) {
/*
* This block may still be byteswapped. However, all of the
@@ -1484,34 +1443,17 @@ zio_crypt_init_uios_dnode(boolean_t encrypt, uint64_t version,
}
}
- nr_src = 0;
- nr_dst += nr_iovecs;
-
- if (nr_src != 0) {
- src_iovecs = kmem_alloc(nr_src * sizeof (iovec_t), KM_SLEEP);
- if (src_iovecs == NULL) {
- ret = SET_ERROR(ENOMEM);
- goto error;
- }
- bzero(src_iovecs, nr_src * sizeof (iovec_t));
- }
-
- if (nr_dst != 0) {
- dst_iovecs = kmem_alloc(nr_dst * sizeof (iovec_t), KM_SLEEP);
- if (dst_iovecs == NULL) {
- ret = SET_ERROR(ENOMEM);
- goto error;
- }
- bzero(dst_iovecs, nr_dst * sizeof (iovec_t));
- }
-
- nr_iovecs = 1;
+ dst_iovecs = kmem_alloc(nr_iovecs * sizeof (iovec_t), KM_SLEEP);
/*
* Iterate through the dnodes again, this time filling in the uios
* we allocated earlier. We also concatenate any data we want to
* authenticate onto aadbuf.
*/
+
+ /* The first iovec will contain the authbuf. */
+ vec = 1;
+
for (i = 0; i < max_dnp; i += sdnp[i].dn_extra_slots + 1) {
dnp = &sdnp[i];
@@ -1565,12 +1507,10 @@ zio_crypt_init_uios_dnode(boolean_t encrypt, uint64_t version,
if (dnp->dn_type != DMU_OT_NONE &&
DMU_OT_IS_ENCRYPTED(dnp->dn_bonustype) &&
dnp->dn_bonuslen != 0) {
- ASSERT3U(nr_iovecs, <, nr_dst);
- ASSERT3P(dst_iovecs, !=, NULL);
- dst_iovecs[nr_iovecs].iov_base = DN_BONUS(&ddnp[i]);
- dst_iovecs[nr_iovecs].iov_len = crypt_len;
+ dst_iovecs[vec].iov_base = DN_BONUS(&ddnp[i]);
+ dst_iovecs[vec].iov_len = crypt_len;
- nr_iovecs++;
+ vec++;
total_len += crypt_len;
} else {
bcopy(DN_BONUS(dnp), DN_BONUS(&ddnp[i]), crypt_len);
@@ -1580,33 +1520,24 @@ zio_crypt_init_uios_dnode(boolean_t encrypt, uint64_t version,
}
}
- *no_crypt = (nr_iovecs == 0);
- *enc_len = total_len;
- *authbuf = aadbuf;
- *auth_len = aad_len;
+ /* The last iovec will contain the MAC. */
+ ASSERT3U(vec, ==, nr_iovecs - 1);
+ /* AAD */
dst_iovecs[0].iov_base = aadbuf;
dst_iovecs[0].iov_len = aad_len;
+ /* MAC */
+ dst_iovecs[vec].iov_base = 0;
+ dst_iovecs[vec].iov_len = 0;
+
+ *no_crypt = (vec == 1);
+ *enc_len = total_len;
+ *authbuf = aadbuf;
+ *auth_len = aad_len;
out_uio->uio_iov = dst_iovecs;
- out_uio->uio_iovcnt = nr_dst;
+ out_uio->uio_iovcnt = nr_iovecs;
return (0);
-
-error:
- zio_buf_free(aadbuf, datalen);
- if (src_iovecs != NULL)
- kmem_free(src_iovecs, nr_src * sizeof (iovec_t));
- if (dst_iovecs != NULL)
- kmem_free(dst_iovecs, nr_dst * sizeof (iovec_t));
-
- *enc_len = 0;
- *authbuf = NULL;
- *auth_len = 0;
- *no_crypt = B_FALSE;
- out_uio->uio_iov = NULL;
- out_uio->uio_iovcnt = 0;
-
- return (ret);
}
/* ARGSUSED */
diff --git a/module/os/linux/spl/spl-procfs-list.c b/module/os/linux/spl/spl-procfs-list.c
index 189d6a7c6082..cae13228c62c 100644
--- a/module/os/linux/spl/spl-procfs-list.c
+++ b/module/os/linux/spl/spl-procfs-list.c
@@ -89,7 +89,17 @@ procfs_list_next_node(procfs_list_cursor_t *cursor, loff_t *pos)
cursor->cached_node = next_node;
cursor->cached_pos = NODE_ID(procfs_list, cursor->cached_node);
*pos = cursor->cached_pos;
+ } else {
+ /*
+ * seq_read() expects ->next() to update the position even
+ * when there are no more entries. Advance the position to
+ * prevent a warning from being logged.
+ */
+ cursor->cached_node = NULL;
+ cursor->cached_pos++;
+ *pos = cursor->cached_pos;
}
+
return (next_node);
}
@@ -105,6 +115,8 @@ procfs_list_seq_start(struct seq_file *f, loff_t *pos)
cursor->cached_node = SEQ_START_TOKEN;
cursor->cached_pos = 0;
return (SEQ_START_TOKEN);
+ } else if (cursor->cached_node == NULL) {
+ return (NULL);
}
/*
@@ -207,6 +219,7 @@ static const kstat_proc_op_t procfs_list_operations = {
*/
void
procfs_list_install(const char *module,
+ const char *submodule,
const char *name,
mode_t mode,
procfs_list_t *procfs_list,
@@ -215,6 +228,12 @@ procfs_list_install(const char *module,
int (*clear)(procfs_list_t *procfs_list),
size_t procfs_list_node_off)
{
+ char *modulestr;
+
+ if (submodule != NULL)
+ modulestr = kmem_asprintf("%s/%s", module, submodule);
+ else
+ modulestr = kmem_asprintf("%s", module);
mutex_init(&procfs_list->pl_lock, NULL, MUTEX_DEFAULT, NULL);
list_create(&procfs_list->pl_list,
procfs_list_node_off + sizeof (procfs_list_node_t),
@@ -225,9 +244,10 @@ procfs_list_install(const char *module,
procfs_list->pl_clear = clear;
procfs_list->pl_node_offset = procfs_list_node_off;
- kstat_proc_entry_init(&procfs_list->pl_kstat_entry, module, name);
+ kstat_proc_entry_init(&procfs_list->pl_kstat_entry, modulestr, name);
kstat_proc_entry_install(&procfs_list->pl_kstat_entry, mode,
&procfs_list_operations, procfs_list);
+ kmem_strfree(modulestr);
}
EXPORT_SYMBOL(procfs_list_install);
diff --git a/module/os/linux/zfs/vdev_disk.c b/module/os/linux/zfs/vdev_disk.c
index 85daef43be40..a54961c76870 100644
--- a/module/os/linux/zfs/vdev_disk.c
+++ b/module/os/linux/zfs/vdev_disk.c
@@ -436,6 +436,16 @@ vdev_submit_bio_impl(struct bio *bio)
#endif
}
+/*
+ * preempt_schedule_notrace is GPL-only which breaks the ZFS build, so
+ * replace it with preempt_schedule under the following condition:
+ */
+#if defined(CONFIG_ARM64) && \
+ defined(CONFIG_PREEMPTION) && \
+ defined(CONFIG_BLK_CGROUP)
+#define preempt_schedule_notrace(x) preempt_schedule(x)
+#endif
+
#ifdef HAVE_BIO_SET_DEV
#if defined(CONFIG_BLK_CGROUP) && defined(HAVE_BIO_SET_DEV_GPL_ONLY)
/*
diff --git a/module/os/linux/zfs/zfs_debug.c b/module/os/linux/zfs/zfs_debug.c
index d98463f1b7f7..8d7f04097da8 100644
--- a/module/os/linux/zfs/zfs_debug.c
+++ b/module/os/linux/zfs/zfs_debug.c
@@ -94,6 +94,7 @@ void
zfs_dbgmsg_init(void)
{
procfs_list_install("zfs",
+ NULL,
"dbgmsg",
0600,
&zfs_dbgmsgs,