kern/146297: [zfs] [patch] zfs list improvements (onnv 8415, 10474)

Martin Matuska mm at FreeBSD.org
Tue May 4 10:50:02 UTC 2010


>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:


More information about the freebsd-bugs mailing list