Remove libumem, we will try and remove this dependency entirely. If we can't then...
[zfs.git] / zfs / zcmd / zfs / zfs_iter.c
index 9e39338..a22370a 100644 (file)
  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
-#pragma ident  "@(#)zfs_iter.c 1.8     07/10/29 SMI"
-
 #include <libintl.h>
 #include <libuutil.h>
 #include <stddef.h>
@@ -56,7 +54,7 @@ typedef struct zfs_node {
 
 typedef struct callback_data {
        uu_avl_t        *cb_avl;
-       int             cb_recurse;
+       int             cb_flags;
        zfs_type_t      cb_types;
        zfs_sort_column_t *cb_sortcol;
        zprop_list_t    **cb_proplist;
@@ -65,7 +63,23 @@ typedef struct callback_data {
 uu_avl_pool_t *avl_pool;
 
 /*
- * Called for each dataset.  If the object the object is of an appropriate type,
+ * Include snaps if they were requested or if this a zfs list where types
+ * were not specified and the "listsnapshots" property is set on this pool.
+ */
+static int
+zfs_include_snapshots(zfs_handle_t *zhp, callback_data_t *cb)
+{
+       zpool_handle_t *zph;
+
+       if ((cb->cb_flags & ZFS_ITER_PROP_LISTSNAPS) == 0)
+               return (cb->cb_types & ZFS_TYPE_SNAPSHOT);
+
+       zph = zfs_get_pool_handle(zhp);
+       return (zpool_get_prop_int(zph, ZPOOL_PROP_LISTSNAPS, NULL));
+}
+
+/*
+ * Called for each dataset.  If the object is of an appropriate type,
  * add it to the avl tree and recurse over any children as necessary.
  */
 static int
@@ -73,11 +87,10 @@ zfs_callback(zfs_handle_t *zhp, void *data)
 {
        callback_data_t *cb = data;
        int dontclose = 0;
+       int include_snaps = zfs_include_snapshots(zhp, cb);
 
-       /*
-        * If this object is of the appropriate type, add it to the AVL tree.
-        */
-       if (zfs_get_type(zhp) & cb->cb_types) {
+       if ((zfs_get_type(zhp) & cb->cb_types) ||
+           ((zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT) && include_snaps)) {
                uu_avl_index_t idx;
                zfs_node_t *node = safe_malloc(sizeof (zfs_node_t));
 
@@ -100,11 +113,10 @@ zfs_callback(zfs_handle_t *zhp, void *data)
        /*
         * Recurse if necessary.
         */
-       if (cb->cb_recurse) {
+       if (cb->cb_flags & ZFS_ITER_RECURSE) {
                if (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM)
                        (void) zfs_iter_filesystems(zhp, zfs_callback, data);
-               if (zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT &&
-                   (cb->cb_types & ZFS_TYPE_SNAPSHOT))
+               if ((zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT) && include_snaps)
                        (void) zfs_iter_snapshots(zhp, zfs_callback, data);
        }
 
@@ -296,7 +308,7 @@ zfs_sort(const void *larg, const void *rarg, void *data)
 
                if (lstr)
                        ret = strcmp(lstr, rstr);
-               if (lnum < rnum)
+               else if (lnum < rnum)
                        ret = -1;
                else if (lnum > rnum)
                        ret = 1;
@@ -312,9 +324,9 @@ zfs_sort(const void *larg, const void *rarg, void *data)
 }
 
 int
-zfs_for_each(int argc, char **argv, boolean_t recurse, zfs_type_t types,
-    zfs_sort_column_t *sortcol, zprop_list_t **proplist, zfs_iter_f callback,
-    void *data, boolean_t args_can_be_paths)
+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;
        int ret = 0;
@@ -331,7 +343,7 @@ zfs_for_each(int argc, char **argv, boolean_t recurse, zfs_type_t types,
        }
 
        cb.cb_sortcol = sortcol;
-       cb.cb_recurse = recurse;
+       cb.cb_flags = flags;
        cb.cb_proplist = proplist;
        cb.cb_types = types;
        if ((cb.cb_avl = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL) {
@@ -344,7 +356,7 @@ zfs_for_each(int argc, char **argv, boolean_t recurse, zfs_type_t types,
                /*
                 * If given no arguments, iterate over all datasets.
                 */
-               cb.cb_recurse = 1;
+               cb.cb_flags |= ZFS_ITER_RECURSE;
                ret = zfs_iter_root(g_zfs, zfs_callback, &cb);
        } else {
                int i;
@@ -357,14 +369,14 @@ zfs_for_each(int argc, char **argv, boolean_t recurse, zfs_type_t types,
                 * can take volumes as well.
                 */
                argtype = types;
-               if (recurse) {
+               if (flags & ZFS_ITER_RECURSE) {
                        argtype |= ZFS_TYPE_FILESYSTEM;
                        if (types & ZFS_TYPE_SNAPSHOT)
                                argtype |= ZFS_TYPE_VOLUME;
                }
 
                for (i = 0; i < argc; i++) {
-                       if (args_can_be_paths) {
+                       if (flags & ZFS_ITER_ARGS_CAN_BE_PATHS) {
                                zhp = zfs_path_to_zhandle(g_zfs, argv[i],
                                    argtype);
                        } else {