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