diff options
author | Pawel Jakub Dawidek <[email protected]> | 2012-05-29 10:50:50 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2012-06-14 09:49:04 -0700 |
commit | 0cee24064a79f9c01fc4521543c37acea538405f (patch) | |
tree | cc7429b7bc14f057aade9bea66a72a39e6a5a23c /cmd/zfs/zfs_iter.c | |
parent | 74497b7ab6af69434453e03c755d3f6e6e655aee (diff) |
Speed up 'zfs list -t snapshot -o name -s name'
FreeBSD #xxx: Dramatically optimize listing snapshots when user
requests only snapshot names and wants to sort them by name, ie.
when executes:
# zfs list -t snapshot -o name -s name
Because only name is needed we don't have to read all snapshot
properties.
Below you can find how long does it take to list 34509 snapshots
from a single disk pool before and after this change with cold and
warm cache:
before:
# time zfs list -t snapshot -o name -s name > /dev/null
cold cache: 525s
warm cache: 218s
after:
# time zfs list -t snapshot -o name -s name > /dev/null
cold cache: 1.7s
warm cache: 1.1s
NOTE: This patch only appears in FreeBSD. If/when Illumos picks up
the change we may want to drop this patch and adopt their version.
However, for now this addresses a real issue.
Ported-by: Brian Behlendorf <[email protected]>
Issue #450
Diffstat (limited to 'cmd/zfs/zfs_iter.c')
-rw-r--r-- | cmd/zfs/zfs_iter.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/cmd/zfs/zfs_iter.c b/cmd/zfs/zfs_iter.c index e2ab90eaf..6239a8f6b 100644 --- a/cmd/zfs/zfs_iter.c +++ b/cmd/zfs/zfs_iter.c @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012 Pawel Jakub Dawidek <[email protected]>. */ #include <libintl.h> @@ -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); |