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

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/dsl_pool.c
          +++ new/usr/src/uts/common/fs/zfs/dsl_pool.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   * Copyright (c) 2013 by Delphix. All rights reserved.
       24 + * Copyright (c) 2013 Steven Hartland. All rights reserved.
  24   25   */
  25   26  
  26   27  #include <sys/dsl_pool.h>
  27   28  #include <sys/dsl_dataset.h>
  28   29  #include <sys/dsl_prop.h>
  29   30  #include <sys/dsl_dir.h>
  30   31  #include <sys/dsl_synctask.h>
  31   32  #include <sys/dsl_scan.h>
  32   33  #include <sys/dnode.h>
  33   34  #include <sys/dmu_tx.h>
↓ open down ↓ 795 lines elided ↑ open up ↑
 829  830   * Walk through the pool-wide zap object of temporary snapshot user holds
 830  831   * and release them.
 831  832   */
 832  833  void
 833  834  dsl_pool_clean_tmp_userrefs(dsl_pool_t *dp)
 834  835  {
 835  836          zap_attribute_t za;
 836  837          zap_cursor_t zc;
 837  838          objset_t *mos = dp->dp_meta_objset;
 838  839          uint64_t zapobj = dp->dp_tmp_userrefs_obj;
      840 +        nvlist_t *holds;
 839  841  
 840  842          if (zapobj == 0)
 841  843                  return;
 842  844          ASSERT(spa_version(dp->dp_spa) >= SPA_VERSION_USERREFS);
 843  845  
      846 +        holds = fnvlist_alloc();
      847 +
 844  848          for (zap_cursor_init(&zc, mos, zapobj);
 845  849              zap_cursor_retrieve(&zc, &za) == 0;
 846  850              zap_cursor_advance(&zc)) {
 847  851                  char *htag;
 848  852                  uint64_t dsobj;
      853 +                nvlist_t *tags;
 849  854  
 850  855                  htag = strchr(za.za_name, '-');
 851  856                  *htag = '\0';
 852  857                  ++htag;
 853      -                dsobj = strtonum(za.za_name, NULL);
 854      -                dsl_dataset_user_release_tmp(dp, dsobj, htag);
      858 +                if (nvlist_lookup_nvlist(holds, za.za_name, &tags) != 0) {
      859 +                        tags = fnvlist_alloc();
      860 +                        fnvlist_add_boolean(tags, htag);
      861 +                        fnvlist_add_nvlist(holds, za.za_name, tags);
      862 +                        fnvlist_free(tags);
      863 +                } else {
      864 +                        fnvlist_add_boolean(tags, htag);
      865 +                }
 855  866          }
      867 +        dsl_dataset_user_release_tmp(dp, holds);
      868 +        fnvlist_free(holds);
 856  869          zap_cursor_fini(&zc);
 857  870  }
 858  871  
 859  872  /*
 860  873   * Create the pool-wide zap object for storing temporary snapshot holds.
 861  874   */
 862  875  void
 863  876  dsl_pool_user_hold_create_obj(dsl_pool_t *dp, dmu_tx_t *tx)
 864  877  {
 865  878          objset_t *mos = dp->dp_meta_objset;
↓ open down ↓ 166 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX