Illumos #3122 zfs destroy filesystem should prefetch blocks
[zfs.git] / cmd / zfs / zfs_iter.c
index 04dd2bd..6239a8f 100644 (file)
@@ -19,8 +19,8 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
  */
 
 #include <libintl.h>
@@ -107,7 +107,8 @@ zfs_callback(zfs_handle_t *zhp, void *data)
                                        zfs_prune_proplist(zhp,
                                            cb->cb_props_table);
 
-                               if (zfs_expand_proplist(zhp, cb->cb_proplist)
+                               if (zfs_expand_proplist(zhp, cb->cb_proplist,
+                                   (cb->cb_flags & ZFS_ITER_RECVD_PROPS))
                                    != 0) {
                                        free(node);
                                        return (-1);
@@ -129,8 +130,11 @@ zfs_callback(zfs_handle_t *zhp, void *data)
                cb->cb_depth++;
                if (zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM)
                        (void) zfs_iter_filesystems(zhp, zfs_callback, data);
-               if ((zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT) && include_snaps)
-                       (void) zfs_iter_snapshots(zhp, zfs_callback, data);
+               if ((zfs_get_type(zhp) != ZFS_TYPE_SNAPSHOT) && include_snaps) {
+                       (void) zfs_iter_snapshots(zhp,
+                           (cb->cb_flags & ZFS_ITER_SIMPLE) != 0, zfs_callback,
+                           data);
+               }
                cb->cb_depth--;
        }
 
@@ -184,6 +188,13 @@ zfs_free_sort_columns(zfs_sort_column_t *sc)
        }
 }
 
+int
+zfs_sort_only_by_name(const zfs_sort_column_t *sc)
+{
+       return (sc != NULL && sc->sc_next == NULL &&
+           sc->sc_prop == ZFS_PROP_NAME);
+}
+
 /* ARGSUSED */
 static int
 zfs_compare(const void *larg, const void *rarg, void *unused)
@@ -224,7 +235,13 @@ zfs_compare(const void *larg, const void *rarg, void *unused)
                        lcreate = zfs_prop_get_int(l, ZFS_PROP_CREATETXG);
                        rcreate = zfs_prop_get_int(r, ZFS_PROP_CREATETXG);
 
-                       if (lcreate < rcreate)
+                       /*
+                        * Both lcreate and rcreate being 0 means we don't have
+                        * properties and we should compare full name.
+                        */
+                       if (lcreate == 0 && rcreate == 0)
+                               ret = strcmp(lat + 1, rat + 1);
+                       else if (lcreate < rcreate)
                                ret = -1;
                        else if (lcreate > rcreate)
                                ret = 1;
@@ -290,7 +307,14 @@ zfs_sort(const void *larg, const void *rarg, void *data)
                        if (rvalid)
                                verify(nvlist_lookup_string(rval,
                                    ZPROP_VALUE, &rstr) == 0);
+               } else if (psc->sc_prop == ZFS_PROP_NAME) {
+                       lvalid = rvalid = B_TRUE;
 
+                       (void) strlcpy(lbuf, zfs_get_name(l), sizeof(lbuf));
+                       (void) strlcpy(rbuf, zfs_get_name(r), sizeof(rbuf));
+
+                       lstr = lbuf;
+                       rstr = rbuf;
                } else if (zfs_prop_is_string(psc->sc_prop)) {
                        lvalid = (zfs_prop_get(l, psc->sc_prop, lbuf,
                            sizeof (lbuf), NULL, NULL, 0, B_TRUE) == 0);
@@ -350,11 +374,8 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
        avl_pool = uu_avl_pool_create("zfs_pool", sizeof (zfs_node_t),
            offsetof(zfs_node_t, zn_avlnode), zfs_sort, UU_DEFAULT);
 
-       if (avl_pool == NULL) {
-               (void) fprintf(stderr,
-                   gettext("internal error: out of memory\n"));
-               exit(1);
-       }
+       if (avl_pool == NULL)
+               nomem();
 
        cb.cb_sortcol = sortcol;
        cb.cb_flags = flags;
@@ -399,11 +420,8 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
                    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"));
-               exit(1);
-       }
+       if ((cb.cb_avl = uu_avl_create(avl_pool, NULL, UU_DEFAULT)) == NULL)
+               nomem();
 
        if (argc == 0) {
                /*
@@ -453,11 +471,8 @@ zfs_for_each(int argc, char **argv, int flags, zfs_type_t types,
        /*
         * Finally, clean up the AVL tree.
         */
-       if ((walk = uu_avl_walk_start(cb.cb_avl, UU_WALK_ROBUST)) == NULL) {
-               (void) fprintf(stderr,
-                   gettext("internal error: out of memory"));
-               exit(1);
-       }
+       if ((walk = uu_avl_walk_start(cb.cb_avl, UU_WALK_ROBUST)) == NULL)
+               nomem();
 
        while ((node = uu_avl_walk_next(walk)) != NULL) {
                uu_avl_remove(cb.cb_avl, node);