From b6265ad99f3435137504d78fe7b6d398b0705cfd Mon Sep 17 00:00:00 2001 From: delphij Date: Tue, 16 Mar 2010 00:48:27 +0000 Subject: [PATCH] Merge OpenSolaris revision 8802:010b31dd4c53: 6773366 "zfs list" memory consumption can be further reduced PR: bin/144720 Submitted by: mm Approved by: pjd Obtained from: OpenSolaris MFC after: 1 month --- cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c | 55 +++++++++++++++++-- .../opensolaris/lib/libzfs/common/libzfs.h | 1 + .../lib/libzfs/common/libzfs_dataset.c | 30 +++++++++- .../lib/libzfs/common/libzfs_impl.h | 3 +- 4 files changed, 81 insertions(+), 8 deletions(-) diff --git a/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c index a22370a02795..e5149cbb9ef0 100644 --- a/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c +++ b/cddl/contrib/opensolaris/cmd/zfs/zfs_iter.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -58,6 +58,7 @@ typedef struct callback_data { zfs_type_t cb_types; zfs_sort_column_t *cb_sortcol; zprop_list_t **cb_proplist; + uint8_t cb_props_table[ZFS_NUM_PROPS]; } callback_data_t; uu_avl_pool_t *avl_pool; @@ -98,11 +99,20 @@ zfs_callback(zfs_handle_t *zhp, void *data) uu_avl_node_init(node, &node->zn_avlnode, avl_pool); if (uu_avl_find(cb->cb_avl, node, cb->cb_sortcol, &idx) == NULL) { - if (cb->cb_proplist && - zfs_expand_proplist(zhp, cb->cb_proplist) != 0) { - free(node); - return (-1); + + if (cb->cb_proplist) { + if ((*cb->cb_proplist) && + !(*cb->cb_proplist)->pl_all) + zfs_prune_proplist(zhp, + cb->cb_props_table); + + if (zfs_expand_proplist(zhp, cb->cb_proplist) + != 0) { + free(node); + return (-1); + } } + uu_avl_insert(cb->cb_avl, node, idx); dontclose = 1; } else { @@ -328,7 +338,7 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types, zfs_sort_column_t *sortcol, zprop_list_t **proplist, zfs_iter_f callback, void *data) { - callback_data_t cb; + callback_data_t cb = {0}; int ret = 0; zfs_node_t *node; uu_avl_walk_t *walk; @@ -346,6 +356,39 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types, cb.cb_flags = flags; cb.cb_proplist = proplist; cb.cb_types = types; + + /* + * If cb_proplist is provided then in the zfs_handles created we + * retain only those properties listed in cb_proplist and sortcol. + * The rest are pruned. So, the caller should make sure that no other + * properties other than those listed in cb_proplist/sortcol are + * accessed. + * + * If cb_proplist is NULL then we retain all the properties. + */ + if (cb.cb_proplist && *cb.cb_proplist) { + zprop_list_t *p = *cb.cb_proplist; + + while (p) { + if (p->pl_prop >= ZFS_PROP_TYPE && + p->pl_prop < ZFS_NUM_PROPS) { + cb.cb_props_table[p->pl_prop] = B_TRUE; + } + p = p->pl_next; + } + + while (sortcol) { + if (sortcol->sc_prop >= ZFS_PROP_TYPE && + sortcol->sc_prop < ZFS_NUM_PROPS) { + cb.cb_props_table[sortcol->sc_prop] = B_TRUE; + } + sortcol = sortcol->sc_next; + } + } else { + (void) memset(cb.cb_props_table, B_TRUE, + sizeof (cb.cb_props_table)); + } + if ((cb.cb_avl = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL) { (void) fprintf(stderr, gettext("internal error: out of memory\n")); diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h index 9a13bbbf5422..a959494cd52e 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs.h @@ -369,6 +369,7 @@ typedef struct zprop_list { } zprop_list_t; extern int zfs_expand_proplist(zfs_handle_t *, zprop_list_t **); +extern void zfs_prune_proplist(zfs_handle_t *, uint8_t *); #define ZFS_MOUNTPOINT_NONE "none" #define ZFS_MOUNTPOINT_LEGACY "legacy" diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c index f3b132f1fc85..51adc40d1784 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_dataset.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -2045,6 +2045,8 @@ getprop_uint64(zfs_handle_t *zhp, zfs_prop_t prop, char **source) verify(nvlist_lookup_uint64(nv, ZPROP_VALUE, &value) == 0); (void) nvlist_lookup_string(nv, ZPROP_SOURCE, source); } else { + verify(!zhp->zfs_props_table || + zhp->zfs_props_table[prop] == B_TRUE); value = zfs_prop_default_numeric(prop); *source = ""; } @@ -2064,6 +2066,8 @@ getprop_string(zfs_handle_t *zhp, zfs_prop_t prop, char **source) verify(nvlist_lookup_string(nv, ZPROP_VALUE, &value) == 0); (void) nvlist_lookup_string(nv, ZPROP_SOURCE, source); } else { + verify(!zhp->zfs_props_table || + zhp->zfs_props_table[prop] == B_TRUE); if ((value = (char *)zfs_prop_default_string(prop)) == NULL) value = ""; *source = ""; @@ -4267,6 +4271,30 @@ zfs_deleg_share_nfs(libzfs_handle_t *hdl, char *dataset, char *path, return (error); } +void +zfs_prune_proplist(zfs_handle_t *zhp, uint8_t *props) +{ + nvpair_t *curr; + + /* + * Keep a reference to the props-table against which we prune the + * properties. + */ + zhp->zfs_props_table = props; + + curr = nvlist_next_nvpair(zhp->zfs_props, NULL); + + while (curr) { + zfs_prop_t zfs_prop = zfs_name_to_prop(nvpair_name(curr)); + nvpair_t *next = nvlist_next_nvpair(zhp->zfs_props, curr); + + if (props[zfs_prop] == B_FALSE) + (void) nvlist_remove(zhp->zfs_props, + nvpair_name(curr), nvpair_type(curr)); + curr = next; + } +} + /* * Attach/detach the given filesystem to/from the given jail. */ diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h index afe71f399481..c0e47e905f92 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_impl.h @@ -20,7 +20,7 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -77,6 +77,7 @@ struct zfs_handle { nvlist_t *zfs_user_props; boolean_t zfs_mntcheck; char *zfs_mntopts; + uint8_t *zfs_props_table; }; /*