changeset 3654:9c6042b08979

6483718 need a stable interface to get all native properties 6514071 recent changes to zfs.h breaks Sun Cluster
author gw25295
date Wed, 14 Feb 2007 19:54:59 -0800
parents b023d36e83d9
children bf932d11a0cb
files usr/src/cmd/zfs/zfs_main.c usr/src/common/zfs/zfs_prop.c usr/src/lib/libzfs/common/libzfs_dataset.c usr/src/lib/libzfs/common/mapfile-vers usr/src/lib/libzfs_jni/common/libzfs_jni_main.c usr/src/lib/libzfs_jni/common/libzfs_jni_property.c usr/src/uts/common/sys/fs/zfs.h
diffstat 7 files changed, 225 insertions(+), 125 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/zfs/zfs_main.c	Wed Feb 14 19:32:07 2007 -0800
+++ b/usr/src/cmd/zfs/zfs_main.c	Wed Feb 14 19:54:59 2007 -0800
@@ -239,6 +239,35 @@
 }
 
 /*
+ * Callback routinue that will print out information for each of the
+ * the properties.
+ */
+static zfs_prop_t
+usage_prop_cb(zfs_prop_t prop, void *cb)
+{
+	FILE *fp = cb;
+
+	(void) fprintf(fp, "\t%-13s  ", zfs_prop_to_name(prop));
+
+	if (zfs_prop_readonly(prop))
+		(void) fprintf(fp, "  NO    ");
+	else
+		(void) fprintf(fp, " YES    ");
+
+	if (zfs_prop_inheritable(prop))
+		(void) fprintf(fp, "  YES   ");
+	else
+		(void) fprintf(fp, "   NO   ");
+
+	if (zfs_prop_values(prop) == NULL)
+		(void) fprintf(fp, "-\n");
+	else
+		(void) fprintf(fp, "%s\n", zfs_prop_values(prop));
+
+	return (ZFS_PROP_CONT);
+}
+
+/*
  * Display usage message.  If we're inside a command, display only the usage for
  * that command.  Otherwise, iterate over the entire command table and display
  * a complete usage message.
@@ -286,24 +315,9 @@
 		(void) fprintf(fp, "\n\t%-13s  %s  %s   %s\n\n",
 		    "PROPERTY", "EDIT", "INHERIT", "VALUES");
 
-		for (i = 0; i < ZFS_NPROP_VISIBLE; i++) {
-			(void) fprintf(fp, "\t%-13s  ", zfs_prop_to_name(i));
-
-			if (zfs_prop_readonly(i))
-				(void) fprintf(fp, "  NO    ");
-			else
-				(void) fprintf(fp, " YES    ");
-
-			if (zfs_prop_inheritable(i))
-				(void) fprintf(fp, "  YES   ");
-			else
-				(void) fprintf(fp, "   NO   ");
-
-			if (zfs_prop_values(i) == NULL)
-				(void) fprintf(fp, "-\n");
-			else
-				(void) fprintf(fp, "%s\n", zfs_prop_values(i));
-		}
+		/* Iterate over all properties */
+		(void) zfs_prop_iter(usage_prop_cb, fp, B_FALSE);
+
 		(void) fprintf(fp, gettext("\nSizes are specified in bytes "
 		    "with standard units such as K, M, G, etc.\n"));
 		(void) fprintf(fp, gettext("\n\nUser-defined properties can "
--- a/usr/src/common/zfs/zfs_prop.c	Wed Feb 14 19:32:07 2007 -0800
+++ b/usr/src/common/zfs/zfs_prop.c	Wed Feb 14 19:54:59 2007 -0800
@@ -78,99 +78,108 @@
 	const char	*pd_values;
 	const char	*pd_colname;
 	boolean_t	pd_rightalign;
+	boolean_t	pd_visible;
 } prop_desc_t;
 
-static prop_desc_t zfs_prop_table[ZFS_NPROP_ALL] = {
+static prop_desc_t zfs_prop_table[] = {
 	{ "type",	prop_type_string,	0,	NULL,	prop_readonly,
-	    ZFS_TYPE_ANY, "filesystem | volume | snapshot", "TYPE", B_TRUE },
+	    ZFS_TYPE_ANY, "filesystem | volume | snapshot", "TYPE", B_TRUE,
+	    B_TRUE },
 	{ "creation",	prop_type_number,	0,	NULL,	prop_readonly,
-	    ZFS_TYPE_ANY, "<date>", "CREATION", B_FALSE },
+	    ZFS_TYPE_ANY, "<date>", "CREATION", B_FALSE, B_TRUE },
 	{ "used",	prop_type_number,	0,	NULL,	prop_readonly,
-	    ZFS_TYPE_ANY, "<size>",	"USED", B_TRUE },
+	    ZFS_TYPE_ANY, "<size>",	"USED", B_TRUE, B_TRUE },
 	{ "available",	prop_type_number,	0,	NULL,	prop_readonly,
-	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "AVAIL", B_TRUE },
+	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<size>", "AVAIL", B_TRUE,
+	    B_TRUE },
 	{ "referenced",	prop_type_number,	0,	NULL,	prop_readonly,
 	    ZFS_TYPE_ANY,
-	    "<size>", "REFER", B_TRUE },
+	    "<size>", "REFER", B_TRUE, B_TRUE },
 	{ "compressratio", prop_type_number,	0,	NULL,	prop_readonly,
-	    ZFS_TYPE_ANY, "<1.00x or higher if compressed>", "RATIO", B_TRUE },
+	    ZFS_TYPE_ANY, "<1.00x or higher if compressed>", "RATIO", B_TRUE,
+	    B_TRUE },
 	{ "mounted",	prop_type_boolean,	0,	NULL,	prop_readonly,
-	    ZFS_TYPE_FILESYSTEM, "yes | no | -", "MOUNTED", B_TRUE },
+	    ZFS_TYPE_FILESYSTEM, "yes | no | -", "MOUNTED", B_TRUE, B_TRUE },
 	{ "origin",	prop_type_string,	0,	NULL,	prop_readonly,
 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "<snapshot>", "ORIGIN",
-	    B_FALSE },
+	    B_FALSE, B_TRUE },
 	{ "quota",	prop_type_number,	0,	NULL,	prop_default,
-	    ZFS_TYPE_FILESYSTEM, "<size> | none", "QUOTA", B_TRUE },
+	    ZFS_TYPE_FILESYSTEM, "<size> | none", "QUOTA", B_TRUE, B_TRUE },
 	{ "reservation", prop_type_number,	0,	NULL,	prop_default,
 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
-	    "<size> | none", "RESERV", B_TRUE },
+	    "<size> | none", "RESERV", B_TRUE, B_TRUE },
 	{ "volsize",	prop_type_number,	0,	NULL,	prop_default,
-	    ZFS_TYPE_VOLUME, "<size>", "VOLSIZE", B_TRUE },
+	    ZFS_TYPE_VOLUME, "<size>", "VOLSIZE", B_TRUE, B_TRUE },
 	{ "volblocksize", prop_type_number,	8192,	NULL,	prop_readonly,
-	    ZFS_TYPE_VOLUME, "512 to 128k, power of 2",	"VOLBLOCK", B_TRUE },
+	    ZFS_TYPE_VOLUME, "512 to 128k, power of 2",	"VOLBLOCK", B_TRUE,
+	    B_TRUE },
 	{ "recordsize",	prop_type_number,	SPA_MAXBLOCKSIZE,	NULL,
 	    prop_inherit,
 	    ZFS_TYPE_FILESYSTEM,
-	    "512 to 128k, power of 2", "RECSIZE", B_TRUE },
+	    "512 to 128k, power of 2", "RECSIZE", B_TRUE, B_TRUE },
 	{ "mountpoint",	prop_type_string,	0,	"/",	prop_inherit,
 	    ZFS_TYPE_FILESYSTEM,
-	    "<path> | legacy | none", "MOUNTPOINT", B_FALSE },
+	    "<path> | legacy | none", "MOUNTPOINT", B_FALSE, B_TRUE },
 	{ "sharenfs",	prop_type_string,	0,	"off",	prop_inherit,
 	    ZFS_TYPE_FILESYSTEM,
-	    "on | off | share(1M) options", "SHARENFS", B_FALSE },
-	{ "shareiscsi",	prop_type_string,	0,	"off",	prop_inherit,
-	    ZFS_TYPE_ANY,
-	    "on | off | type=<type>", "SHAREISCSI", B_FALSE },
+	    "on | off | share(1M) options", "SHARENFS", B_FALSE, B_TRUE },
 	{ "checksum",	prop_type_index,	ZIO_CHECKSUM_DEFAULT,	"on",
 	    prop_inherit,	ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
-	    "on | off | fletcher2 | fletcher4 | sha256", "CHECKSUM", B_TRUE },
+	    "on | off | fletcher2 | fletcher4 | sha256", "CHECKSUM", B_TRUE,
+	    B_TRUE },
 	{ "compression", prop_type_index,	ZIO_COMPRESS_DEFAULT,	"off",
 	    prop_inherit,	ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
-	    "on | off | lzjb", "COMPRESS", B_TRUE },
+	    "on | off | lzjb", "COMPRESS", B_TRUE, B_TRUE },
 	{ "atime",	prop_type_boolean,	1,	NULL,	prop_inherit,
 	    ZFS_TYPE_FILESYSTEM,
-	    "on | off", "ATIME", B_TRUE },
+	    "on | off", "ATIME", B_TRUE, B_TRUE },
 	{ "devices",	prop_type_boolean,	1,	NULL,	prop_inherit,
 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
-	    "on | off", "DEVICES", B_TRUE },
+	    "on | off", "DEVICES", B_TRUE, B_TRUE },
 	{ "exec",	prop_type_boolean,	1,	NULL,	prop_inherit,
 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
-	    "on | off", "EXEC", B_TRUE },
+	    "on | off", "EXEC", B_TRUE, B_TRUE },
 	{ "setuid",	prop_type_boolean,	1,	NULL,	prop_inherit,
 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT, "on | off", "SETUID",
-	    B_TRUE },
+	    B_TRUE, B_TRUE },
 	{ "readonly",	prop_type_boolean,	0,	NULL,	prop_inherit,
 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME,
-	    "on | off", "RDONLY", B_TRUE },
+	    "on | off", "RDONLY", B_TRUE, B_TRUE },
 	{ "zoned",	prop_type_boolean,	0,	NULL,	prop_inherit,
 	    ZFS_TYPE_FILESYSTEM,
-	    "on | off", "ZONED", B_TRUE },
+	    "on | off", "ZONED", B_TRUE, B_TRUE },
 	{ "snapdir",	prop_type_index,	ZFS_SNAPDIR_HIDDEN, "hidden",
 	    prop_inherit,
 	    ZFS_TYPE_FILESYSTEM,
-	    "hidden | visible", "SNAPDIR", B_TRUE },
+	    "hidden | visible", "SNAPDIR", B_TRUE, B_TRUE },
 	{ "aclmode", prop_type_index,	ZFS_ACL_GROUPMASK, "groupmask",
 	    prop_inherit, ZFS_TYPE_FILESYSTEM,
-	    "discard | groupmask | passthrough", "ACLMODE", B_TRUE },
+	    "discard | groupmask | passthrough", "ACLMODE", B_TRUE, B_TRUE },
 	{ "aclinherit", prop_type_index,	ZFS_ACL_SECURE,	"secure",
 	    prop_inherit, ZFS_TYPE_FILESYSTEM,
-	    "discard | noallow | secure | passthrough", "ACLINHERIT", B_TRUE },
+	    "discard | noallow | secure | passthrough", "ACLINHERIT", B_TRUE,
+	    B_TRUE },
+	{ "createtxg",	prop_type_number,	0,	NULL,	prop_readonly,
+	    ZFS_TYPE_ANY, NULL, NULL, B_FALSE, B_FALSE },
+	{ "name",	prop_type_string,	0,	NULL,	prop_readonly,
+	    ZFS_TYPE_ANY, NULL, "NAME", B_FALSE, B_FALSE },
 	{ "canmount",	prop_type_boolean,	1,	NULL,	prop_default,
 	    ZFS_TYPE_FILESYSTEM,
-	    "on | off", "CANMOUNT", B_TRUE },
+	    "on | off", "CANMOUNT", B_TRUE, B_TRUE },
+	{ "shareiscsi",	prop_type_string,	0,	"off",	prop_inherit,
+	    ZFS_TYPE_ANY,
+	    "on | off | type=<type>", "SHAREISCSI", B_FALSE, B_TRUE },
+	{ "iscsioptions", prop_type_string,	0,	NULL,	prop_inherit,
+	    ZFS_TYPE_VOLUME, NULL, "ISCSIOPTIONS", B_FALSE, B_FALSE },
 	{ "xattr",	prop_type_boolean,	1,	NULL,	prop_inherit,
 	    ZFS_TYPE_FILESYSTEM | ZFS_TYPE_SNAPSHOT,
-	    "on | off", "XATTR", B_TRUE },
-	{ "createtxg",	prop_type_number,	0,	NULL,	prop_readonly,
-	    ZFS_TYPE_ANY, NULL, NULL, B_FALSE},
-	{ "name",	prop_type_string,	0,	NULL,	prop_readonly,
-	    ZFS_TYPE_ANY, NULL, "NAME", B_FALSE },
-	{ "iscsioptions", prop_type_string,	0,	NULL,	prop_inherit,
-	    ZFS_TYPE_VOLUME, NULL, "ISCSIOPTIONS", B_FALSE },
+	    "on | off", "XATTR", B_TRUE, B_TRUE },
 	{ "numclones", prop_type_number,	0,	NULL,	prop_readonly,
-	    ZFS_TYPE_SNAPSHOT, NULL, NULL, B_FALSE },
+	    ZFS_TYPE_SNAPSHOT, NULL, NULL, B_FALSE, B_FALSE },
 };
 
