svn commit: r365917 - in releng/12.2: cddl/contrib/opensolaris/cmd/zfs cddl/contrib/opensolaris/cmd/zpool sys/cddl/compat/opensolaris/kern sys/cddl/compat/opensolaris/sys sys/cddl/contrib/opensolar...

Allan Jude allanjude at FreeBSD.org
Sat Sep 19 20:47:00 UTC 2020


Author: allanjude
Date: Sat Sep 19 20:46:56 2020
New Revision: 365917
URL: https://svnweb.freebsd.org/changeset/base/365917

Log:
  MFS r365689,r365808,r365860
  
  MFOpenZFS: Introduce read/write kstats per dataset
  
  The following patch introduces a few statistics on reads and writes
  grouped by dataset. These statistics are implemented as kstats
  (backed by aggregate sums for performance) and can be retrieved by
  using the dataset objset ID number. The motivation for this change is
  to provide some preliminary analytics on dataset usage/performance.
  
  Reviewed-by: Richard Elling <Richard.Elling at RichardElling.com>
  Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
  Reviewed by: Matthew Ahrens <mahrens at delphix.com>
  Signed-off-by: Serapheim Dimitropoulos <serapheim at delphix.com>
  
  openzfs/zfs at a448a2557ec4938ed6944c7766fe0b8e6e5f6456
  
  Also contains parts of:
  MFOpenZFS: Connect dataset_kstats for FreeBSD
  
  Example output:
  kstat.zfs.mypool.dataset.objset-0x10b.nread: 150528
  kstat.zfs.mypool.dataset.objset-0x10b.reads: 48
  kstat.zfs.mypool.dataset.objset-0x10b.nwritten: 134217728
  kstat.zfs.mypool.dataset.objset-0x10b.writes: 1024
  kstat.zfs.mypool.dataset.objset-0x10b.dataset_name: mypool/datasetname
  
  Reviewed-by: Ryan Moeller <ryan at iXsystems.com>
  Reviewed by: Sean Eric Fagan <sef at ixsystems.com>
  Reviewed-by: Serapheim Dimitropoulos <serapheim at delphix.com>
  Reviewed-by: Brian Behlendorf <behlendorf1 at llnl.gov>
  Signed-off-by: Allan Jude <allan at klarasystems.com>
  
  openzfs/zfs at 4547fc4e071ceb1818b3a46c3035b923e06e5390
  
  Approved by:	re (gjb)
  Relnotes:	yes
  Sponsored by:	Klara Inc.

Added:
  releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dataset_kstats.c
     - copied unchanged from r365689, stable/12/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dataset_kstats.c
  releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dataset_kstats.h
     - copied unchanged from r365689, stable/12/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dataset_kstats.h
Modified:
  releng/12.2/cddl/contrib/opensolaris/cmd/zfs/zfs.8
  releng/12.2/cddl/contrib/opensolaris/cmd/zpool/zpool.8
  releng/12.2/sys/cddl/compat/opensolaris/kern/opensolaris_kstat.c
  releng/12.2/sys/cddl/compat/opensolaris/sys/kstat.h
  releng/12.2/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c
  releng/12.2/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c
  releng/12.2/sys/cddl/contrib/opensolaris/uts/common/Makefile.files
  releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
  releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h
  releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
  releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
  releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
  releng/12.2/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
  releng/12.2/sys/conf/files
  releng/12.2/tests/sys/cddl/zfs/tests/cli_root/zpool_get/zpool_get.cfg
Directory Properties:
  releng/12.2/   (props changed)

Modified: releng/12.2/cddl/contrib/opensolaris/cmd/zfs/zfs.8
==============================================================================
--- releng/12.2/cddl/contrib/opensolaris/cmd/zfs/zfs.8	Sat Sep 19 20:18:14 2020	(r365916)
+++ releng/12.2/cddl/contrib/opensolaris/cmd/zfs/zfs.8	Sat Sep 19 20:46:56 2020	(r365917)
@@ -32,7 +32,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd October 16, 2019
+.Dd September 12, 2020
 .Dt ZFS 8
 .Os
 .Sh NAME
@@ -635,6 +635,16 @@ property can be either
 .Cm yes
 or
 .Cm no .
