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 ↓ 828 lines elided ↑ open up ↑
 829  829   * Walk through the pool-wide zap object of temporary snapshot user holds
 830  830   * and release them.
 831  831   */
 832  832  void
 833  833  dsl_pool_clean_tmp_userrefs(dsl_pool_t *dp)
 834  834  {
 835  835          zap_attribute_t za;
 836  836          zap_cursor_t zc;
 837  837          objset_t *mos = dp->dp_meta_objset;
 838  838          uint64_t zapobj = dp->dp_tmp_userrefs_obj;
      839 +        nvlist_t *holds;
 839  840  
 840  841          if (zapobj == 0)
 841  842                  return;
 842  843          ASSERT(spa_version(dp->dp_spa) >= SPA_VERSION_USERREFS);
 843  844  
      845 +        holds = fnvlist_alloc();
      846 +
 844  847          for (zap_cursor_init(&zc, mos, zapobj);
 845  848              zap_cursor_retrieve(&zc, &za) == 0;
 846  849              zap_cursor_advance(&zc)) {
 847  850                  char *htag;
 848  851                  uint64_t dsobj;
      852 +                nvlist_t *tags;
 849  853  
 850  854                  htag = strchr(za.za_name, '-');
 851  855                  *htag = '\0';
 852  856                  ++htag;
 853      -                dsobj = strtonum(za.za_name, NULL);
 854      -                dsl_dataset_user_release_tmp(dp, dsobj, htag);
      857 +                if (nvlist_lookup_nvlist(holds, za.za_name, &tags) != 0) {
      858 +                        tags = fnvlist_alloc();
      859 +                        fnvlist_add_boolean(tags, htag);
      860 +                        fnvlist_add_nvlist(holds, za.za_name, tags);
      861 +                        fnvlist_free(tags);
      862 +                } else {
      863 +                        fnvlist_add_boolean(tags, htag);
      864 +                }
 855  865          }
      866 +        dsl_dataset_user_release_tmp(dp, holds);
      867 +        fnvlist_free(holds);
 856  868          zap_cursor_fini(&zc);
 857  869  }
 858  870  
 859  871  /*
 860  872   * Create the pool-wide zap object for storing temporary snapshot holds.
 861  873   */
 862  874  void
 863  875  dsl_pool_user_hold_create_obj(dsl_pool_t *dp, dmu_tx_t *tx)
 864  876  {
 865  877          objset_t *mos = dp->dp_meta_objset;
↓ open down ↓ 166 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX