>Number:         146297
>Category:       kern
>Synopsis:       [zfs] [patch] zfs list improvements (onnv 8415, 10474)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue May 04 10:50:02 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Martin Matuska
>Release:        FreeBSD 8.0-STABLE amd64
>Organization:
>Environment:
>Description:
Improve zfs list operation by importing the following changes from OpenSolaris:

Import full onnv revision: 8415:d5525cd1cbc2
    Bug IDs:
        6386929 initial "zfs list" is slow
        6755389 Initial run of any zfs command that iterates over datasets can 
be slow
        6758338 zfs list should list all explicitly requested snapshots

Backport partial onnv revision: 10474:0e96dd3b905a
    Bug IDs:
        6847118 hang in ZFS during rollback

>How-To-Repeat:
>Fix:
Index: cddl/contrib/opensolaris/cmd/zfs/zfs_main.c
===================================================================
--- cddl/contrib/opensolaris/cmd/zfs/zfs_main.c (revision 207610)
+++ cddl/contrib/opensolaris/cmd/zfs/zfs_main.c (working copy)
@@ -1790,7 +1790,7 @@
        boolean_t scripted = B_FALSE;
        static char default_fields[] =
            "name,used,available,referenced,mountpoint";
-       int types = ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME;
+       int types = ZFS_TYPE_DATASET;
        boolean_t types_specified = B_FALSE;
        char *fields = NULL;
        list_cbdata_t cb = { 0 };
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c (revision 
207610)
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c (working copy)
@@ -1213,6 +1213,39 @@
        return (err);
 }
 
+/* ARGSUSED */
+int
+dmu_objset_prefetch(char *name, void *arg)
+{
+       dsl_dataset_t *ds;
+
+       if (dsl_dataset_hold(name, FTAG, &ds))
+               return (0);
+
+       if (!BP_IS_HOLE(&ds->ds_phys->ds_bp)) {
+               mutex_enter(&ds->ds_opening_lock);
+               if (!dsl_dataset_get_user_ptr(ds)) {
+                       uint32_t aflags = ARC_NOWAIT | ARC_PREFETCH;
+                       zbookmark_t zb;
+
+                       zb.zb_objset = ds->ds_object;
+                       zb.zb_object = 0;
+                       zb.zb_level = -1;
+                       zb.zb_blkid = 0;
+
+                       (void) arc_read_nolock(NULL, dsl_dataset_get_spa(ds),
+                           &ds->ds_phys->ds_bp, NULL, NULL,
+                           ZIO_PRIORITY_ASYNC_READ,
+                           ZIO_FLAG_CANFAIL | ZIO_FLAG_SPECULATIVE,
+                           &aflags, &zb);
+               }
+               mutex_exit(&ds->ds_opening_lock);
+       }
+
+       dsl_dataset_rele(ds, FTAG);
+       return (0);
+}
+
 void
 dmu_objset_set_user(objset_t *os, void *user_ptr)
 {
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c  (revision 
207610)
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c  (working copy)
@@ -1349,6 +1349,14 @@
                (void) strlcat(zc->zc_name, "/", sizeof (zc->zc_name));
        p = zc->zc_name + strlen(zc->zc_name);
 
+       if (zc->zc_cookie == 0) {
+               uint64_t cookie = 0;
+               int len = sizeof (zc->zc_name) - (p - zc->zc_name);
+
+               while (dmu_dir_list_next(os, len, p, NULL, &cookie) == 0)
+                       dmu_objset_prefetch(p, NULL);
+       }
+
        do {
                error = dmu_dir_list_next(os,
                    sizeof (zc->zc_name) - (p - zc->zc_name), p,
@@ -1387,6 +1395,9 @@
        objset_t *os;
        int error;
 
+       if (zc->zc_cookie == 0)
+               dmu_objset_find(zc->zc_name, dmu_objset_prefetch,
+                   NULL, DS_FIND_SNAPSHOTS);
        error = dmu_objset_open(zc->zc_name,
            DMU_OST_ANY, DS_MODE_USER | DS_MODE_READONLY, &os);
        if (error)
Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_objset.h
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_objset.h     
(revision 207610)
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dmu_objset.h     
(working copy)
@@ -26,8 +26,6 @@
 #ifndef        _SYS_DMU_OBJSET_H
 #define        _SYS_DMU_OBJSET_H
 
-#pragma ident  "%Z%%M% %I%     %E% SMI"
-
 #include <sys/spa.h>
 #include <sys/arc.h>
 #include <sys/txg.h>
@@ -118,6 +116,7 @@
     int flags);
 int dmu_objset_find_spa(spa_t *spa, const char *name,
     int func(spa_t *, uint64_t, const char *, void *), void *arg, int flags);
+int dmu_objset_prefetch(char *name, void *arg);
 void dmu_objset_byteswap(void *buf, size_t size);
 int dmu_objset_evict_dbufs(objset_t *os);
 
>Release-Note:
>Audit-Trail:
>Unformatted:
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to