Print this page
    
NEX-18589 checksum errors on SSD-based pool
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-9554 dsl_scan.c internals contain some confusingly similar function names for handling the dataset and block sorting queues
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-9562 Attaching a vdev while resilver/scrub is running causes panic.
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-6088 ZFS scrub/resilver take excessively long due to issuing lots of random IO
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/fs/zfs/sys/dsl_scan.h
          +++ new/usr/src/uts/common/fs/zfs/sys/dsl_scan.h
   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   *
  
    | 
      ↓ open down ↓ | 
    12 lines elided | 
    
      ↑ open up ↑ | 
  
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  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) 2010, Oracle and/or its affiliates. All rights reserved.
  23      - * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
       23 + * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
  24   24   * Copyright (c) 2017 Datto Inc.
  25   25   */
  26   26  
  27   27  #ifndef _SYS_DSL_SCAN_H
  28   28  #define _SYS_DSL_SCAN_H
  29   29  
  30   30  #include <sys/zfs_context.h>
  31   31  #include <sys/zio.h>
  32   32  #include <sys/ddt.h>
  33   33  #include <sys/bplist.h>
  34   34  
  35   35  #ifdef  __cplusplus
  36   36  extern "C" {
  37   37  #endif
  38   38  
  39   39  struct objset;
  40   40  struct dsl_dir;
  41   41  struct dsl_dataset;
  42   42  struct dsl_pool;
  43   43  struct dmu_tx;
  44   44  
  45   45  /*
  46   46   * All members of this structure must be uint64_t, for byteswap
  47   47   * purposes.
  48   48   */
  49   49  typedef struct dsl_scan_phys {
  50   50          uint64_t scn_func; /* pool_scan_func_t */
  51   51          uint64_t scn_state; /* dsl_scan_state_t */
  52   52          uint64_t scn_queue_obj;
  53   53          uint64_t scn_min_txg;
  54   54          uint64_t scn_max_txg;
  55   55          uint64_t scn_cur_min_txg;
  56   56          uint64_t scn_cur_max_txg;
  57   57          uint64_t scn_start_time;
  58   58          uint64_t scn_end_time;
  59   59          uint64_t scn_to_examine; /* total bytes to be scanned */
  60   60          uint64_t scn_examined; /* bytes scanned so far */
  61   61          uint64_t scn_to_process;
  62   62          uint64_t scn_processed;
  63   63          uint64_t scn_errors;    /* scan I/O error count */
  64   64          uint64_t scn_ddt_class_max;
  65   65          ddt_bookmark_t scn_ddt_bookmark;
  66   66          zbookmark_phys_t scn_bookmark;
  67   67          uint64_t scn_flags; /* dsl_scan_flags_t */
  68   68  } dsl_scan_phys_t;
  69   69  
  70   70  #define SCAN_PHYS_NUMINTS (sizeof (dsl_scan_phys_t) / sizeof (uint64_t))
  71   71  
  72   72  typedef enum dsl_scan_flags {
  73   73          DSF_VISIT_DS_AGAIN = 1<<0,
  74   74          DSF_SCRUB_PAUSED = 1<<1,
  75   75  } dsl_scan_flags_t;
  76   76  
  77   77  /*
  78   78   * Every pool will have one dsl_scan_t and this structure will contain
  79   79   * in-memory information about the scan and a pointer to the on-disk
  80   80   * representation (i.e. dsl_scan_phys_t). Most of the state of the scan
  81   81   * is contained on-disk to allow the scan to resume in the event of a reboot
  82   82   * or panic. This structure maintains information about the behavior of a
  83   83   * running scan, some caching information, and how it should traverse the pool.
  84   84   *
  85   85   * The following members of this structure direct the behavior of the scan:
  86   86   *
  87   87   * scn_suspending -     a scan that cannot be completed in a single txg or
  88   88   *                      has exceeded its allotted time will need to suspend.
  89   89   *                      When this flag is set the scanner will stop traversing
  90   90   *                      the pool and write out the current state to disk.
  91   91   *
  92   92   * scn_restart_txg -    directs the scanner to either restart or start a
  93   93   *                      a scan at the specified txg value.
  94   94   *
  95   95   * scn_done_txg -       when a scan completes its traversal it will set
  96   96   *                      the completion txg to the next txg. This is necessary
  97   97   *                      to ensure that any blocks that were freed during
  98   98   *                      the scan but have not yet been processed (i.e deferred
  99   99   *                      frees) are accounted for.
 100  100   *
 101  101   * This structure also maintains information about deferred frees which are
 102  102   * a special kind of traversal. Deferred free can exist in either a bptree or
 103  103   * a bpobj structure. The scn_is_bptree flag will indicate the type of
 104  104   * deferred free that is in progress. If the deferred free is part of an
 105  105   * asynchronous destroy then the scn_async_destroying flag will be set.
 106  106   */
 107  107  typedef struct dsl_scan {
 108  108          struct dsl_pool *scn_dp;
 109  109  
  
    | 
      ↓ open down ↓ | 
    76 lines elided | 
    
      ↑ open up ↑ | 
  
 110  110          boolean_t scn_suspending;
 111  111          uint64_t scn_restart_txg;
 112  112          uint64_t scn_done_txg;
 113  113          uint64_t scn_sync_start_time;
 114  114          zio_t *scn_zio_root;
 115  115  
 116  116          /* for freeing blocks */
 117  117          boolean_t scn_is_bptree;
 118  118          boolean_t scn_async_destroying;
 119  119          boolean_t scn_async_stalled;
 120      -        uint64_t  scn_async_block_min_time_ms;
 121      -
 122      -        /* for debugging / information */
 123  120          uint64_t scn_visited_this_txg;
 124  121  
 125  122          dsl_scan_phys_t scn_phys;
      123 +        dsl_scan_phys_t scn_phys_cached;
      124 +
      125 +        /*
      126 +         * With multi-threaded sync, we need to make sure scn_queue access
      127 +         * is kept nicely serialized.
      128 +         */
      129 +        kmutex_t scn_queue_lock;
      130 +        avl_tree_t scn_queue;
      131 +
      132 +        /*
      133 +         * These signal how much work is pending from the scanner to the
      134 +         * reader. Whenever the queue of zios grows, scn_bytes_pending grows
      135 +         * the corresponding amount. Once a read for a block has been issued
      136 +         * (whether in-order or out-of-order later on), scn_bytes_issued is
      137 +         * incremented by the amount of data consumed from scn_bytes_pending.
      138 +         * After a scan has completed, scn_bytes_pending will be 0 and
      139 +         * scn_bytes_issued will have the total amount of data read.
      140 +         *
      141 +         * Lock ordering:
      142 +         * scn_status_lock may only be held on its own or AFTER grabbing
      143 +         * a vdev_scan_queue_lock, never BEFORE vdev_scan_queue_lock.
      144 +         */
      145 +        kmutex_t scn_status_lock;
      146 +        uint64_t scn_bytes_pending;
      147 +        uint64_t scn_bytes_issued;
      148 +
      149 +        boolean_t scn_clearing;
      150 +        boolean_t scn_checkpointing;
      151 +        uint64_t scn_last_checkpoint;
      152 +        taskq_t *scn_taskq;
      153 +
      154 +        uint64_t scn_last_queue_run_time;
      155 +        uint64_t scn_last_dequeue_limit;
      156 +
      157 +        /* protects scn_is_sorted and scn_done_ds */
      158 +        kmutex_t scn_sorted_lock;
      159 +        /*
      160 +         * Flag denoting if we're running an out-of-order sorting scan or an
      161 +         * old non-sorting inline scan. This changes our checking behavior.
      162 +         */
      163 +        boolean_t scn_is_sorted;
 126  164  } dsl_scan_t;
 127  165  
      166 +typedef struct dsl_scan_io_queue dsl_scan_io_queue_t;
      167 +
      168 +void dsl_scan_global_init(void);
      169 +void dsl_scan_global_fini(void);
      170 +
 128  171  int dsl_scan_init(struct dsl_pool *dp, uint64_t txg);
 129  172  void dsl_scan_fini(struct dsl_pool *dp);
 130  173  void dsl_scan_sync(struct dsl_pool *, dmu_tx_t *);
 131  174  int dsl_scan_cancel(struct dsl_pool *);
 132  175  int dsl_scan(struct dsl_pool *, pool_scan_func_t);
 133  176  boolean_t dsl_scan_scrubbing(const struct dsl_pool *dp);
 134  177  int dsl_scrub_set_pause_resume(const struct dsl_pool *dp, pool_scrub_cmd_t cmd);
 135  178  void dsl_resilver_restart(struct dsl_pool *, uint64_t txg);
 136  179  boolean_t dsl_scan_resilvering(struct dsl_pool *dp);
 137  180  boolean_t dsl_dataset_unstable(struct dsl_dataset *ds);
 138  181  void dsl_scan_ddt_entry(dsl_scan_t *scn, enum zio_checksum checksum,
 139  182      ddt_entry_t *dde, dmu_tx_t *tx);
 140  183  void dsl_scan_ds_destroyed(struct dsl_dataset *ds, struct dmu_tx *tx);
 141  184  void dsl_scan_ds_snapshotted(struct dsl_dataset *ds, struct dmu_tx *tx);
 142  185  void dsl_scan_ds_clone_swapped(struct dsl_dataset *ds1, struct dsl_dataset *ds2,
 143  186      struct dmu_tx *tx);
 144  187  boolean_t dsl_scan_active(dsl_scan_t *scn);
      188 +void dsl_scan_freed(spa_t *spa, const blkptr_t *bp);
      189 +void dsl_scan_io_queue_destroy(dsl_scan_io_queue_t *queue);
      190 +void dsl_scan_io_queue_vdev_xfer(vdev_t *svd, vdev_t *tvd);
 145  191  boolean_t dsl_scan_is_paused_scrub(const dsl_scan_t *scn);
 146  192  
 147  193  #ifdef  __cplusplus
 148  194  }
 149  195  #endif
 150  196  
 151  197  #endif /* _SYS_DSL_SCAN_H */
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX