From e2fcb562759f32d3ca6f3764914222132ce2cfd9 Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Tue, 7 Mar 2017 09:47:40 -0800 Subject: [PATCH] OpenZFS 7843 - get_clones_stat() is suboptimal for lots of clones Reviewed by: Pavel Zakharov Reviewed by: Matthew Ahrens Reviewed-by: George Melikov Reviewed-by: Giuseppe Di Natale Ported-by: Brian Behlendorf OpenZFS-issue: https://www.illumos.org/issues/7843 OpenZFS-commit: https://github.com/openzfs/openzfs/commit/4d519e7 Closes #5868 --- module/zfs/dsl_dataset.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/module/zfs/dsl_dataset.c b/module/zfs/dsl_dataset.c index 6c9bcbc9f..c91c2e991 100644 --- a/module/zfs/dsl_dataset.c +++ b/module/zfs/dsl_dataset.c @@ -1753,10 +1753,21 @@ 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.