+#define	ZFS_PROP_COUNT	((sizeof (zfs_prop_table))/(sizeof (prop_desc_t)))
+
 zfs_proptype_t
 zfs_prop_get_type(zfs_prop_t prop)
 {
@@ -209,6 +218,16 @@
 #endif
 }
 
+zfs_prop_t
+zfs_name_to_prop_cb(zfs_prop_t prop, void *cb_data)
+{
+	const char *propname = cb_data;
+
+	if (propname_match(propname, prop, strlen(propname)))
+		return (prop);
+
+	return (ZFS_PROP_CONT);
+}
 
 /*
  * Given a property name, returns the corresponding property ID.
@@ -216,14 +235,10 @@
 zfs_prop_t
 zfs_name_to_prop(const char *propname)
 {
-	int i;
+	zfs_prop_t prop;
 
-	for (i = 0; i < ZFS_NPROP_ALL; i++) {
-		if (propname_match(propname, i, strlen(propname)))
-			return (i);
-	}
-
-	return (ZFS_PROP_INVAL);
+	prop = zfs_prop_iter(zfs_name_to_prop_cb, (void *)propname, B_TRUE);
+	return (prop == ZFS_PROP_CONT ? ZFS_PROP_INVAL : prop);
 }
 
 /*
@@ -408,6 +423,38 @@
 	return (-1);
 }
 
+/*
+ * Determine if the specified property is visible or not.
+ */
+boolean_t
+zfs_prop_is_visible(zfs_prop_t prop)
+{
+	if (prop < 0)
+		return (B_FALSE);
+
+	return (zfs_prop_table[prop].pd_visible);
+}
+
+/*
+ * Iterate over all properties, calling back into the specified function
+ * for each property. We will continue to iterate until we either
+ * reach the end or the callback function something other than
+ * ZFS_PROP_CONT.
+ */
+zfs_prop_t
+zfs_prop_iter(zfs_prop_f func, void *cb, boolean_t show_all)
+{
+	int i;
+
+	for (i = 0; i < ZFS_PROP_COUNT; i++) {
+		if (zfs_prop_is_visible(i) || show_all) {
+			if (func(i, cb) != ZFS_PROP_CONT)
+				return (i);
+		}
+	}
+	return (ZFS_PROP_CONT);
+}
+
 #ifndef _KERNEL
 
 /*
--- a/usr/src/lib/libzfs/common/libzfs_dataset.c	Wed Feb 14 19:32:07 2007 -0800
+++ b/usr/src/lib/libzfs/common/libzfs_dataset.c	Wed Feb 14 19:54:59 2007 -0800
@@ -3347,7 +3347,6 @@
 int
 zfs_get_proplist(libzfs_handle_t *hdl, char *fields, zfs_proplist_t **listp)
 {
-	int i;
 	size_t len;
 	char *s, *p;
 	char c;
@@ -3402,16 +3401,13 @@
 		 */
 		c = s[len];
 		s[len] = '\0';
-		for (i = 0; i < ZFS_NPROP_ALL; i++) {
-			if ((prop = zfs_name_to_prop(s)) != ZFS_PROP_INVAL)
-				break;
-		}
+		prop = zfs_name_to_prop(s);
 
 		/*
 		 * If no column is specified, and this isn't a user property,
 		 * return failure.
 		 */
-		if (i == ZFS_NPROP_ALL && !zfs_prop_user(s)) {
+		if (prop == ZFS_PROP_INVAL && !zfs_prop_user(s)) {
 			zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
 			    "invalid property '%s'"), s);
 			return (zfs_error(hdl, EZFS_BADPROP,
@@ -3458,6 +3454,30 @@
 	}
 }
 
+typedef struct expand_data {
+	zfs_proplist_t	**last;
+	libzfs_handle_t	*hdl;
+} expand_data_t;
+
+static zfs_prop_t
+zfs_expand_proplist_cb(zfs_prop_t prop, void *cb)
+{
+	zfs_proplist_t *entry;
+	expand_data_t *edp = cb;
+
+	if ((entry = zfs_alloc(edp->hdl, sizeof (zfs_proplist_t))) == NULL)
+		return (ZFS_PROP_INVAL);
+
+	entry->pl_prop = prop;
+	entry->pl_width = zfs_prop_width(prop, &entry->pl_fixed);
+	entry->pl_all = B_TRUE;
+
+	*(edp->last) = entry;
+	edp->last = &entry->pl_next;
+
+	return (ZFS_PROP_CONT);
+}
+
 /*
  * This function is used by 'zfs list' to determine the exact set of columns to
  * display, and their maximum widths.  This does two main things:
@@ -3473,13 +3493,13 @@
 zfs_expand_proplist(zfs_handle_t *zhp, zfs_proplist_t **plp)
 {
 	libzfs_handle_t *hdl = zhp->zfs_hdl;
-	zfs_prop_t prop;
 	zfs_proplist_t *entry;
 	zfs_proplist_t **last, **start;
 	nvlist_t *userprops, *propval;
 	nvpair_t *elem;
 	char *strval;
 	char buf[ZFS_MAXPROPLEN];
+	expand_data_t exp;
 
 	if (*plp == NULL) {
 		/*
@@ -3488,19 +3508,13 @@
 		 * properties.
 		 */
 		last = plp;
