Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 10 Jun 2012 07:40:26 +0000 (UTC)
From:      Martin Matuska <mm@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r236839 - in stable/9: cddl/contrib/opensolaris/cmd/zpool cddl/contrib/opensolaris/lib/libzfs/common sys/cddl/contrib/opensolaris/common/zfs sys/cddl/contrib/opensolaris/uts/common/fs/z...
Message-ID:  <201206100740.q5A7eQO1080957@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mm
Date: Sun Jun 10 07:40:26 2012
New Revision: 236839
URL: http://svn.freebsd.org/changeset/base/236839

Log:
  MFC r236155:
  Import illumos changeset 13570:3411fd5f1589
  1948 zpool list should show more detailed pool information
  
  Display per-vdev information with "zpool list -v".
  The added expandsize property has currently no value on FreeBSD.
  This changeset allows adding expansion support to individual vdevs
  in the future.
  
  References:
  https://www.illumos.org/issues/1948
  
  Obtained from:	illumos (issue #1948)

Modified:
  stable/9/cddl/contrib/opensolaris/cmd/zpool/zpool.8
  stable/9/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
  stable/9/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
  stable/9/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
  stable/9/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_root.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
  stable/9/sys/cddl/contrib/opensolaris/uts/common/sys/fs/zfs.h
Directory Properties:
  stable/9/cddl/contrib/opensolaris/   (props changed)
  stable/9/sys/   (props changed)
  stable/9/sys/cddl/contrib/opensolaris/   (props changed)

Modified: stable/9/cddl/contrib/opensolaris/cmd/zpool/zpool.8
==============================================================================
--- stable/9/cddl/contrib/opensolaris/cmd/zpool/zpool.8	Sun Jun 10 07:24:04 2012	(r236838)
+++ stable/9/cddl/contrib/opensolaris/cmd/zpool/zpool.8	Sun Jun 10 07:40:26 2012	(r236839)
@@ -537,6 +537,8 @@ value of 1.76 indicates that 1.76 units 
 for a description of the deduplication feature.
 .It Sy free
 Number of blocks within the pool that are not allocated.
+.It Sy expandsize
+This property has currently no value on FreeBSD.
 .It Sy guid
 A unique identifier for the pool.
 .It Sy health
@@ -1275,7 +1277,7 @@ Treat exported or foreign devices as ina
 .It Xo
 .Nm
 .Cm list
-.Op Fl H
+.Op Fl Hv
 .Op Fl o Ar property Ns Op , Ns Ar ...
 .Op Fl T Cm d Ns | Ns Cm u
 .Op Ar pool

Modified: stable/9/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c
==============================================================================
--- stable/9/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c	Sun Jun 10 07:24:04 2012	(r236838)
+++ stable/9/cddl/contrib/opensolaris/cmd/zpool/zpool_main.c	Sun Jun 10 07:40:26 2012	(r236839)
@@ -22,9 +22,9 @@
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  * Copyright (c) 2012 by Frederik Wessels. All rights reserved.
- * Copyright (c) 2011 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
+ * Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
  */
 
 #include <solaris.h>
@@ -46,6 +46,7 @@
 #include <pwd.h>
 #include <zone.h>
 #include <sys/time.h>
+#include <zfs_prop.h>
 #include <sys/fs/zfs.h>
 #include <sys/stat.h>
 
@@ -70,6 +71,7 @@ static int zpool_do_status(int, char **)
 static int zpool_do_online(int, char **);
 static int zpool_do_offline(int, char **);
 static int zpool_do_clear(int, char **);
+static int zpool_do_reopen(int, char **);
 
 static int zpool_do_reguid(int, char **);
 
@@ -132,7 +134,8 @@ typedef enum {
 	HELP_GET,
 	HELP_SET,
 	HELP_SPLIT,
-	HELP_REGUID
+	HELP_REGUID,
+	HELP_REOPEN
 } zpool_help_t;
 
 
@@ -167,6 +170,7 @@ static zpool_command_t command_table[] =
 	{ "online",	zpool_do_online,	HELP_ONLINE		},
 	{ "offline",	zpool_do_offline,	HELP_OFFLINE		},
 	{ "clear",	zpool_do_clear,		HELP_CLEAR		},
+	{ "reopen",	zpool_do_reopen,	HELP_REOPEN		},
 	{ NULL },
 	{ "attach",	zpool_do_attach,	HELP_ATTACH		},
 	{ "detach",	zpool_do_detach,	HELP_DETACH		},
@@ -241,6 +245,8 @@ get_usage(zpool_help_t idx) {
 		    "[new-device]\n"));
 	case HELP_REMOVE:
 		return (gettext("\tremove <pool> <device> ...\n"));
+	case HELP_REOPEN:
+		return (""); /* Undocumented command */
 	case HELP_SCRUB:
 		return (gettext("\tscrub [-s] <pool> ...\n"));
 	case HELP_STATUS:
@@ -2109,10 +2115,10 @@ error:
 }
 
 typedef struct iostat_cbdata {
-	zpool_list_t *cb_list;
-	int cb_verbose;
-	int cb_iteration;
+	boolean_t cb_verbose;
 	int cb_namewidth;
+	int cb_iteration;
+	zpool_list_t *cb_list;
 } iostat_cbdata_t;
 
 static void
@@ -2582,8 +2588,9 @@ zpool_do_iostat(int argc, char **argv)
 }
 
 typedef struct list_cbdata {
+	boolean_t	cb_verbose;
+	int		cb_namewidth;
 	boolean_t	cb_scripted;
-	boolean_t	cb_first;
 	zprop_list_t	*cb_proplist;
 } list_cbdata_t;
 
@@ -2591,16 +2598,27 @@ typedef struct list_cbdata {
  * Given a list of columns to display, output appropriate headers for each one.
  */
 static void
-print_header(zprop_list_t *pl)
+print_header(list_cbdata_t *cb)
 {
+	zprop_list_t *pl = cb->cb_proplist;
 	const char *header;
 	boolean_t first = B_TRUE;
 	boolean_t right_justify;
+	size_t width = 0;
 
 	for (; pl != NULL; pl = pl->pl_next) {
 		if (pl->pl_prop == ZPROP_INVAL)
 			continue;
 
+		width = pl->pl_width;
+		if (first && cb->cb_verbose) {
+			/*
+			 * Reset the width to accommodate the verbose listing
+			 * of devices.
+			 */
+			width = cb->cb_namewidth;
+		}
+
 		if (!first)
 			(void) printf("  ");
 		else
@@ -2612,9 +2630,10 @@ print_header(zprop_list_t *pl)
 		if (pl->pl_next == NULL && !right_justify)
 			(void) printf("%s", header);
 		else if (right_justify)
-			(void) printf("%*s", pl->pl_width, header);
+			(void) printf("%*s", width, header);
 		else
-			(void) printf("%-*s", pl->pl_width, header);
+			(void) printf("%-*s", width, header);
+
 	}
 
 	(void) printf("\n");
@@ -2625,17 +2644,28 @@ print_header(zprop_list_t *pl)
  * to the described layout.
  */
 static void
-print_pool(zpool_handle_t *zhp, zprop_list_t *pl, int scripted)
+print_pool(zpool_handle_t *zhp, list_cbdata_t *cb)
 {
+	zprop_list_t *pl = cb->cb_proplist;
 	boolean_t first = B_TRUE;
 	char property[ZPOOL_MAXPROPLEN];
 	char *propstr;
 	boolean_t right_justify;
-	int width;
+	size_t width;
 
 	for (; pl != NULL; pl = pl->pl_next) {
+
+		width = pl->pl_width;
+		if (first && cb->cb_verbose) {
+			/*
+			 * Reset the width to accommodate the verbose listing
+			 * of devices.
+			 */
+			width = cb->cb_namewidth;
+		}
+
 		if (!first) {
-			if (scripted)
+			if (cb->cb_scripted)
 				(void) printf("\t");
 			else
 				(void) printf("  ");
@@ -2645,7 +2675,10 @@ print_pool(zpool_handle_t *zhp, zprop_li
 
 		right_justify = B_FALSE;
 		if (pl->pl_prop != ZPROP_INVAL) {
-			if (zpool_get_prop(zhp, pl->pl_prop, property,
+			if (pl->pl_prop == ZPOOL_PROP_EXPANDSZ &&
+			    zpool_get_prop_int(zhp, pl->pl_prop, NULL) == 0)
+				propstr = "-";
+			else if (zpool_get_prop(zhp, pl->pl_prop, property,
 			    sizeof (property), NULL) != 0)
 				propstr = "-";
 			else
@@ -2656,14 +2689,13 @@ print_pool(zpool_handle_t *zhp, zprop_li
 			propstr = "-";
 		}
 
-		width = pl->pl_width;
 
 		/*
 		 * If this is being called in scripted mode, or if this is the
 		 * last column and it is left-justified, don't include a width
 		 * format specifier.
 		 */
-		if (scripted || (pl->pl_next == NULL && !right_justify))
+		if (cb->cb_scripted || (pl->pl_next == NULL && !right_justify))
 			(void) printf("%s", propstr);
 		else if (right_justify)
 			(void) printf("%*s", width, propstr);
@@ -2674,6 +2706,101 @@ print_pool(zpool_handle_t *zhp, zprop_li
 	(void) printf("\n");
 }
 
+static void
+print_one_column(zpool_prop_t prop, uint64_t value, boolean_t scripted)
+{
+	char propval[64];
+	boolean_t fixed;
+	size_t width = zprop_width(prop, &fixed, ZFS_TYPE_POOL);
+
+	zfs_nicenum(value, propval, sizeof (propval));
+
+	if (prop == ZPOOL_PROP_EXPANDSZ && value == 0)
+		(void) strlcpy(propval, "-", sizeof (propval));
+
+	if (scripted)
+		(void) printf("\t%s", propval);
+	else
+		(void) printf("  %*s", width, propval);
+}
+
+void
+print_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
+    list_cbdata_t *cb, int depth)
+{
+	nvlist_t **child;
+	vdev_stat_t *vs;
+	uint_t c, children;
+	char *vname;
+	boolean_t scripted = cb->cb_scripted;
+
+	verify(nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
+	    (uint64_t **)&vs, &c) == 0);
+
+	if (name != NULL) {
+		if (scripted)
+			(void) printf("\t%s", name);
+		else if (strlen(name) + depth > cb->cb_namewidth)
+			(void) printf("%*s%s", depth, "", name);
+		else
+			(void) printf("%*s%s%*s", depth, "", name,
+			    (int)(cb->cb_namewidth - strlen(name) - depth), "");
+
+		/* only toplevel vdevs have capacity stats */
+		if (vs->vs_space == 0) {
+			if (scripted)
+				(void) printf("\t-\t-\t-");
+			else
+				(void) printf("      -      -      -");
+		} else {
+			print_one_column(ZPOOL_PROP_SIZE, vs->vs_space,
+			    scripted);
+			print_one_column(ZPOOL_PROP_CAPACITY, vs->vs_alloc,
+			    scripted);
+			print_one_column(ZPOOL_PROP_FREE,
+			    vs->vs_space - vs->vs_alloc, scripted);
+		}
+		print_one_column(ZPOOL_PROP_EXPANDSZ, vs->vs_esize,
+		    scripted);
+		(void) printf("\n");
+	}
+
+	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN,
+	    &child, &children) != 0)
+		return;
+
+	for (c = 0; c < children; c++) {
+		uint64_t ishole = B_FALSE;
+
+		if (nvlist_lookup_uint64(child[c],
+		    ZPOOL_CONFIG_IS_HOLE, &ishole) == 0 && ishole)
+			continue;
+
+		vname = zpool_vdev_name(g_zfs, zhp, child[c], B_FALSE);
+		print_list_stats(zhp, vname, child[c], cb, depth + 2);
+		free(vname);
+	}
+
+	/*
+	 * Include level 2 ARC devices in iostat output
+	 */
+	if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE,
+	    &child, &children) != 0)
+		return;
+
+	if (children > 0) {
+		(void) printf("%-*s      -      -      -      -      -      "
+		    "-\n", cb->cb_namewidth, "cache");
+		for (c = 0; c < children; c++) {
+			vname = zpool_vdev_name(g_zfs, zhp, child[c],
+			    B_FALSE);
+			print_list_stats(zhp, vname, child[c], cb, depth + 2);
+			free(vname);
+		}
+	}
+}
+
+
 /*
  * Generic callback function to list a pool.
  */
@@ -2681,14 +2808,18 @@ int
 list_callback(zpool_handle_t *zhp, void *data)
 {
 	list_cbdata_t *cbp = data;
+	nvlist_t *config;
+	nvlist_t *nvroot;
 
-	if (cbp->cb_first) {
-		if (!cbp->cb_scripted)
-			print_header(cbp->cb_proplist);
-		cbp->cb_first = B_FALSE;
-	}
+	config = zpool_get_config(zhp, NULL);
 
-	print_pool(zhp, cbp->cb_proplist, cbp->cb_scripted);
+	print_pool(zhp, cbp);
+	if (!cbp->cb_verbose)
+		return (0);
+
+	verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
+	    &nvroot) == 0);
+	print_list_stats(zhp, NULL, nvroot, cbp, 0);
 
 	return (0);
 }
@@ -2712,12 +2843,15 @@ zpool_do_list(int argc, char **argv)
 	int ret;
 	list_cbdata_t cb = { 0 };
 	static char default_props[] =
-	    "name,size,allocated,free,capacity,dedupratio,health,altroot";
+	    "name,size,allocated,free,capacity,dedupratio,"
+	    "health,altroot";
 	char *props = default_props;
 	unsigned long interval = 0, count = 0;
+	zpool_list_t *list;
+	boolean_t first = B_TRUE;
 
 	/* check options */
-	while ((c = getopt(argc, argv, ":Ho:T:")) != -1) {
+	while ((c = getopt(argc, argv, ":Ho:T:v")) != -1) {
 		switch (c) {
 		case 'H':
 			cb.cb_scripted = B_TRUE;
@@ -2728,6 +2862,9 @@ zpool_do_list(int argc, char **argv)
 		case 'T':
 			get_timestamp_arg(*optarg);
 			break;
+		case 'v':
+			cb.cb_verbose = B_TRUE;
+			break;
 		case ':':
 			(void) fprintf(stderr, gettext("missing argument for "
 			    "'%c' option\n"), optopt);
@@ -2748,21 +2885,32 @@ zpool_do_list(int argc, char **argv)
 	if (zprop_get_list(g_zfs, props, &cb.cb_proplist, ZFS_TYPE_POOL) != 0)
 		usage(B_FALSE);
 
-	cb.cb_first = B_TRUE;
+	if ((list = pool_list_get(argc, argv, &cb.cb_proplist, &ret)) == NULL)
+		return (1);
+
+	if (argc == 0 && !cb.cb_scripted && pool_list_count(list) == 0) {
+		(void) printf(gettext("no pools available\n"));
+		zprop_free_list(cb.cb_proplist);
+		return (0);
+	}
 
 	for (;;) {
+		pool_list_update(list);
+
+		if (pool_list_count(list) == 0)
+			break;
+
+		cb.cb_namewidth = 0;
+		(void) pool_list_iter(list, B_FALSE, get_namewidth, &cb);
 
 		if (timestamp_fmt != NODATE)
 			print_timestamp(timestamp_fmt);
 
-		ret = for_each_pool(argc, argv, B_TRUE, &cb.cb_proplist,
-		    list_callback, &cb);
-
-		if (argc == 0 && cb.cb_first && !cb.cb_scripted) {
-			(void) printf(gettext("no pools available\n"));
-			zprop_free_list(cb.cb_proplist);
-			return (0);
+		if (!cb.cb_scripted && (first || cb.cb_verbose)) {
+			print_header(&cb);
+			first = B_FALSE;
 		}
+		ret = pool_list_iter(list, B_TRUE, list_callback, &cb);
 
 		if (interval == 0)
 			break;
@@ -3382,6 +3530,36 @@ zpool_do_reguid(int argc, char **argv)
 }
 
 
+/*
+ * zpool reopen <pool>
+ *
+ * Reopen the pool so that the kernel can update the sizes of all vdevs.
+ *
+ * NOTE: This command is currently undocumented.  If the command is ever
+ * exposed then the appropriate usage() messages will need to be made.
+ */
+int
+zpool_do_reopen(int argc, char **argv)
+{
+	int ret = 0;
+	zpool_handle_t *zhp;
+	char *pool;
+
+	argc--;
+	argv++;
+
+	if (argc != 1)
+		return (2);
+
+	pool = argv[0];
+	if ((zhp = zpool_open_canfail(g_zfs, pool)) == NULL)
+		return (1);
+
+	ret = zpool_reopen(zhp);
+	zpool_close(zhp);
+	return (ret);
+}
+
 typedef struct scrub_cbdata {
 	int	cb_type;
 	int	cb_argc;

Modified: stable/9/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h
==============================================================================
--- stable/9/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h	Sun Jun 10 07:24:04 2012	(r236838)
+++ stable/9/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h	Sun Jun 10 07:40:26 2012	(r236839)
@@ -24,7 +24,7 @@
  * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
  * Copyright (c) 2011 Pawel Jakub Dawidek <pawel@dawidek.net>.
  * All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
  * Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>. All rights reserved.
  */
@@ -237,6 +237,7 @@ typedef struct splitflags {
 extern int zpool_scan(zpool_handle_t *, pool_scan_func_t);
 extern int zpool_clear(zpool_handle_t *, const char *, nvlist_t *);
 extern int zpool_reguid(zpool_handle_t *);
+extern int zpool_reopen(zpool_handle_t *);
 
 extern int zpool_vdev_online(zpool_handle_t *, const char *, int,
     vdev_state_t *);

Modified: stable/9/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c
==============================================================================
--- stable/9/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c	Sun Jun 10 07:24:04 2012	(r236838)
+++ stable/9/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_pool.c	Sun Jun 10 07:40:26 2012	(r236839)
@@ -22,7 +22,7 @@
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  */
 
 #include <sys/types.h>
@@ -301,6 +301,7 @@ zpool_get_prop(zpool_handle_t *zhp, zpoo
 		case ZPOOL_PROP_SIZE:
 		case ZPOOL_PROP_ALLOCATED:
 		case ZPOOL_PROP_FREE:
+		case ZPOOL_PROP_EXPANDSZ:
 			(void) zfs_nicenum(intval, buf, len);
 			break;
 
@@ -390,8 +391,8 @@ pool_uses_efi(nvlist_t *config)
 	return (B_FALSE);
 }
 
-static boolean_t
-pool_is_bootable(zpool_handle_t *zhp)
+boolean_t
+zpool_is_bootable(zpool_handle_t *zhp)
 {
 	char bootfs[ZPOOL_MAXNAMELEN];
 
@@ -1126,7 +1127,7 @@ zpool_add(zpool_handle_t *zhp, nvlist_t 
 		return (zfs_error(hdl, EZFS_BADVERSION, msg));
 	}
 
-	if (pool_is_bootable(zhp) && nvlist_lookup_nvlist_array(nvroot,
+	if (zpool_is_bootable(zhp) && nvlist_lookup_nvlist_array(nvroot,
 	    ZPOOL_CONFIG_SPARES, &spares, &nspares) == 0) {
 		uint64_t s;
 
@@ -2412,7 +2413,7 @@ zpool_vdev_attach(zpool_handle_t *zhp,
 	uint_t children;
 	nvlist_t *config_root;
 	libzfs_handle_t *hdl = zhp->zpool_hdl;
-	boolean_t rootpool = pool_is_bootable(zhp);
+	boolean_t rootpool = zpool_is_bootable(zhp);
 
 	if (replacing)
 		(void) snprintf(msg, sizeof (msg), dgettext(TEXT_DOMAIN,
@@ -3054,6 +3055,26 @@ zpool_reguid(zpool_handle_t *zhp)
 }
 
 /*
+ * Reopen the pool.
+ */
+int
+zpool_reopen(zpool_handle_t *zhp)
+{
+	zfs_cmd_t zc = { 0 };
+	char msg[1024];
+	libzfs_handle_t *hdl = zhp->zpool_hdl;
+
+	(void) snprintf(msg, sizeof (msg),
+	    dgettext(TEXT_DOMAIN, "cannot reopen '%s'"),
+	    zhp->zpool_name);
+
+	(void) strlcpy(zc.zc_name, zhp->zpool_name, sizeof (zc.zc_name));
+	if (zfs_ioctl(hdl, ZFS_IOC_POOL_REOPEN, &zc) == 0)
+		return (0);
+	return (zpool_standard_error(hdl, errno, msg));
+}
+
+/*
  * Convert from a devid string to a path.
  */
 static char *
@@ -3703,7 +3724,7 @@ zpool_label_disk(libzfs_handle_t *hdl, z
 	if (zhp) {
 		nvlist_t *nvroot;
 
-		if (pool_is_bootable(zhp)) {
+		if (zpool_is_bootable(zhp)) {
 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 			    "EFI labeled devices are not supported on root "
 			    "pools."));

Modified: stable/9/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c	Sun Jun 10 07:24:04 2012	(r236838)
+++ stable/9/sys/cddl/contrib/opensolaris/common/zfs/zpool_prop.c	Sun Jun 10 07:40:26 2012	(r236839)
@@ -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) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  */
 
 #include <sys/zio.h>
@@ -81,6 +81,8 @@ zpool_prop_init(void)
 	    ZFS_TYPE_POOL, "<size>", "FREE");
 	zprop_register_number(ZPOOL_PROP_ALLOCATED, "allocated", 0,
 	    PROP_READONLY, ZFS_TYPE_POOL, "<size>", "ALLOC");
+	zprop_register_number(ZPOOL_PROP_EXPANDSZ, "expandsize", 0,
+	    PROP_READONLY, ZFS_TYPE_POOL, "<size>", "EXPANDSZ");
 	zprop_register_number(ZPOOL_PROP_CAPACITY, "capacity", 0, PROP_READONLY,
 	    ZFS_TYPE_POOL, "<size>", "CAP");
 	zprop_register_number(ZPOOL_PROP_GUID, "guid", 0, PROP_READONLY,

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c	Sun Jun 10 07:24:04 2012	(r236838)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c	Sun Jun 10 07:40:26 2012	(r236839)
@@ -21,7 +21,7 @@
 
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  */
 
 /*
@@ -175,15 +175,17 @@ spa_prop_add_list(nvlist_t *nvl, zpool_p
 static void
 spa_prop_get_config(spa_t *spa, nvlist_t **nvp)
 {
+	vdev_t *rvd = spa->spa_root_vdev;
 	uint64_t size;
 	uint64_t alloc;
+	uint64_t space;
 	uint64_t cap, version;
 	zprop_source_t src = ZPROP_SRC_NONE;
 	spa_config_dirent_t *dp;
 
 	ASSERT(MUTEX_HELD(&spa->spa_props_lock));
 
-	if (spa->spa_root_vdev != NULL) {
+	if (rvd != NULL) {
 		alloc = metaslab_class_get_alloc(spa_normal_class(spa));
 		size = metaslab_class_get_space(spa_normal_class(spa));
 		spa_prop_add_list(*nvp, ZPOOL_PROP_NAME, spa_name(spa), 0, src);
@@ -191,6 +193,15 @@ spa_prop_get_config(spa_t *spa, nvlist_t
 		spa_prop_add_list(*nvp, ZPOOL_PROP_ALLOCATED, NULL, alloc, src);
 		spa_prop_add_list(*nvp, ZPOOL_PROP_FREE, NULL,
 		    size - alloc, src);
+
+		space = 0;
+		for (int c = 0; c < rvd->vdev_children; c++) {
+			vdev_t *tvd = rvd->vdev_child[c];
+			space += tvd->vdev_max_asize - tvd->vdev_asize;
+		}
+		spa_prop_add_list(*nvp, ZPOOL_PROP_EXPANDSZ, NULL, space,
+		    src);
+
 		spa_prop_add_list(*nvp, ZPOOL_PROP_READONLY, NULL,
 		    (spa_mode(spa) == FREAD), src);
 
@@ -201,7 +212,7 @@ spa_prop_get_config(spa_t *spa, nvlist_t
 		    ddt_get_pool_dedup_ratio(spa), src);
 
 		spa_prop_add_list(*nvp, ZPOOL_PROP_HEALTH, NULL,
-		    spa->spa_root_vdev->vdev_state, src);
+		    rvd->vdev_state, src);
 
 		version = spa_version(spa);
 		if (version == zpool_prop_default_numeric(ZPOOL_PROP_VERSION))

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h	Sun Jun 10 07:24:04 2012	(r236838)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/vdev_impl.h	Sun Jun 10 07:40:26 2012	(r236839)
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  */
 
 #ifndef _SYS_VDEV_IMPL_H
@@ -55,7 +56,8 @@ typedef struct vdev_cache_entry vdev_cac
 /*
  * Virtual device operations
  */
-typedef int	vdev_open_func_t(vdev_t *vd, uint64_t *size, uint64_t *ashift);
+typedef int	vdev_open_func_t(vdev_t *vd, uint64_t *size, uint64_t *max_size,
+    uint64_t *ashift);
 typedef void	vdev_close_func_t(vdev_t *vd);
 typedef uint64_t vdev_asize_func_t(vdev_t *vd, uint64_t psize);
 typedef int	vdev_io_start_func_t(zio_t *zio);
@@ -118,6 +120,7 @@ struct vdev {
 	uint64_t	vdev_orig_guid;	/* orig. guid prior to remove	*/
 	uint64_t	vdev_asize;	/* allocatable device capacity	*/
 	uint64_t	vdev_min_asize;	/* min acceptable asize		*/
+	uint64_t	vdev_max_asize;	/* max acceptable asize		*/
 	uint64_t	vdev_ashift;	/* block alignment shift	*/
 	uint64_t	vdev_state;	/* see VDEV_STATE_* #defines	*/
 	uint64_t	vdev_prevstate;	/* used when reopening a vdev	*/

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c	Sun Jun 10 07:24:04 2012	(r236838)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c	Sun Jun 10 07:40:26 2012	(r236839)
@@ -22,7 +22,7 @@
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
- * Copyright (c) 2011 by Delphix. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  */
 
 #include <sys/zfs_context.h>
@@ -119,7 +119,7 @@ vdev_get_min_asize(vdev_t *vd)
 	vdev_t *pvd = vd->vdev_parent;
 
 	/*
-	 * The our parent is NULL (inactive spare or cache) or is the root,
+	 * If our parent is NULL (inactive spare or cache) or is the root,
 	 * just return our own asize.
 	 */
 	if (pvd == NULL)
@@ -748,6 +748,7 @@ vdev_add_parent(vdev_t *cvd, vdev_ops_t 
 
 	mvd->vdev_asize = cvd->vdev_asize;
 	mvd->vdev_min_asize = cvd->vdev_min_asize;
+	mvd->vdev_max_asize = cvd->vdev_max_asize;
 	mvd->vdev_ashift = cvd->vdev_ashift;
 	mvd->vdev_state = cvd->vdev_state;
 	mvd->vdev_crtxg = cvd->vdev_crtxg;
@@ -1119,7 +1120,8 @@ vdev_open(vdev_t *vd)
 	spa_t *spa = vd->vdev_spa;
 	int error;
 	uint64_t osize = 0;
-	uint64_t asize, psize;
+	uint64_t max_osize = 0;
+	uint64_t asize, max_asize, psize;
 	uint64_t ashift = 0;
 
 	ASSERT(vd->vdev_open_thread == curthread ||
@@ -1150,7 +1152,7 @@ vdev_open(vdev_t *vd)
 		return (ENXIO);
 	}
 
-	error = vd->vdev_ops->vdev_op_open(vd, &osize, &ashift);
+	error = vd->vdev_ops->vdev_op_open(vd, &osize, &max_osize, &ashift);
 
 	/*
 	 * Reset the vdev_reopening flag so that we actually close
@@ -1208,6 +1210,7 @@ vdev_open(vdev_t *vd)
 	}
 
 	osize = P2ALIGN(osize, (uint64_t)sizeof (vdev_label_t));
+	max_osize = P2ALIGN(max_osize, (uint64_t)sizeof (vdev_label_t));
 
 	if (vd->vdev_children == 0) {
 		if (osize < SPA_MINDEVSIZE) {
@@ -1217,6 +1220,8 @@ vdev_open(vdev_t *vd)
 		}
 		psize = osize;
 		asize = osize - (VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE);
+		max_asize = max_osize - (VDEV_LABEL_START_SIZE +
+		    VDEV_LABEL_END_SIZE);
 	} else {
 		if (vd->vdev_parent != NULL && osize < SPA_MINDEVSIZE -
 		    (VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE)) {
@@ -1226,6 +1231,7 @@ vdev_open(vdev_t *vd)
 		}
 		psize = 0;
 		asize = osize;
+		max_asize = max_osize;
 	}
 
 	vd->vdev_psize = psize;
@@ -1245,6 +1251,7 @@ vdev_open(vdev_t *vd)
 		 * For testing purposes, a higher ashift can be requested.
 		 */
 		vd->vdev_asize = asize;
+		vd->vdev_max_asize = max_asize;
 		vd->vdev_ashift = MAX(ashift, vd->vdev_ashift);
 	} else {
 		/*
@@ -1255,6 +1262,7 @@ vdev_open(vdev_t *vd)
 			    VDEV_AUX_BAD_LABEL);
 			return (EINVAL);
 		}
+		vd->vdev_max_asize = max_asize;
 	}
 
 	/*
@@ -2478,6 +2486,7 @@ vdev_get_stats(vdev_t *vd, vdev_stat_t *
 	vs->vs_rsize = vdev_get_min_asize(vd);
 	if (vd->vdev_ops->vdev_op_leaf)
 		vs->vs_rsize += VDEV_LABEL_START_SIZE + VDEV_LABEL_END_SIZE;
+	vs->vs_esize = vd->vdev_max_asize - vd->vdev_asize;
 	mutex_exit(&vd->vdev_stat_lock);
 
 	/*

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c	Sun Jun 10 07:24:04 2012	(r236838)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_disk.c	Sun Jun 10 07:40:26 2012	(r236839)
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  */
 
 #include <sys/zfs_context.h>
@@ -30,6 +31,7 @@
 #include <sys/fs/zfs.h>
 #include <sys/zio.h>
 #include <sys/sunldi.h>
+#include <sys/efi_partition.h>
 #include <sys/fm/fs/zfs.h>
 
 /*
@@ -102,8 +104,39 @@ vdev_disk_rele(vdev_t *vd)
 	}
 }
 
+static uint64_t
+vdev_disk_get_space(vdev_t *vd, uint64_t capacity, uint_t blksz)
+{
+	ASSERT(vd->vdev_wholedisk);
+
+	vdev_disk_t *dvd = vd->vdev_tsd;
+	dk_efi_t dk_ioc;
+	efi_gpt_t *efi;
+	uint64_t avail_space = 0;
+	int efisize = EFI_LABEL_SIZE * 2;
+
+	dk_ioc.dki_data = kmem_alloc(efisize, KM_SLEEP);
+	dk_ioc.dki_lba = 1;
+	dk_ioc.dki_length = efisize;
+	dk_ioc.dki_data_64 = (uint64_t)(uintptr_t)dk_ioc.dki_data;
+	efi = dk_ioc.dki_data;
+
+	if (ldi_ioctl(dvd->vd_lh, DKIOCGETEFI, (intptr_t)&dk_ioc,
+	    FKIOCTL, kcred, NULL) == 0) {
+		uint64_t efi_altern_lba = LE_64(efi->efi_gpt_AlternateLBA);
+
+		zfs_dbgmsg("vdev %s, capacity %llu, altern lba %llu",
+		    vd->vdev_path, capacity, efi_altern_lba);
+		if (capacity > efi_altern_lba)
+			avail_space = (capacity - efi_altern_lba) * blksz;
+	}
+	kmem_free(dk_ioc.dki_data, efisize);
+	return (avail_space);
+}
+
 static int
-vdev_disk_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift)
+vdev_disk_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
+    uint64_t *ashift)
 {
 	spa_t *spa = vd->vdev_spa;
 	vdev_disk_t *dvd;
@@ -274,16 +307,6 @@ skip_open:
 	}
 
 	/*
-	 * If we own the whole disk, try to enable disk write caching.
-	 * We ignore errors because it's OK if we can't do it.
-	 */
-	if (vd->vdev_wholedisk == 1) {
-		int wce = 1;
-		(void) ldi_ioctl(dvd->vd_lh, DKIOCSETWCE, (intptr_t)&wce,
-		    FKIOCTL, kcred, NULL);
-	}
-
-	/*
 	 * Determine the device's minimum transfer size.
 	 * If the ioctl isn't supported, assume DEV_BSIZE.
 	 */
@@ -293,6 +316,25 @@ skip_open:
 
 	*ashift = highbit(MAX(dkmext.dki_pbsize, SPA_MINBLOCKSIZE)) - 1;
 
+	if (vd->vdev_wholedisk == 1) {
+		uint64_t capacity = dkmext.dki_capacity - 1;
+		uint64_t blksz = dkmext.dki_lbsize;
+		int wce = 1;
+
+		/*
+		 * If we own the whole disk, try to enable disk write caching.
+		 * We ignore errors because it's OK if we can't do it.
+		 */
+		(void) ldi_ioctl(dvd->vd_lh, DKIOCSETWCE, (intptr_t)&wce,
+		    FKIOCTL, kcred, NULL);
+
+		*max_psize = *psize + vdev_disk_get_space(vd, capacity, blksz);
+		zfs_dbgmsg("capacity change: vdev %s, psize %llu, "
+		    "max_psize %llu", vd->vdev_path, *psize, *max_psize);
+	} else {
+		*max_psize = *psize;
+	}
+
 	/*
 	 * Clear the nowritecache bit, so that on a vdev_reopen() we will
 	 * try again.

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c	Sun Jun 10 07:24:04 2012	(r236838)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c	Sun Jun 10 07:40:26 2012	(r236839)
@@ -20,6 +20,7 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  */
 
 #include <sys/zfs_context.h>
@@ -47,7 +48,8 @@ vdev_file_rele(vdev_t *vd)
 }
 
 static int
-vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift)
+vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
+    uint64_t *ashift)
 {
 	vdev_file_t *vf;
 	vnode_t *vp;
@@ -125,7 +127,7 @@ skip_open:
 		return (error);
 	}
 
-	*psize = vattr.va_size;
+	*max_psize = *psize = vattr.va_size;
 	*ashift = SPA_MINBLOCKSHIFT;
 
 	return (0);

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c	Sun Jun 10 07:24:04 2012	(r236838)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c	Sun Jun 10 07:40:26 2012	(r236839)
@@ -21,6 +21,8 @@
 /*
  * Copyright (c) 2006 Pawel Jakub Dawidek <pjd@FreeBSD.org>
  * All rights reserved.
+ *
+ * Portions Copyright (c) 2012 Martin Matuska <mm@FreeBSD.org>
  */
 
 #include <sys/zfs_context.h>
@@ -405,7 +407,8 @@ vdev_geom_open_by_path(vdev_t *vd, int c
 }
 
 static int
-vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift)
+vdev_geom_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
+    uint64_t *ashift)
 {
 	struct g_provider *pp;
 	struct g_consumer *cp;
@@ -488,7 +491,7 @@ vdev_geom_open(vdev_t *vd, uint64_t *psi
 	/*
 	 * Determine the actual size of the device.
 	 */
-	*psize = pp->mediasize;
+	*max_psize = *psize = pp->mediasize;
 
 	/*
 	 * Determine the device's minimum transfer size.

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c	Sun Jun 10 07:24:04 2012	(r236838)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c	Sun Jun 10 07:40:26 2012	(r236839)
@@ -23,6 +23,10 @@
  * Use is subject to license terms.
  */
 
+/*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
 #include <sys/zfs_context.h>
 #include <sys/spa.h>
 #include <sys/vdev_impl.h>
@@ -127,7 +131,8 @@ vdev_mirror_map_alloc(zio_t *zio)
 }
 
 static int
-vdev_mirror_open(vdev_t *vd, uint64_t *asize, uint64_t *ashift)
+vdev_mirror_open(vdev_t *vd, uint64_t *asize, uint64_t *max_asize,
+    uint64_t *ashift)
 {
 	int numerrors = 0;
 	int lasterror = 0;
@@ -149,6 +154,7 @@ vdev_mirror_open(vdev_t *vd, uint64_t *a
 		}
 
 		*asize = MIN(*asize - 1, cvd->vdev_asize - 1) + 1;
+		*max_asize = MIN(*max_asize - 1, cvd->vdev_max_asize - 1) + 1;
 		*ashift = MAX(*ashift, cvd->vdev_ashift);
 	}
 

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c	Sun Jun 10 07:24:04 2012	(r236838)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c	Sun Jun 10 07:40:26 2012	(r236839)
@@ -24,6 +24,10 @@
  */
 
 /*
+ * Copyright (c) 2012 by Delphix. All rights reserved.
+ */
+
+/*
  * The 'missing' vdev is a special vdev type used only during import.  It
  * signifies a placeholder in the root vdev for some vdev that we know is
  * missing.  We pass it down to the kernel to allow the rest of the
@@ -40,7 +44,8 @@
 
 /* ARGSUSED */
 static int
-vdev_missing_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift)
+vdev_missing_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
+    uint64_t *ashift)
 {
 	/*
 	 * Really this should just fail.  But then the root vdev will be in the
@@ -49,6 +54,7 @@ vdev_missing_open(vdev_t *vd, uint64_t *
 	 * will fail the GUID sum check before ever trying to open the pool.
 	 */
 	*psize = 0;
+	*max_psize = 0;
 	*ashift = 0;
 	return (0);
 }

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c	Sun Jun 10 07:24:04 2012	(r236838)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c	Sun Jun 10 07:40:26 2012	(r236839)
@@ -21,6 +21,7 @@
 
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  */
 
 #include <sys/zfs_context.h>
@@ -1441,7 +1442,8 @@ vdev_raidz_reconstruct(raidz_map_t *rm, 
 }
 
 static int
-vdev_raidz_open(vdev_t *vd, uint64_t *asize, uint64_t *ashift)
+vdev_raidz_open(vdev_t *vd, uint64_t *asize, uint64_t *max_asize,
+    uint64_t *ashift)
 {
 	vdev_t *cvd;
 	uint64_t nparity = vd->vdev_nparity;
@@ -1469,10 +1471,12 @@ vdev_raidz_open(vdev_t *vd, uint64_t *as
 		}
 
 		*asize = MIN(*asize - 1, cvd->vdev_asize - 1) + 1;
+		*max_asize = MIN(*max_asize - 1, cvd->vdev_max_asize - 1) + 1;
 		*ashift = MAX(*ashift, cvd->vdev_ashift);
 	}
 
 	*asize *= vd->vdev_children;
+	*max_asize *= vd->vdev_children;
 
 	if (numerrors > nparity) {
 		vd->vdev_stat.vs_aux = VDEV_AUX_NO_REPLICAS;

Modified: stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_root.c
==============================================================================
--- stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_root.c	Sun Jun 10 07:24:04 2012	(r236838)
+++ stable/9/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_root.c	Sun Jun 10 07:40:26 2012	(r236839)
@@ -23,6 +23,10 @@
  * Use is subject to license terms.
  */

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206100740.q5A7eQO1080957>