+.It Sy objsetid
+A unique identifier for this dataset within the pool. Unlike the dataset's
+.Sy guid
+, the
+.Sy objsetid
+of a dataset is not transferred to other pools when the snapshot is copied
+with a send/receive operation.
+The
+.Sy objsetid
+can be reused (for a new datatset) after the dataset is deleted.
 .It Sy origin
 For cloned file systems or volumes, the snapshot from which the clone was
 created. See also the

Modified: releng/12.2/cddl/contrib/opensolaris/cmd/zpool/zpool.8
==============================================================================
--- releng/12.2/cddl/contrib/opensolaris/cmd/zpool/zpool.8	Sat Sep 19 20:18:14 2020	(r365916)
+++ releng/12.2/cddl/contrib/opensolaris/cmd/zpool/zpool.8	Sat Sep 19 20:46:56 2020	(r365917)
@@ -687,6 +687,15 @@ will decrease while
 increases.
 .It Sy guid
 A unique identifier for the pool.
+.It Sy load_guid
+A unique identifier for the pool.
+Unlike the
+.Sy guid
+property, this identifier is generated every time we load the pool (e.g. does
+not persist across imports/exports) and never changes while the pool is loaded
+(even if a
+.Sy reguid
+operation takes place).
 .It Sy health
 The current health of the pool. Health can be
 .Qq Sy ONLINE ,