-		for (prop = 0; prop < ZFS_NPROP_VISIBLE; prop++) {
-			if ((entry = zfs_alloc(hdl,
-			    sizeof (zfs_proplist_t))) == NULL)
-				return (-1);
-
-			entry->pl_prop = prop;
-			entry->pl_width = zfs_prop_width(prop,
-			    &entry->pl_fixed);
-			entry->pl_all = B_TRUE;
-
-			*last = entry;
-			last = &entry->pl_next;
-		}
+
+		exp.last = last;
+		exp.hdl = hdl;
+
+		if (zfs_prop_iter(zfs_expand_proplist_cb, &exp,
+		    B_FALSE) == ZFS_PROP_INVAL)
+			return (-1);
 
 		/*
 		 * Add 'name' to the beginning of the list, which is handled
--- a/usr/src/lib/libzfs/common/mapfile-vers	Wed Feb 14 19:32:07 2007 -0800
+++ b/usr/src/lib/libzfs/common/mapfile-vers	Wed Feb 14 19:54:59 2007 -0800
@@ -72,6 +72,7 @@
 	zfs_prop_inherit;
 	zfs_prop_inheritable;
 	zfs_prop_is_string;
+	zfs_prop_iter;
 	zfs_prop_readonly;
 	zfs_prop_set;
 	zfs_prop_to_name;
--- a/usr/src/lib/libzfs_jni/common/libzfs_jni_main.c	Wed Feb 14 19:32:07 2007 -0800
+++ b/usr/src/lib/libzfs_jni/common/libzfs_jni_main.c	Wed Feb 14 19:54:59 2007 -0800
@@ -20,7 +20,7 @@
  */
 
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -499,6 +499,30 @@
 	zfs_type_t type;
 } zjni_class_type_map_t;
 
+typedef struct mapping_data {
+	JNIEnv			*env;
+	zfs_type_t		type;
+	zjni_ArrayList_t	*list;
+} mapping_data_t;
+
+static zfs_prop_t
+mapping_cb(zfs_prop_t prop, void *cb)
+{
+	mapping_data_t *map = cb;
+	JNIEnv *env = map->env;
+	zjni_ArrayList_t *list = map->list;
+
+	if (zfs_prop_valid_for_type(prop, map->type)) {
+		/* Add name of property to list */
+		jstring propName = (*env)->NewStringUTF(env,
+		    zfs_prop_to_name(prop));
+		(*env)->CallBooleanMethod(env, ((zjni_Object_t *)list)->object,
+		    ((zjni_Collection_t *)list)->method_add, propName);
+	}
+
+	return (ZFS_PROP_CONT);
+}
+
 /*
  * Class:     com_sun_zfs_common_model_SystemDataModel
  * Method:    getValidPropertyNames
@@ -541,21 +565,12 @@
 		    env, typeClass, isAssignableFrom, class);
 
 		if (isInstance == JNI_TRUE) {
-			zfs_prop_t prop;
-			for (prop = 0; prop < ZFS_NPROP_VISIBLE; prop++) {
-				if (zfs_prop_valid_for_type(prop,
-				    mappings[i].type)) {
-					/* Add name of property to list */
-					jstring propName =
-					    (*env)->NewStringUTF(env,
-						zfs_prop_to_name(prop));
-					(*env)->CallBooleanMethod(
-					    env,
-					    ((zjni_Object_t *)list)->object,
-					    ((zjni_Collection_t *)list)->
-					    method_add, propName);
-				}
-			}
+			mapping_data_t map_data;
+
+			map_data.env = env;
+			map_data.type = mappings[i].type;
+			map_data.list = list;
+			(void) zfs_prop_iter(mapping_cb, &map_data, B_FALSE);
 			break;
 		}
 	}
--- a/usr/src/lib/libzfs_jni/common/libzfs_jni_property.c	Wed Feb 14 19:32:07 2007 -0800
+++ b/usr/src/lib/libzfs_jni/common/libzfs_jni_property.c	Wed Feb 14 19:54:59 2007 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * 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.
@@ -20,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -531,17 +530,25 @@
 	return (NULL);
 }
 
+static zfs_prop_t
+zjni_get_property_from_name_cb(zfs_prop_t prop, void *cb)
+{
+	const char *name = cb;
+
+	if (strcasecmp(name, zfs_prop_to_name(prop)) == 0)
+		return (prop);
+
+	return (ZFS_PROP_CONT);
+}
+
 zfs_prop_t
 zjni_get_property_from_name(const char *name)
 {
 	zfs_prop_t prop;
-	for (prop = 0; prop < ZFS_NPROP_VISIBLE; prop++) {
-		if (strcasecmp(name, zfs_prop_to_name(prop)) == 0) {
-			return (prop);
-		}
-	}
 
-	return (ZFS_PROP_INVAL);
+	prop = zfs_prop_iter(zjni_get_property_from_name_cb, (void *)name,
+	    B_FALSE);
+	return (prop == ZFS_PROP_CONT ? ZFS_PROP_INVAL : prop);
 }
 
 jobject
