Print this page
    
re #12611 rb4105 zpool import panic in ddt_zap_count()
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/fs/zfs/ddt_zap.c
          +++ new/usr/src/uts/common/fs/zfs/ddt_zap.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  
    | 
      ↓ 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  /*
  23   23   * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
       24 + * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  24   25   */
  25   26  
  26   27  #include <sys/zfs_context.h>
  27   28  #include <sys/spa.h>
  28   29  #include <sys/zio.h>
  29   30  #include <sys/ddt.h>
  30   31  #include <sys/zap.h>
  31   32  #include <sys/dmu_tx.h>
  32   33  #include <util/sscanf.h>
  33   34  
  34   35  int ddt_zap_leaf_blockshift = 12;
  35   36  int ddt_zap_indirect_blockshift = 12;
  36   37  
  37   38  static int
  38   39  ddt_zap_create(objset_t *os, uint64_t *objectp, dmu_tx_t *tx, boolean_t prehash)
  39   40  {
  40   41          zap_flags_t flags = ZAP_FLAG_HASH64 | ZAP_FLAG_UINT64_KEY;
  41   42  
  42   43          if (prehash)
  43   44                  flags |= ZAP_FLAG_PRE_HASHED_KEY;
  44   45  
  45   46          *objectp = zap_create_flags(os, 0, flags, DMU_OT_DDT_ZAP,
  46   47              ddt_zap_leaf_blockshift, ddt_zap_indirect_blockshift,
  47   48              DMU_OT_NONE, 0, tx);
  48   49  
  49   50          return (*objectp == 0 ? ENOTSUP : 0);
  50   51  }
  51   52  
  52   53  static int
  53   54  ddt_zap_destroy(objset_t *os, uint64_t object, dmu_tx_t *tx)
  54   55  {
  55   56          return (zap_destroy(os, object, tx));
  56   57  }
  57   58  
  58   59  static int
  59   60  ddt_zap_lookup(objset_t *os, uint64_t object, ddt_entry_t *dde)
  60   61  {
  61   62          uchar_t cbuf[sizeof (dde->dde_phys) + 1];
  62   63          uint64_t one, csize;
  63   64          int error;
  64   65  
  65   66          error = zap_length_uint64(os, object, (uint64_t *)&dde->dde_key,
  66   67              DDT_KEY_WORDS, &one, &csize);
  67   68          if (error)
  68   69                  return (error);
  69   70  
  70   71          ASSERT(one == 1);
  71   72          ASSERT(csize <= sizeof (cbuf));
  72   73  
  73   74          error = zap_lookup_uint64(os, object, (uint64_t *)&dde->dde_key,
  74   75              DDT_KEY_WORDS, 1, csize, cbuf);
  75   76          if (error)
  76   77                  return (error);
  77   78  
  78   79          ddt_decompress(cbuf, dde->dde_phys, csize, sizeof (dde->dde_phys));
  79   80  
  80   81          return (0);
  81   82  }
  82   83  
  83   84  static void
  84   85  ddt_zap_prefetch(objset_t *os, uint64_t object, ddt_entry_t *dde)
  85   86  {
  86   87          (void) zap_prefetch_uint64(os, object, (uint64_t *)&dde->dde_key,
  87   88              DDT_KEY_WORDS);
  88   89  }
  89   90  
  90   91  static int
  91   92  ddt_zap_update(objset_t *os, uint64_t object, ddt_entry_t *dde, dmu_tx_t *tx)
  92   93  {
  93   94          uchar_t cbuf[sizeof (dde->dde_phys) + 1];
  94   95          uint64_t csize;
  95   96  
  96   97          csize = ddt_compress(dde->dde_phys, cbuf,
  97   98              sizeof (dde->dde_phys), sizeof (cbuf));
  98   99  
  99  100          return (zap_update_uint64(os, object, (uint64_t *)&dde->dde_key,
 100  101              DDT_KEY_WORDS, 1, csize, cbuf, tx));
 101  102  }
 102  103  
 103  104  static int
 104  105  ddt_zap_remove(objset_t *os, uint64_t object, ddt_entry_t *dde, dmu_tx_t *tx)
 105  106  {
 106  107          return (zap_remove_uint64(os, object, (uint64_t *)&dde->dde_key,
 107  108              DDT_KEY_WORDS, tx));
 108  109  }
 109  110  
 110  111  static int
 111  112  ddt_zap_walk(objset_t *os, uint64_t object, ddt_entry_t *dde, uint64_t *walk)
 112  113  {
 113  114          zap_cursor_t zc;
 114  115          zap_attribute_t za;
 115  116          int error;
 116  117  
 117  118          zap_cursor_init_serialized(&zc, os, object, *walk);
 118  119          if ((error = zap_cursor_retrieve(&zc, &za)) == 0) {
 119  120                  uchar_t cbuf[sizeof (dde->dde_phys) + 1];
 120  121                  uint64_t csize = za.za_num_integers;
 121  122                  ASSERT(za.za_integer_length == 1);
 122  123                  error = zap_lookup_uint64(os, object, (uint64_t *)za.za_name,
 123  124                      DDT_KEY_WORDS, 1, csize, cbuf);
 124  125                  ASSERT(error == 0);
 125  126                  if (error == 0) {
 126  127                          ddt_decompress(cbuf, dde->dde_phys, csize,
  
    | 
      ↓ open down ↓ | 
    93 lines elided | 
    
      ↑ open up ↑ | 
  
 127  128                              sizeof (dde->dde_phys));
 128  129                          dde->dde_key = *(ddt_key_t *)za.za_name;
 129  130                  }
 130  131                  zap_cursor_advance(&zc);
 131  132                  *walk = zap_cursor_serialize(&zc);
 132  133          }
 133  134          zap_cursor_fini(&zc);
 134  135          return (error);
 135  136  }
 136  137  
 137      -static uint64_t
 138      -ddt_zap_count(objset_t *os, uint64_t object)
      138 +static int
      139 +ddt_zap_count(objset_t *os, uint64_t object, uint64_t *count)
 139  140  {
 140      -        uint64_t count = 0;
      141 +        int error = zap_count(os, object, count);
      142 +        ASSERT(error == 0);
 141  143  
 142      -        VERIFY(zap_count(os, object, &count) == 0);
 143      -
 144      -        return (count);
      144 +        return (error);
 145  145  }
 146  146  
 147  147  const ddt_ops_t ddt_zap_ops = {
 148  148          "zap",
 149  149          ddt_zap_create,
 150  150          ddt_zap_destroy,
 151  151          ddt_zap_lookup,
 152  152          ddt_zap_prefetch,
 153  153          ddt_zap_update,
 154  154          ddt_zap_remove,
 155  155          ddt_zap_walk,
 156  156          ddt_zap_count,
 157  157  };
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX