Print this page
3740 Poor ZFS send / receive performance due to snapshot hold / release processing
Submitted by: Steven Hartland <steven.hartland@multiplay.co.uk>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>

@@ -19,10 +19,11 @@
  * CDDL HEADER END
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2013 by Delphix. All rights reserved.
+ * Copyright (c) 2013 Steven Hartland. All rights reserved.
  */
 
 #include <sys/dsl_pool.h>
 #include <sys/dsl_dataset.h>
 #include <sys/dsl_prop.h>

@@ -834,27 +835,38 @@
 {
         zap_attribute_t za;
         zap_cursor_t zc;
         objset_t *mos = dp->dp_meta_objset;
         uint64_t zapobj = dp->dp_tmp_userrefs_obj;
+        nvlist_t *holds;
 
         if (zapobj == 0)
                 return;
         ASSERT(spa_version(dp->dp_spa) >= SPA_VERSION_USERREFS);
 
+        holds = fnvlist_alloc();
+
         for (zap_cursor_init(&zc, mos, zapobj);
             zap_cursor_retrieve(&zc, &za) == 0;
             zap_cursor_advance(&zc)) {
                 char *htag;
-                uint64_t dsobj;
+                nvlist_t *tags;
 
                 htag = strchr(za.za_name, '-');
                 *htag = '\0';
                 ++htag;
-                dsobj = strtonum(za.za_name, NULL);
-                dsl_dataset_user_release_tmp(dp, dsobj, htag);
+                if (nvlist_lookup_nvlist(holds, za.za_name, &tags) != 0) {
+                        tags = fnvlist_alloc();
+                        fnvlist_add_boolean(tags, htag);
+                        fnvlist_add_nvlist(holds, za.za_name, tags);
+                        fnvlist_free(tags);
+                } else {
+                        fnvlist_add_boolean(tags, htag);
+                }
         }
+        dsl_dataset_user_release_tmp(dp, holds);
+        fnvlist_free(holds);
         zap_cursor_fini(&zc);
 }
 
 /*
  * Create the pool-wide zap object for storing temporary snapshot holds.