Add createtxg sort support for simple snapshot iterator

- When iterating snapshots with name only, e.g., "-o name -s name",
libzfs uses simple snapshot iterator and results are displayed
in alphabetic order. This PR adds support for faster version of
createtxg sort by avoiding nvlist parsing for properties. Flags
"-o name -s createtxg" will enable createtxg sort while using
simple snapshot iterator.
- Added support to read createtxg property directly from zfs handle
for filesystem, volume and snapshot types instead of parsing nvlist.

Reviewed-by: Ryan Moeller <ryan@iXsystems.com>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Signed-off-by: Ameer Hamza <ahamza@ixsystems.com>
Closes #13577
This commit is contained in:
Ameer Hamza 2022-07-26 02:04:46 +05:00 committed by GitHub
parent 8792dd24cd
commit 3a1ce49141
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 8 deletions

View File

@ -218,6 +218,13 @@ zfs_sort_only_by_name(const zfs_sort_column_t *sc)
sc->sc_prop == ZFS_PROP_NAME); sc->sc_prop == ZFS_PROP_NAME);
} }
int
zfs_sort_only_by_createtxg(const zfs_sort_column_t *sc)
{
return (sc != NULL && sc->sc_next == NULL &&
sc->sc_prop == ZFS_PROP_CREATETXG);
}
static int static int
zfs_compare(const void *larg, const void *rarg) zfs_compare(const void *larg, const void *rarg)
{ {
@ -301,7 +308,7 @@ zfs_sort(const void *larg, const void *rarg, void *data)
for (psc = sc; psc != NULL; psc = psc->sc_next) { for (psc = sc; psc != NULL; psc = psc->sc_next) {
char lbuf[ZFS_MAXPROPLEN], rbuf[ZFS_MAXPROPLEN]; char lbuf[ZFS_MAXPROPLEN], rbuf[ZFS_MAXPROPLEN];
char *lstr, *rstr; char *lstr, *rstr;
uint64_t lnum, rnum; uint64_t lnum = 0, rnum = 0;
boolean_t lvalid, rvalid; boolean_t lvalid, rvalid;
int ret = 0; int ret = 0;
@ -352,11 +359,9 @@ zfs_sort(const void *larg, const void *rarg, void *data)
zfs_get_type(r), B_FALSE); zfs_get_type(r), B_FALSE);
if (lvalid) if (lvalid)
(void) zfs_prop_get_numeric(l, psc->sc_prop, lnum = zfs_prop_get_int(l, psc->sc_prop);
&lnum, NULL, NULL, 0);
if (rvalid) if (rvalid)
(void) zfs_prop_get_numeric(r, psc->sc_prop, rnum = zfs_prop_get_int(r, psc->sc_prop);
&rnum, NULL, NULL, 0);
} }
if (!lvalid && !rvalid) if (!lvalid && !rvalid)

View File

@ -53,6 +53,7 @@ int zfs_for_each(int, char **, int options, zfs_type_t,
int zfs_add_sort_column(zfs_sort_column_t **, const char *, boolean_t); int zfs_add_sort_column(zfs_sort_column_t **, const char *, boolean_t);
void zfs_free_sort_columns(zfs_sort_column_t *); void zfs_free_sort_columns(zfs_sort_column_t *);
int zfs_sort_only_by_name(const zfs_sort_column_t *); int zfs_sort_only_by_name(const zfs_sort_column_t *);
int zfs_sort_only_by_createtxg(const zfs_sort_column_t *);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -3654,11 +3654,14 @@ found3:;
argv += optind; argv += optind;
/* /*
* If we are only going to list snapshot names and sort by name, * If we are only going to list snapshot names and sort by name or
* then we can use faster version. * by createtxg, then we can use faster version.
*/ */
if (strcmp(fields, "name") == 0 && zfs_sort_only_by_name(sortcol)) if (strcmp(fields, "name") == 0 &&
(zfs_sort_only_by_name(sortcol) ||
zfs_sort_only_by_createtxg(sortcol))) {
flags |= ZFS_ITER_SIMPLE; flags |= ZFS_ITER_SIMPLE;
}
/* /*
* If "-o space" and no types were specified, don't display snapshots. * If "-o space" and no types were specified, don't display snapshots.

View File

@ -527,6 +527,7 @@ make_dataset_simple_handle_zc(zfs_handle_t *pzhp, zfs_cmd_t *zc)
zhp->zfs_head_type = pzhp->zfs_type; zhp->zfs_head_type = pzhp->zfs_type;
zhp->zfs_type = ZFS_TYPE_SNAPSHOT; zhp->zfs_type = ZFS_TYPE_SNAPSHOT;
zhp->zpool_hdl = zpool_handle(zhp); zhp->zpool_hdl = zpool_handle(zhp);
zhp->zfs_dmustats = zc->zc_objset_stats;
return (zhp); return (zhp);
} }
@ -2283,6 +2284,19 @@ get_numeric_property(zfs_handle_t *zhp, zfs_prop_t prop, zprop_source_t *src,
*val = zhp->zfs_dmustats.dds_redacted; *val = zhp->zfs_dmustats.dds_redacted;
break; break;
case ZFS_PROP_CREATETXG:
/*
* We can directly read createtxg property from zfs
* handle for Filesystem, Snapshot and ZVOL types.
*/
if ((zhp->zfs_type == ZFS_TYPE_FILESYSTEM) ||
(zhp->zfs_type == ZFS_TYPE_SNAPSHOT) ||
(zhp->zfs_type == ZFS_TYPE_VOLUME)) {
*val = zhp->zfs_dmustats.dds_creation_txg;
break;
}
zfs_fallthrough;
default: default:
switch (zfs_prop_get_type(prop)) { switch (zfs_prop_get_type(prop)) {
case PROP_TYPE_NUMBER: case PROP_TYPE_NUMBER:

View File

@ -2322,6 +2322,8 @@ zfs_ioc_snapshot_list_next(zfs_cmd_t *zc)
} }
if (zc->zc_simple) { if (zc->zc_simple) {
zc->zc_objset_stats.dds_creation_txg =
dsl_get_creationtxg(ds);
dsl_dataset_rele(ds, FTAG); dsl_dataset_rele(ds, FTAG);
break; break;
} }