Modified: releng/12.2/sys/cddl/compat/opensolaris/kern/opensolaris_kstat.c
==============================================================================
--- releng/12.2/sys/cddl/compat/opensolaris/kern/opensolaris_kstat.c	Sat Sep 19 20:18:14 2020	(r365916)
+++ releng/12.2/sys/cddl/compat/opensolaris/kern/opensolaris_kstat.c	Sat Sep 19 20:46:56 2020	(r365917)
@@ -38,12 +38,24 @@ static MALLOC_DEFINE(M_KSTAT, "kstat_data", "Kernel st
 
 SYSCTL_ROOT_NODE(OID_AUTO, kstat, CTLFLAG_RW, 0, "Kernel statistics");
 
+static int
+kstat_default_update(kstat_t *ksp, int rw)
+{
+	KASSERT(ksp != NULL, ("kstat=%p", ksp));
+
+	if (rw == KSTAT_WRITE)
+		return (EACCES);
+
+	return (0);
+}
+
 kstat_t *
 kstat_create(char *module, int instance, char *name, char *class, uchar_t type,
     ulong_t ndata, uchar_t flags)
 {
 	struct sysctl_oid *root;
 	kstat_t *ksp;
+	char *pool;
 
 	KASSERT(instance == 0, ("instance=%d", instance));
 	KASSERT(type == KSTAT_TYPE_NAMED, ("type=%hhu", type));
@@ -56,11 +68,21 @@ kstat_create(char *module, int instance, char *name, c
 	 */
 	ksp = malloc(sizeof(*ksp), M_KSTAT, M_WAITOK);
 	ksp->ks_ndata = ndata;
+	ksp->ks_update = kstat_default_update;
 
 	/*
+	 * 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.
+	 */
+	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,
@@ -72,11 +94,26 @@ kstat_create(char *module, int instance, char *name, c
 		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);
@@ -84,8 +121,13 @@ kstat_create(char *module, int instance, char *name, c
 	root = SYSCTL_ADD_NODE(&ksp->ks_sysctl_ctx, 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);
@@ -98,13 +140,38 @@ kstat_create(char *module, int instance, char *name, c
 static int
 kstat_sysctl(SYSCTL_HANDLER_ARGS)
 {
-	kstat_named_t *ksent = arg1;
+	kstat_t *ksp = arg1;
+	kstat_named_t *ksent = ksp->ks_data;
 	uint64_t val;
 
+	/* Select the correct element */
+	ksent += arg2;
+	/* Update the aggsums before reading */
+	(void) ksp->ks_update(ksp, KSTAT_READ);
 	val = ksent->value.ui64;
+
 	return sysctl_handle_64(oidp, &val, 0, req);
 }
 
+static int
+kstat_sysctl_string(SYSCTL_HANDLER_ARGS)
+{
+	kstat_t *ksp = arg1;
+	kstat_named_t *ksent = ksp->ks_data;
+	char *val;
+	uint32_t len = 0;
+
+	/* Select the correct element */
+	ksent += arg2;
+	/* Update the aggsums before reading */
+	(void) ksp->ks_update(ksp, KSTAT_READ);
+	val = KSTAT_NAMED_STR_PTR(ksent);
+	len = KSTAT_NAMED_STR_BUFLEN(ksent);
+	val[len-1] = '\0';
+
+	return (sysctl_handle_string(oidp, val, len, req));
+}
+
 void
 kstat_install(kstat_t *ksp)
 {
@@ -113,11 +180,19 @@ kstat_install(kstat_t *ksp)
 
 	ksent = ksp->ks_data;
 	for (i = 0; i < ksp->ks_ndata; i++, ksent++) {
+		if (ksent->data_type == KSTAT_DATA_STRING) {
+			SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
+			    SYSCTL_CHILDREN(ksp->ks_sysctl_root),
+			    OID_AUTO, ksent->name,
+			    CTLTYPE_STRING | CTLFLAG_RD, ksp, i,
+			    kstat_sysctl_string, "A", ksent->desc);
+			continue;
+		}
 		KASSERT(ksent->data_type == KSTAT_DATA_UINT64,
 		    ("data_type=%d", ksent->data_type));
 		SYSCTL_ADD_PROC(&ksp->ks_sysctl_ctx,
 		    SYSCTL_CHILDREN(ksp->ks_sysctl_root), OID_AUTO, ksent->name,
-		    CTLTYPE_U64 | CTLFLAG_RD, ksent, sizeof(*ksent),
+		    CTLTYPE_U64 | CTLFLAG_RD, ksp, i,
 		    kstat_sysctl, "QU", ksent->desc);
 	}
 }

Modified: releng/12.2/sys/cddl/compat/opensolaris/sys/kstat.h
==============================================================================
--- releng/12.2/sys/cddl/compat/opensolaris/sys/kstat.h	Sat Sep 19 20:18:14 2020	(r365916)
+++ releng/12.2/sys/cddl/compat/opensolaris/sys/kstat.h	Sat Sep 19 20:46:56 2020	(r365917)
@@ -68,13 +68,24 @@ typedef struct kstat_named {
 #define	KSTAT_DATA_UINT32	2
 #define	KSTAT_DATA_INT64	3
 #define	KSTAT_DATA_UINT64	4
+#define	KSTAT_DATA_STRING	7
 	uchar_t	data_type;
 #define	KSTAT_DESCLEN		128
 	char	desc[KSTAT_DESCLEN];
 	union {
 		uint64_t	ui64;
+                struct {
+                        union {
+                                char *ptr;      /* NULL-term string */
+                                char __pad[8];  /* 64-bit padding */
+                        } addr;
+                        uint32_t len;           /* # bytes for strlen + '\0' */
+                } string;
 	} value;
 } kstat_named_t;
+
+#define KSTAT_NAMED_STR_PTR(knptr) ((knptr)->value.string.addr.ptr)
+#define KSTAT_NAMED_STR_BUFLEN(knptr) ((knptr)->value.string.len)
 
 kstat_t *kstat_create(char *module, int instance, char *name, char *cls,
     uchar_t type, ulong_t ndata, uchar_t flags);

Modified: releng/12.2/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c
==============================================================================
--- releng/12.2/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c	Sat Sep 19 20:18:14 2020	(r365916)
+++ releng/12.2/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c	Sat Sep 19 20:46:56 2020	(r365917)
@@ -446,6 +446,8 @@ zfs_prop_init(void)
 	    ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "<uint64>", "GUID");
 	zprop_register_number(ZFS_PROP_CREATETXG, "createtxg", 0, PROP_READONLY,
 	    ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK, "<uint64>", "CREATETXG");
+	zprop_register_number(ZFS_PROP_OBJSETID, "objsetid", 0,
+	    PROP_READONLY, ZFS_TYPE_DATASET, "<uint64>", "OBJSETID");
 
 	/* inherit number properties */
 	zprop_register_number(ZFS_PROP_RECORDSIZE, "recordsize",
@@ -472,8 +474,6 @@ zfs_prop_init(void)
 	    "USERACCOUNTING");
 	zprop_register_hidden(ZFS_PROP_UNIQUE, "unique", PROP_TYPE_NUMBER,
 	    PROP_READONLY, ZFS_TYPE_DATASET, "UNIQUE");
-	zprop_register_hidden(ZFS_PROP_OBJSETID, "objsetid", PROP_TYPE_NUMBER,
-	    PROP_READONLY, ZFS_TYPE_DATASET, "OBJSETID");
 	zprop_register_hidden(ZFS_PROP_INCONSISTENT, "inconsistent",
 	    PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_DATASET, "INCONSISTENT");
 	zprop_register_hidden(ZFS_PROP_PREV_SNAP, "prevsnap", PROP_TYPE_STRING,

Modified: releng/12.2/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c
==============================================================================
--- releng/12.2/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c	Sat Sep 19 20:18:14 2020	(r365916)
+++ releng/12.2/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c	Sat Sep 19 20:46:56 2020	(r365917)
@@ -21,7 +21,7 @@
 /*
  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2017, 2018 by Delphix. All rights reserved.
  * Copyright (c) 2014 Integros [integros.com]
  */
 
@@ -96,6 +96,8 @@ zpool_prop_init(void)
 	    ZFS_TYPE_POOL, "<size>", "CAP");
 	zprop_register_number(ZPOOL_PROP_GUID, "guid", 0, PROP_READONLY,
 	    ZFS_TYPE_POOL, "<guid>", "GUID");
+	zprop_register_number(ZPOOL_PROP_LOAD_GUID, "load_guid", 0,
+	    PROP_READONLY, ZFS_TYPE_POOL, "<load_guid>", "LOAD_GUID");
 	zprop_register_number(ZPOOL_PROP_HEALTH, "health", 0, PROP_READONLY,
 	    ZFS_TYPE_POOL, "<state>", "HEALTH");
 	zprop_register_number(ZPOOL_PROP_DEDUPRATIO, "dedupratio", 0,

Modified: releng/12.2/sys/cddl/contrib/opensolaris/uts/common/Makefile.files
==============================================================================
--- releng/12.2/sys/cddl/contrib/opensolaris/uts/common/Makefile.files	Sat Sep 19 20:18:14 2020	(r365916)
+++ releng/12.2/sys/cddl/contrib/opensolaris/uts/common/Makefile.files	Sat Sep 19 20:46:56 2020	(r365917)
@@ -71,6 +71,7 @@ ZFS_COMMON_OBJS +=		\
 	bptree.o		\
 	bqueue.o		\
 	cityhash.o		\
+	dataset_kstats.c	\
 	dbuf.o			\
 	dbuf_stats.o		\
 	ddt.o			\

Copied: releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dataset_kstats.c (from r365689, stable/12/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dataset_kstats.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dataset_kstats.c	Sat Sep 19 20:46:56 2020	(r365917, copy of r365689, stable/12/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dataset_kstats.c)
@@ -0,0 +1,185 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2018 by Delphix. All rights reserved.
+ */
+
+#include <sys/dataset_kstats.h>
+#include <sys/dmu_objset.h>
+#include <sys/dsl_dataset.h>
+#include <sys/spa.h>
+
+static dataset_kstat_values_t empty_dataset_kstats = {
+	{ "dataset_name",	KSTAT_DATA_STRING },
+	{ "writes",	KSTAT_DATA_UINT64 },
+	{ "nwritten",	KSTAT_DATA_UINT64 },
+	{ "reads",	KSTAT_DATA_UINT64 },
+	{ "nread",	KSTAT_DATA_UINT64 },
+};
+
+static int
+dataset_kstats_update(kstat_t *ksp, int rw)
+{
+	dataset_kstats_t *dk = ksp->ks_private;
+	ASSERT3P(dk->dk_kstats->ks_data, ==, ksp->ks_data);
+
+	if (rw == KSTAT_WRITE)
+		return (EACCES);
+
+	dataset_kstat_values_t *dkv = dk->dk_kstats->ks_data;
+	dkv->dkv_writes.value.ui64 =
+	    aggsum_value(&dk->dk_aggsums.das_writes);
+	dkv->dkv_nwritten.value.ui64 =
+	    aggsum_value(&dk->dk_aggsums.das_nwritten);
+	dkv->dkv_reads.value.ui64 =
+	    aggsum_value(&dk->dk_aggsums.das_reads);
+	dkv->dkv_nread.value.ui64 =
+	    aggsum_value(&dk->dk_aggsums.das_nread);
+
+	return (0);
+}
+
+void
+dataset_kstats_create(dataset_kstats_t *dk, objset_t *objset)
+{
+	/*
+	 * There should not be anything wrong with having kstats for
+	 * snapshots. Since we are not sure how useful they would be
+	 * though nor how much their memory overhead would matter in
+	 * a filesystem with many snapshots, we skip them for now.
+	 */
+	if (dmu_objset_is_snapshot(objset))
+		return;
+
+	/*
+	 * At the time of this writing, KSTAT_STRLEN is 255 in Linux,
+	 * and the spa_name can theoretically be up to 256 characters.
+	 * In reality though the spa_name can be 240 characters max
+	 * [see origin directory name check in pool_namecheck()]. Thus,
+	 * the naming scheme for the module name below should not cause
+	 * any truncations. In the event that a truncation does happen
+	 * though, due to some future change, we silently skip creating
+	 * the kstat and log the event.
+	 */
+	char kstat_module_name[KSTAT_STRLEN];
+	int n = snprintf(kstat_module_name, sizeof (kstat_module_name),
+	    "zfs/%s", spa_name(dmu_objset_spa(objset)));
+	if (n < 0) {
+		zfs_dbgmsg("failed to create dataset kstat for objset %lld: "
+		    " snprintf() for kstat module name returned %d",
+		    (unsigned long long)dmu_objset_id(objset), n);
+		return;
+	} else if (n >= KSTAT_STRLEN) {
+		zfs_dbgmsg("failed to create dataset kstat for objset %lld: "
+		    "kstat module name length (%d) exceeds limit (%d)",
+		    (unsigned long long)dmu_objset_id(objset),
+		    n, KSTAT_STRLEN);
+		return;
+	}
+
+	char kstat_name[KSTAT_STRLEN];
+	n = snprintf(kstat_name, sizeof (kstat_name), "objset-0x%llx",
+	    (unsigned long long)dmu_objset_id(objset));
+	if (n < 0) {
+		zfs_dbgmsg("failed to create dataset kstat for objset %lld: "
+		    " snprintf() for kstat name returned %d",
+		    (unsigned long long)dmu_objset_id(objset), n);
+		return;
+	}
+	ASSERT3U(n, <, KSTAT_STRLEN);
+
+	kstat_t *kstat = kstat_create(kstat_module_name, 0, kstat_name,
+	    "dataset", KSTAT_TYPE_NAMED,
+	    sizeof (empty_dataset_kstats) / sizeof (kstat_named_t),
+	    KSTAT_FLAG_VIRTUAL);
+	if (kstat == NULL)
+		return;
+
+	dataset_kstat_values_t *dk_kstats =
+	    kmem_alloc(sizeof (empty_dataset_kstats), KM_SLEEP);
+	bcopy(&empty_dataset_kstats, dk_kstats,
+	    sizeof (empty_dataset_kstats));
+
+	char *ds_name = kmem_zalloc(ZFS_MAX_DATASET_NAME_LEN, KM_SLEEP);
+	dsl_dataset_name(objset->os_dsl_dataset, ds_name);
+	KSTAT_NAMED_STR_PTR(&dk_kstats->dkv_ds_name) = ds_name;
+	KSTAT_NAMED_STR_BUFLEN(&dk_kstats->dkv_ds_name) =
+	    ZFS_MAX_DATASET_NAME_LEN;
+
+	kstat->ks_data = dk_kstats;
+	kstat->ks_update = dataset_kstats_update;
+	kstat->ks_private = dk;
+
+	kstat_install(kstat);
+	dk->dk_kstats = kstat;
+
+	aggsum_init(&dk->dk_aggsums.das_writes, 0);
+	aggsum_init(&dk->dk_aggsums.das_nwritten, 0);
+	aggsum_init(&dk->dk_aggsums.das_reads, 0);
+	aggsum_init(&dk->dk_aggsums.das_nread, 0);
+}
+
+void
+dataset_kstats_destroy(dataset_kstats_t *dk)
+{
+	if (dk->dk_kstats == NULL)
+		return;
+
+	dataset_kstat_values_t *dkv = dk->dk_kstats->ks_data;
+	kmem_free(KSTAT_NAMED_STR_PTR(&dkv->dkv_ds_name),
+	    KSTAT_NAMED_STR_BUFLEN(&dkv->dkv_ds_name));
+	kmem_free(dkv, sizeof (empty_dataset_kstats));
+
+	kstat_delete(dk->dk_kstats);
+	dk->dk_kstats = NULL;
+
+	aggsum_fini(&dk->dk_aggsums.das_writes);
+	aggsum_fini(&dk->dk_aggsums.das_nwritten);
+	aggsum_fini(&dk->dk_aggsums.das_reads);
+	aggsum_fini(&dk->dk_aggsums.das_nread);
+}
+
+void
+dataset_kstats_update_write_kstats(dataset_kstats_t *dk,
+    int64_t nwritten)
+{
+	ASSERT3S(nwritten, >=, 0);
+
+	if (dk->dk_kstats == NULL)
+		return;
+
+	aggsum_add(&dk->dk_aggsums.das_writes, 1);
+	aggsum_add(&dk->dk_aggsums.das_nwritten, nwritten);
+}
+
+void
+dataset_kstats_update_read_kstats(dataset_kstats_t *dk,
+    int64_t nread)
+{
+	ASSERT3S(nread, >=, 0);
+
+	if (dk->dk_kstats == NULL)
+		return;
+
+	aggsum_add(&dk->dk_aggsums.das_reads, 1);
+	aggsum_add(&dk->dk_aggsums.das_nread, nread);
+}

Modified: releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
==============================================================================
--- releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c	Sat Sep 19 20:18:14 2020	(r365916)
+++ releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c	Sat Sep 19 20:46:56 2020	(r365917)
@@ -352,6 +352,9 @@ spa_prop_get_config(spa_t *spa, nvlist_t **nvp)
 		else
 			src = ZPROP_SRC_LOCAL;
 		spa_prop_add_list(*nvp, ZPOOL_PROP_VERSION, NULL, version, src);
+
+		spa_prop_add_list(*nvp, ZPOOL_PROP_LOAD_GUID,
+		    NULL, spa_load_guid(spa), src);
 	}
 
 	if (pool != NULL) {

Copied: releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dataset_kstats.h (from r365689, stable/12/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dataset_kstats.h)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dataset_kstats.h	Sat Sep 19 20:46:56 2020	(r365917, copy of r365689, stable/12/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dataset_kstats.h)
@@ -0,0 +1,59 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2018 by Delphix. All rights reserved.
+ */
+
+#ifndef _SYS_DATASET_KSTATS_H
+#define	_SYS_DATASET_KSTATS_H
+
+#include <sys/aggsum.h>
+#include <sys/dmu.h>
+#include <sys/kstat.h>
+
+typedef struct dataset_aggsum_stats_t {
+	aggsum_t das_writes;
+	aggsum_t das_nwritten;
+	aggsum_t das_reads;
+	aggsum_t das_nread;
+} dataset_aggsum_stats_t;
+
+typedef struct dataset_kstat_values {
+	kstat_named_t dkv_ds_name;
+	kstat_named_t dkv_writes;
+	kstat_named_t dkv_nwritten;
+	kstat_named_t dkv_reads;
+	kstat_named_t dkv_nread;
+} dataset_kstat_values_t;
+
+typedef struct dataset_kstats {
+	dataset_aggsum_stats_t dk_aggsums;
+	kstat_t *dk_kstats;
+} dataset_kstats_t;
+
+void dataset_kstats_create(dataset_kstats_t *, objset_t *);
+void dataset_kstats_destroy(dataset_kstats_t *);
+
+void dataset_kstats_update_write_kstats(dataset_kstats_t *, int64_t);
+void dataset_kstats_update_read_kstats(dataset_kstats_t *, int64_t);
+
+#endif /* _SYS_DATASET_KSTATS_H */

Modified: releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h
==============================================================================
--- releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h	Sat Sep 19 20:18:14 2020	(r365916)
+++ releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_vfsops.h	Sat Sep 19 20:46:56 2020	(r365917)
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2018 by Delphix. All rights reserved.
  * Copyright (c) 2011 Pawel Jakub Dawidek <pawel at dawidek.net>.
  * All rights reserved.
  */
@@ -27,6 +28,7 @@
 #ifndef	_SYS_FS_ZFS_VFSOPS_H
 #define	_SYS_FS_ZFS_VFSOPS_H
 
+#include <sys/dataset_kstats.h>
 #include <sys/list.h>
 #include <sys/vfs.h>
 #include <sys/zil.h>
@@ -80,6 +82,7 @@ struct zfsvfs {
 	boolean_t	z_use_namecache;/* make use of FreeBSD name cache */
 	uint64_t	z_version;	/* ZPL version */
 	uint64_t	z_shares_dir;	/* hidden shares dir */
+	dataset_kstats_t	z_kstat;	/* fs kstats */
 	kmutex_t	z_lock;
 	uint64_t	z_userquota_obj;
 	uint64_t	z_groupquota_obj;

Modified: releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
==============================================================================
--- releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c	Sat Sep 19 20:18:14 2020	(r365916)
+++ releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c	Sat Sep 19 20:46:56 2020	(r365917)
@@ -1245,6 +1245,9 @@ zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting)
 	if (mounting) {
 		boolean_t readonly;
 
+		ASSERT3P(zfsvfs->z_kstat.dk_kstats, ==, NULL);
+		dataset_kstats_create(&zfsvfs->z_kstat, zfsvfs->z_os);
+
 		/*
 		 * During replay we remove the read only flag to
 		 * allow replays to succeed.
@@ -1333,6 +1336,7 @@ zfsvfs_free(zfsvfs_t *zfsvfs)
 	rw_destroy(&zfsvfs->z_fuid_lock);
 	for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
 		mutex_destroy(&zfsvfs->z_hold_mtx[i]);
+	dataset_kstats_destroy(&zfsvfs->z_kstat);
 	kmem_free(zfsvfs, sizeof (zfsvfs_t));
 }
 

Modified: releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
==============================================================================
--- releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	Sat Sep 19 20:18:14 2020	(r365916)
+++ releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	Sat Sep 19 20:46:56 2020	(r365917)
@@ -77,6 +77,7 @@
 #include <sys/vmmeter.h>
 #include <vm/vm_param.h>
 #include <sys/zil.h>
+#include <sys/dataset_kstats.h>
 
 /*
  * Programming rules.
@@ -701,9 +702,10 @@ zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *
 {
 	znode_t		*zp = VTOZ(vp);
 	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
-	ssize_t		n, nbytes;
+	ssize_t		n, nbytes, start_resid;
 	int		error = 0;
 	xuio_t		*xuio = NULL;
+	int64_t		nread;
 
 	ZFS_ENTER(zfsvfs);
 	ZFS_VERIFY_ZP(zp);
@@ -764,6 +766,7 @@ zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *
 
 	ASSERT(uio->uio_loffset < zp->z_size);
 	n = MIN(uio->uio_resid, zp->z_size - uio->uio_loffset);
+	start_resid = n;
 
 #ifdef illumos
 	if ((uio->uio_extflg == UIO_XUIO) &&
@@ -820,6 +823,10 @@ zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *
 
 		n -= nbytes;
 	}
+
+	nread = start_resid - n;
+	dataset_kstats_update_read_kstats(&zfsvfs->z_kstat, nread);
+
 out:
 	rangelock_exit(lr);
 
@@ -873,6 +880,7 @@ zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t 
 	int		count = 0;
 	sa_bulk_attr_t	bulk[4];
 	uint64_t	mtime[2], ctime[2];
+	int64_t		nwritten;
 
 	/*
 	 * Fasttrack empty write
@@ -1239,6 +1247,9 @@ zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t 
 	if (ioflag & (FSYNC | FDSYNC) ||
 	    zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
 		zil_commit(zilog, zp->z_id);
+
+	nwritten = start_resid - uio->uio_resid;
+	dataset_kstats_update_write_kstats(&zfsvfs->z_kstat, nwritten);
 
 	ZFS_EXIT(zfsvfs);
 	return (0);

Modified: releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c
==============================================================================
--- releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c	Sat Sep 19 20:18:14 2020	(r365916)
+++ releng/12.2/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c	Sat Sep 19 20:46:56 2020	(r365917)
@@ -96,6 +96,7 @@
 #include <sys/zil_impl.h>
 #include <sys/filio.h>
 #include <sys/zfs_rlock.h>
+#include <sys/dataset_kstats.h>
 
 #include <geom/geom.h>
 
@@ -177,6 +178,7 @@ typedef struct zvol_state {
 	list_t		zv_extents;	/* List of extents for dump */
 	rangelock_t	zv_rangelock;
 	dnode_t		*zv_dn;		/* dnode hold */
+	dataset_kstats_t	zv_kstat;	/* zvol kstats */
 #ifndef illumos
 	int		zv_state;
 	int		zv_volmode;	/* Provide GEOM or cdev */
@@ -768,6 +770,10 @@ zvol_create_minor(const char *name)
 		else
 			zil_replay(os, zv, zvol_replay_vector);
 	}
+
+	ASSERT3P(zv->zv_kstat.dk_kstats, ==, NULL);
+	dataset_kstats_create(&zv->zv_kstat, zv->zv_objset);
+
 	dmu_objset_disown(os, FTAG);
 	zv->zv_objset = NULL;
 
@@ -823,6 +829,7 @@ zvol_remove_zv(zvol_state_t *zv)
 
 	rangelock_fini(&zv->zv_rangelock);
 
+	dataset_kstats_destroy(&zv->zv_kstat);
 	kmem_free(zv, sizeof (zvol_state_t));
 #ifdef illumos
 	ddi_soft_state_free(zfsdev_state, minor);
@@ -1752,6 +1759,23 @@ unlock:
 	bp->bio_completed = bp->bio_length - resid;
 	if (bp->bio_completed < bp->bio_length && off > volsize)
 		error = EINVAL;
+
+	switch (bp->bio_cmd) {
+	case BIO_FLUSH:
+		break;
+	case BIO_READ:
+		dataset_kstats_update_read_kstats(&zv->zv_kstat,
+		    bp->bio_completed);
+		break;
+	case BIO_WRITE:
+		dataset_kstats_update_write_kstats(&zv->zv_kstat,
+		    bp->bio_completed);
+		break;
+	case BIO_DELETE:
+		break;
+	default:
+		break;
+	}
 
 	if (sync) {
 sync:

Modified: releng/12.2/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
==============================================================================
--- releng/12.2/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h	Sat Sep 19 20:18:14 2020	(r365916)
+++ releng/12.2/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h	Sat Sep 19 20:46:56 2020	(r365917)
@@ -148,7 +148,7 @@ typedef enum {
 	ZFS_PROP_USERREFS,
 	ZFS_PROP_LOGBIAS,
 	ZFS_PROP_UNIQUE,		/* not exposed to the user */
-	ZFS_PROP_OBJSETID,		/* not exposed to the user */
+	ZFS_PROP_OBJSETID,
 	ZFS_PROP_DEDUP,
 	ZFS_PROP_MLSLABEL,
 	ZFS_PROP_SYNC,
@@ -220,6 +220,7 @@ typedef enum {
 	ZPOOL_PROP_TNAME,
 	ZPOOL_PROP_MAXDNODESIZE,
 	ZPOOL_PROP_MULTIHOST,
+	ZPOOL_PROP_LOAD_GUID,
 	ZPOOL_NUM_PROPS
 } zpool_prop_t;
 

Modified: releng/12.2/sys/conf/files
==============================================================================
--- releng/12.2/sys/conf/files	Sat Sep 19 20:18:14 2020	(r365916)
+++ releng/12.2/sys/conf/files	Sat Sep 19 20:46:56 2020	(r365917)
@@ -163,6 +163,7 @@ cddl/contrib/opensolaris/uts/common/fs/zfs/bpobj.c			o
 cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c			optional zfs compile-with "${ZFS_C}"
 cddl/contrib/opensolaris/uts/common/fs/zfs/bqueue.c			optional zfs compile-with "${ZFS_C}"
 cddl/contrib/opensolaris/uts/common/fs/zfs/cityhash.c			optional zfs compile-with "${ZFS_C}"
+cddl/contrib/opensolaris/uts/common/fs/zfs/dataset_kstats.c		optional zfs compile-with "${ZFS_C}"
 cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c			optional zfs compile-with "${ZFS_C}"
 cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf_stats.c		optional zfs compile-with "${ZFS_C}"
 cddl/contrib/opensolaris/uts/common/fs/zfs/ddt.c			optional zfs compile-with "${ZFS_C}"

Modified: releng/12.2/tests/sys/cddl/zfs/tests/cli_root/zpool_get/zpool_get.cfg
==============================================================================
--- releng/12.2/tests/sys/cddl/zfs/tests/cli_root/zpool_get/zpool_get.cfg	Sat Sep 19 20:18:14 2020	(r365916)
+++ releng/12.2/tests/sys/cddl/zfs/tests/cli_root/zpool_get/zpool_get.cfg	Sat Sep 19 20:46:56 2020	(r365917)
@@ -35,6 +35,7 @@ typeset -a properties=(
     "altroot"
     "health"
     "guid"
+    "load_guid"
     "version"
     "bootfs"
     "delegation"


More information about the svn-src-all mailing list