--- a/usr/src/uts/common/sys/fs/zfs.h	Wed Feb 14 19:32:07 2007 -0800
+++ b/usr/src/uts/common/sys/fs/zfs.h	Wed Feb 14 19:54:59 2007 -0800
@@ -52,11 +52,14 @@
 	(ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME | ZFS_TYPE_SNAPSHOT)
 
 /*
- * Properties are identified by these constants.  They are arranged in order of
- * how they should be displayed by 'zfs get'.  If you make any changes to this
- * list, be sure to update the property table in usr/src/common/zfs/zfs_prop.c.
+ * Properties are identified by these constants and must be added to the
+ * end of this list to ensure that external conumsers are not affected
+ * by the change. The property list also determines how 'zfs get' will
+ * display them.  If you make any changes to this list, be sure to update
+ * the property table in usr/src/common/zfs/zfs_prop.c.
  */
 typedef enum {
+	ZFS_PROP_CONT = -2,
 	ZFS_PROP_INVAL = -1,
 	ZFS_PROP_TYPE,
 	ZFS_PROP_CREATION,
@@ -73,7 +76,6 @@
 	ZFS_PROP_RECORDSIZE,
 	ZFS_PROP_MOUNTPOINT,
 	ZFS_PROP_SHARENFS,
-	ZFS_PROP_SHAREISCSI,
 	ZFS_PROP_CHECKSUM,
 	ZFS_PROP_COMPRESSION,
 	ZFS_PROP_ATIME,
@@ -85,21 +87,15 @@
 	ZFS_PROP_SNAPDIR,
 	ZFS_PROP_ACLMODE,
 	ZFS_PROP_ACLINHERIT,
+	ZFS_PROP_CREATETXG,		/* not exposed to the user */
+	ZFS_PROP_NAME,			/* not exposed to the user */
 	ZFS_PROP_CANMOUNT,
+	ZFS_PROP_SHAREISCSI,
+	ZFS_PROP_ISCSIOPTIONS,		/* not exposed to the user */
 	ZFS_PROP_XATTR,
-	/*
-	 * The following properties are not exposed to the user, but are
-	 * accessible by libzfs clients.
-	 */
-	ZFS_PROP_CREATETXG,
-	ZFS_PROP_NAME,
-	ZFS_PROP_ISCSIOPTIONS,
-	ZFS_PROP_NUMCLONES,
-	ZFS_NPROP_ALL
+	ZFS_PROP_NUMCLONES		/* not exposed to the user */
 } zfs_prop_t;
 
-#define	ZFS_NPROP_VISIBLE	ZFS_PROP_CREATETXG
-
 #define	ZFS_PROP_VALUE		"value"
 #define	ZFS_PROP_SOURCE		"source"
 
@@ -117,6 +113,12 @@
 int zfs_prop_index_to_string(zfs_prop_t, uint64_t, const char **);
 
 /*
+ * Property Iterator
+ */
+typedef zfs_prop_t (*zfs_prop_f)(zfs_prop_t, void *);
+extern zfs_prop_t zfs_prop_iter(zfs_prop_f, void *, boolean_t);
+
+/*
  * On-disk version number.
  */
 #define	ZFS_VERSION_1			1ULL