diff options
author | avg <avg@FreeBSD.org> | 2017-03-23 07:57:37 +0000 |
---|---|---|
committer | avg <avg@FreeBSD.org> | 2017-03-23 07:57:37 +0000 |
commit | ff9938d1382fa8461c8d32d158f6d8d000336ee2 (patch) | |
tree | 6a4a9d0ff56a5735e7a7519e31b57d570a402354 /sys | |
parent | 29d17586b5d539b3dbc6f41f4947e37f01fc33cb (diff) | |
download | FreeBSD-src-ff9938d1382fa8461c8d32d158f6d8d000336ee2.zip FreeBSD-src-ff9938d1382fa8461c8d32d158f6d8d000336ee2.tar.gz |
MFC r314912: MFV r314910: 7843 get_clones_stat() is suboptimal for lots of clones
Diffstat (limited to 'sys')
-rw-r--r-- | sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c index 5053bdf..4193f76 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c @@ -1766,11 +1766,22 @@ get_clones_stat(dsl_dataset_t *ds, nvlist_t *nv) zap_cursor_t zc; zap_attribute_t za; nvlist_t *propval = fnvlist_alloc(); - nvlist_t *val = fnvlist_alloc(); + nvlist_t *val; ASSERT(dsl_pool_config_held(ds->ds_dir->dd_pool)); /* + * We use nvlist_alloc() instead of fnvlist_alloc() because the + * latter would allocate the list with NV_UNIQUE_NAME flag. + * As a result, every time a clone name is appended to the list + * it would be (linearly) searched for for a duplicate name. + * We already know that all clone names must be unique and we + * want avoid the quadratic complexity of double-checking that + * because we can have a large number of clones. + */ + VERIFY0(nvlist_alloc(&val, 0, KM_SLEEP)); + + /* * There may be missing entries in ds_next_clones_obj * due to a bug in a previous version of the code. * Only trust it if it has the right number of entries. |