Print this page
    
NEX-4794 Write Back Cache sync and async writes: adjust routing according to watermark limits
Reviewed by: Alex Aizman <alex.aizman@nexenta.com>
Reviewed by: Alek Pinchuk <alek.pinchuk@nexenta.com>
5269 zpool import slow
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: George Wilson <george@delphix.com>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Approved by: Dan McDonald <danmcd@omniti.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/fs/zfs/sys/zil.h
          +++ new/usr/src/uts/common/fs/zfs/sys/zil.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   *
  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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   * Copyright (c) 2012, 2017 by Delphix. All rights reserved.
  24   24   * Copyright (c) 2014 Integros [integros.com]
  25   25   */
  26   26  
  27   27  /* Portions Copyright 2010 Robert Milkowski */
  28   28  
  29   29  #ifndef _SYS_ZIL_H
  30   30  #define _SYS_ZIL_H
  31   31  
  32   32  #include <sys/types.h>
  33   33  #include <sys/spa.h>
  34   34  #include <sys/zio.h>
  35   35  #include <sys/dmu.h>
  36   36  
  37   37  #ifdef  __cplusplus
  38   38  extern "C" {
  39   39  #endif
  40   40  
  41   41  struct dsl_pool;
  42   42  struct dsl_dataset;
  43   43  struct lwb;
  44   44  
  45   45  /*
  46   46   * Intent log format:
  47   47   *
  48   48   * Each objset has its own intent log.  The log header (zil_header_t)
  49   49   * for objset N's intent log is kept in the Nth object of the SPA's
  50   50   * intent_log objset.  The log header points to a chain of log blocks,
  51   51   * each of which contains log records (i.e., transactions) followed by
  52   52   * a log block trailer (zil_trailer_t).  The format of a log record
  53   53   * depends on the record (or transaction) type, but all records begin
  54   54   * with a common structure that defines the type, length, and txg.
  55   55   */
  56   56  
  57   57  /*
  58   58   * Intent log header - this on disk structure holds fields to manage
  59   59   * the log.  All fields are 64 bit to easily handle cross architectures.
  60   60   */
  61   61  typedef struct zil_header {
  62   62          uint64_t zh_claim_txg;  /* txg in which log blocks were claimed */
  63   63          uint64_t zh_replay_seq; /* highest replayed sequence number */
  64   64          blkptr_t zh_log;        /* log chain */
  65   65          uint64_t zh_claim_blk_seq; /* highest claimed block sequence number */
  66   66          uint64_t zh_flags;      /* header flags */
  67   67          uint64_t zh_claim_lr_seq; /* highest claimed lr sequence number */
  68   68          uint64_t zh_pad[3];
  69   69  } zil_header_t;
  70   70  
  71   71  /*
  72   72   * zh_flags bit settings
  73   73   */
  74   74  #define ZIL_REPLAY_NEEDED       0x1     /* replay needed - internal only */
  75   75  #define ZIL_CLAIM_LR_SEQ_VALID  0x2     /* zh_claim_lr_seq field is valid */
  76   76  
  77   77  /*
  78   78   * Log block chaining.
  79   79   *
  80   80   * Log blocks are chained together. Originally they were chained at the
  81   81   * end of the block. For performance reasons the chain was moved to the
  82   82   * beginning of the block which allows writes for only the data being used.
  83   83   * The older position is supported for backwards compatability.
  84   84   *
  85   85   * The zio_eck_t contains a zec_cksum which for the intent log is
  86   86   * the sequence number of this log block. A seq of 0 is invalid.
  87   87   * The zec_cksum is checked by the SPA against the sequence
  88   88   * number passed in the blk_cksum field of the blkptr_t
  89   89   */
  90   90  typedef struct zil_chain {
  91   91          uint64_t zc_pad;
  92   92          blkptr_t zc_next_blk;   /* next block in chain */
  93   93          uint64_t zc_nused;      /* bytes in log block used */
  94   94          zio_eck_t zc_eck;       /* block trailer */
  95   95  } zil_chain_t;
  96   96  
  97   97  #define ZIL_MIN_BLKSZ   4096ULL
  98   98  
  99   99  /*
 100  100   * ziltest is by and large an ugly hack, but very useful in
 101  101   * checking replay without tedious work.
 102  102   * When running ziltest we want to keep all itx's and so maintain
 103  103   * a single list in the zl_itxg[] that uses a high txg: ZILTEST_TXG
 104  104   * We subtract TXG_CONCURRENT_STATES to allow for common code.
 105  105   */
 106  106  #define ZILTEST_TXG (UINT64_MAX - TXG_CONCURRENT_STATES)
 107  107  
 108  108  /*
 109  109   * The words of a log block checksum.
 110  110   */
 111  111  #define ZIL_ZC_GUID_0   0
 112  112  #define ZIL_ZC_GUID_1   1
 113  113  #define ZIL_ZC_OBJSET   2
 114  114  #define ZIL_ZC_SEQ      3
 115  115  
 116  116  typedef enum zil_create {
 117  117          Z_FILE,
 118  118          Z_DIR,
 119  119          Z_XATTRDIR,
 120  120  } zil_create_t;
 121  121  
 122  122  /*
 123  123   * size of xvattr log section.
 124  124   * its composed of lr_attr_t + xvattr bitmap + 2 64 bit timestamps
 125  125   * for create time and a single 64 bit integer for all of the attributes,
 126  126   * and 4 64 bit integers (32 bytes) for the scanstamp.
 127  127   *
 128  128   */
 129  129  
 130  130  #define ZIL_XVAT_SIZE(mapsize) \
 131  131          sizeof (lr_attr_t) + (sizeof (uint32_t) * (mapsize - 1)) + \
 132  132          (sizeof (uint64_t) * 7)
 133  133  
 134  134  /*
 135  135   * Size of ACL in log.  The ACE data is padded out to properly align
 136  136   * on 8 byte boundary.
 137  137   */
 138  138  
 139  139  #define ZIL_ACE_LENGTH(x)       (roundup(x, sizeof (uint64_t)))
 140  140  
 141  141  /*
 142  142   * Intent log transaction types and record structures
 143  143   */
 144  144  #define TX_COMMIT               0       /* Commit marker (no on-disk state) */
 145  145  #define TX_CREATE               1       /* Create file */
 146  146  #define TX_MKDIR                2       /* Make directory */
 147  147  #define TX_MKXATTR              3       /* Make XATTR directory */
 148  148  #define TX_SYMLINK              4       /* Create symbolic link to a file */
 149  149  #define TX_REMOVE               5       /* Remove file */
 150  150  #define TX_RMDIR                6       /* Remove directory */
 151  151  #define TX_LINK                 7       /* Create hard link to a file */
 152  152  #define TX_RENAME               8       /* Rename a file */
 153  153  #define TX_WRITE                9       /* File write */
 154  154  #define TX_TRUNCATE             10      /* Truncate a file */
 155  155  #define TX_SETATTR              11      /* Set file attributes */
 156  156  #define TX_ACL_V0               12      /* Set old formatted ACL */
 157  157  #define TX_ACL                  13      /* Set ACL */
 158  158  #define TX_CREATE_ACL           14      /* create with ACL */
 159  159  #define TX_CREATE_ATTR          15      /* create + attrs */
 160  160  #define TX_CREATE_ACL_ATTR      16      /* create with ACL + attrs */
 161  161  #define TX_MKDIR_ACL            17      /* mkdir with ACL */
 162  162  #define TX_MKDIR_ATTR           18      /* mkdir with attr */
 163  163  #define TX_MKDIR_ACL_ATTR       19      /* mkdir with ACL + attrs */
 164  164  #define TX_WRITE2               20      /* dmu_sync EALREADY write */
 165  165  #define TX_MAX_TYPE             21      /* Max transaction type */
 166  166  
 167  167  /*
 168  168   * The transactions for mkdir, symlink, remove, rmdir, link, and rename
 169  169   * may have the following bit set, indicating the original request
 170  170   * specified case-insensitive handling of names.
 171  171   */
 172  172  #define TX_CI   ((uint64_t)0x1 << 63) /* case-insensitive behavior requested */
 173  173  
 174  174  /*
 175  175   * Transactions for write, truncate, setattr, acl_v0, and acl can be logged
 176  176   * out of order.  For convenience in the code, all such records must have
 177  177   * lr_foid at the same offset.
 178  178   */
 179  179  #define TX_OOO(txtype)                  \
 180  180          ((txtype) == TX_WRITE ||        \
 181  181          (txtype) == TX_TRUNCATE ||      \
 182  182          (txtype) == TX_SETATTR ||       \
 183  183          (txtype) == TX_ACL_V0 ||        \
 184  184          (txtype) == TX_ACL ||           \
 185  185          (txtype) == TX_WRITE2)
 186  186  
 187  187  /*
 188  188   * Format of log records.
 189  189   * The fields are carefully defined to allow them to be aligned
 190  190   * and sized the same on sparc & intel architectures.
 191  191   * Each log record has a common structure at the beginning.
 192  192   *
 193  193   * The log record on disk (lrc_seq) holds the sequence number of all log
 194  194   * records which is used to ensure we don't replay the same record.
 195  195   */
 196  196  typedef struct {                        /* common log record header */
 197  197          uint64_t        lrc_txtype;     /* intent log transaction type */
 198  198          uint64_t        lrc_reclen;     /* transaction record length */
 199  199          uint64_t        lrc_txg;        /* dmu transaction group number */
 200  200          uint64_t        lrc_seq;        /* see comment above */
 201  201  } lr_t;
 202  202  
 203  203  /*
 204  204   * Common start of all out-of-order record types (TX_OOO() above).
 205  205   */
 206  206  typedef struct {
 207  207          lr_t            lr_common;      /* common portion of log record */
 208  208          uint64_t        lr_foid;        /* object id */
 209  209  } lr_ooo_t;
 210  210  
 211  211  /*
 212  212   * Handle option extended vattr attributes.
 213  213   *
 214  214   * Whenever new attributes are added the version number
 215  215   * will need to be updated as will code in
 216  216   * zfs_log.c and zfs_replay.c
 217  217   */
 218  218  typedef struct {
 219  219          uint32_t        lr_attr_masksize; /* number of elements in array */
 220  220          uint32_t        lr_attr_bitmap; /* First entry of array */
 221  221          /* remainder of array and any additional fields */
 222  222  } lr_attr_t;
 223  223  
 224  224  /*
 225  225   * log record for creates without optional ACL.
 226  226   * This log record does support optional xvattr_t attributes.
 227  227   */
 228  228  typedef struct {
 229  229          lr_t            lr_common;      /* common portion of log record */
 230  230          uint64_t        lr_doid;        /* object id of directory */
 231  231          uint64_t        lr_foid;        /* object id of created file object */
 232  232          uint64_t        lr_mode;        /* mode of object */
 233  233          uint64_t        lr_uid;         /* uid of object */
 234  234          uint64_t        lr_gid;         /* gid of object */
 235  235          uint64_t        lr_gen;         /* generation (txg of creation) */
 236  236          uint64_t        lr_crtime[2];   /* creation time */
 237  237          uint64_t        lr_rdev;        /* rdev of object to create */
 238  238          /* name of object to create follows this */
 239  239          /* for symlinks, link content follows name */
 240  240          /* for creates with xvattr data, the name follows the xvattr info */
 241  241  } lr_create_t;
 242  242  
 243  243  /*
 244  244   * FUID ACL record will be an array of ACEs from the original ACL.
 245  245   * If this array includes ephemeral IDs, the record will also include
 246  246   * an array of log-specific FUIDs to replace the ephemeral IDs.
 247  247   * Only one copy of each unique domain will be present, so the log-specific
 248  248   * FUIDs will use an index into a compressed domain table.  On replay this
 249  249   * information will be used to construct real FUIDs (and bypass idmap,
 250  250   * since it may not be available).
 251  251   */
 252  252  
 253  253  /*
 254  254   * Log record for creates with optional ACL
 255  255   * This log record is also used for recording any FUID
 256  256   * information needed for replaying the create.  If the
 257  257   * file doesn't have any actual ACEs then the lr_aclcnt
 258  258   * would be zero.
 259  259   *
 260  260   * After lr_acl_flags, there are a lr_acl_bytes number of variable sized ace's.
 261  261   * If create is also setting xvattr's, then acl data follows xvattr.
 262  262   * If ACE FUIDs are needed then they will follow the xvattr_t.  Following
 263  263   * the FUIDs will be the domain table information.  The FUIDs for the owner
 264  264   * and group will be in lr_create.  Name follows ACL data.
 265  265   */
 266  266  typedef struct {
 267  267          lr_create_t     lr_create;      /* common create portion */
 268  268          uint64_t        lr_aclcnt;      /* number of ACEs in ACL */
 269  269          uint64_t        lr_domcnt;      /* number of unique domains */
 270  270          uint64_t        lr_fuidcnt;     /* number of real fuids */
 271  271          uint64_t        lr_acl_bytes;   /* number of bytes in ACL */
 272  272          uint64_t        lr_acl_flags;   /* ACL flags */
 273  273  } lr_acl_create_t;
 274  274  
 275  275  typedef struct {
 276  276          lr_t            lr_common;      /* common portion of log record */
 277  277          uint64_t        lr_doid;        /* obj id of directory */
 278  278          /* name of object to remove follows this */
 279  279  } lr_remove_t;
 280  280  
 281  281  typedef struct {
 282  282          lr_t            lr_common;      /* common portion of log record */
 283  283          uint64_t        lr_doid;        /* obj id of directory */
 284  284          uint64_t        lr_link_obj;    /* obj id of link */
 285  285          /* name of object to link follows this */
 286  286  } lr_link_t;
 287  287  
 288  288  typedef struct {
 289  289          lr_t            lr_common;      /* common portion of log record */
 290  290          uint64_t        lr_sdoid;       /* obj id of source directory */
 291  291          uint64_t        lr_tdoid;       /* obj id of target directory */
 292  292          /* 2 strings: names of source and destination follow this */
 293  293  } lr_rename_t;
 294  294  
 295  295  typedef struct {
 296  296          lr_t            lr_common;      /* common portion of log record */
 297  297          uint64_t        lr_foid;        /* file object to write */
 298  298          uint64_t        lr_offset;      /* offset to write to */
 299  299          uint64_t        lr_length;      /* user data length to write */
 300  300          uint64_t        lr_blkoff;      /* no longer used */
 301  301          blkptr_t        lr_blkptr;      /* spa block pointer for replay */
 302  302          /* write data will follow for small writes */
 303  303  } lr_write_t;
 304  304  
 305  305  typedef struct {
 306  306          lr_t            lr_common;      /* common portion of log record */
 307  307          uint64_t        lr_foid;        /* object id of file to truncate */
 308  308          uint64_t        lr_offset;      /* offset to truncate from */
 309  309          uint64_t        lr_length;      /* length to truncate */
 310  310  } lr_truncate_t;
 311  311  
 312  312  typedef struct {
 313  313          lr_t            lr_common;      /* common portion of log record */
 314  314          uint64_t        lr_foid;        /* file object to change attributes */
 315  315          uint64_t        lr_mask;        /* mask of attributes to set */
 316  316          uint64_t        lr_mode;        /* mode to set */
 317  317          uint64_t        lr_uid;         /* uid to set */
 318  318          uint64_t        lr_gid;         /* gid to set */
 319  319          uint64_t        lr_size;        /* size to set */
 320  320          uint64_t        lr_atime[2];    /* access time */
 321  321          uint64_t        lr_mtime[2];    /* modification time */
 322  322          /* optional attribute lr_attr_t may be here */
 323  323  } lr_setattr_t;
 324  324  
 325  325  typedef struct {
 326  326          lr_t            lr_common;      /* common portion of log record */
 327  327          uint64_t        lr_foid;        /* obj id of file */
 328  328          uint64_t        lr_aclcnt;      /* number of acl entries */
 329  329          /* lr_aclcnt number of ace_t entries follow this */
 330  330  } lr_acl_v0_t;
 331  331  
 332  332  typedef struct {
 333  333          lr_t            lr_common;      /* common portion of log record */
 334  334          uint64_t        lr_foid;        /* obj id of file */
 335  335          uint64_t        lr_aclcnt;      /* number of ACEs in ACL */
 336  336          uint64_t        lr_domcnt;      /* number of unique domains */
 337  337          uint64_t        lr_fuidcnt;     /* number of real fuids */
 338  338          uint64_t        lr_acl_bytes;   /* number of bytes in ACL */
 339  339          uint64_t        lr_acl_flags;   /* ACL flags */
 340  340          /* lr_acl_bytes number of variable sized ace's follows */
 341  341  } lr_acl_t;
 342  342  
 343  343  /*
 344  344   * ZIL structure definitions, interface function prototype and globals.
 345  345   */
  
    | 
      ↓ open down ↓ | 
    345 lines elided | 
    
      ↑ open up ↑ | 
  
 346  346  
 347  347  /*
 348  348   * Writes are handled in three different ways:
 349  349   *
 350  350   * WR_INDIRECT:
 351  351   *    In this mode, if we need to commit the write later, then the block
 352  352   *    is immediately written into the file system (using dmu_sync),
 353  353   *    and a pointer to the block is put into the log record.
 354  354   *    When the txg commits the block is linked in.
 355  355   *    This saves additionally writing the data into the log record.
 356      - *    There are a few requirements for this to occur:
 357      - *      - write is greater than zfs/zvol_immediate_write_sz
 358      - *      - not using slogs (as slogs are assumed to always be faster
 359      - *        than writing into the main pool)
 360      - *      - the write occupies only one block
      356 + *    There are a few requirements for this to occur. In general, WR_INDIRECT
      357 + *    with the subsequent dmu_sync-ing of the data directly into the filesystem
      358 + *    is used in the two following separate cases:
      359 + *      - logbias = THROUGHPUT mode
      360 + *      - writeback cache (via special vdev) when there is no separate slog
      361 + *    For specific details and configurable tunables - see zfs_log_write().
 361  362   * WR_COPIED:
 362  363   *    If we know we'll immediately be committing the
 363  364   *    transaction (FSYNC or FDSYNC), the we allocate a larger
 364  365   *    log record here for the data and copy the data in.
 365  366   * WR_NEED_COPY:
 366  367   *    Otherwise we don't allocate a buffer, and *if* we need to
 367  368   *    flush the write later then a buffer is allocated and
 368  369   *    we retrieve the data using the dmu.
 369  370   */
 370  371  typedef enum {
 371  372          WR_INDIRECT,    /* indirect - a large write (dmu_sync() data */
 372  373                          /* and put blkptr in log, rather than actual data) */
 373  374          WR_COPIED,      /* immediate - data is copied into lr_write_t */
 374  375          WR_NEED_COPY,   /* immediate - data needs to be copied if pushed */
 375  376          WR_NUM_STATES   /* number of states */
 376  377  } itx_wr_state_t;
 377  378  
 378  379  typedef struct itx {
 379  380          list_node_t     itx_node;       /* linkage on zl_itx_list */
 380  381          void            *itx_private;   /* type-specific opaque data */
 381  382          itx_wr_state_t  itx_wr_state;   /* write state */
 382  383          uint8_t         itx_sync;       /* synchronous transaction */
 383  384          uint64_t        itx_oid;        /* object id */
 384  385          lr_t            itx_lr;         /* common part of log record */
 385  386          /* followed by type-specific part of lr_xx_t and its immediate data */
 386  387  } itx_t;
 387  388  
 388  389  typedef int zil_parse_blk_func_t(zilog_t *zilog, blkptr_t *bp, void *arg,
 389  390      uint64_t txg);
 390  391  typedef int zil_parse_lr_func_t(zilog_t *zilog, lr_t *lr, void *arg,
 391  392      uint64_t txg);
 392  393  typedef int zil_replay_func_t(void *arg1, void *arg2, boolean_t byteswap);
 393  394  typedef int zil_get_data_t(void *arg, lr_write_t *lr, char *dbuf,
 394  395      struct lwb *lwb, zio_t *zio);
 395  396  
 396  397  extern int zil_parse(zilog_t *zilog, zil_parse_blk_func_t *parse_blk_func,
 397  398      zil_parse_lr_func_t *parse_lr_func, void *arg, uint64_t txg);
 398  399  
 399  400  extern void     zil_init(void);
 400  401  extern void     zil_fini(void);
 401  402  
 402  403  extern zilog_t  *zil_alloc(objset_t *os, zil_header_t *zh_phys);
 403  404  extern void     zil_free(zilog_t *zilog);
 404  405  
 405  406  extern zilog_t  *zil_open(objset_t *os, zil_get_data_t *get_data);
 406  407  extern void     zil_close(zilog_t *zilog);
 407  408  
 408  409  extern void     zil_replay(objset_t *os, void *arg,
 409  410      zil_replay_func_t *replay_func[TX_MAX_TYPE]);
 410  411  extern boolean_t zil_replaying(zilog_t *zilog, dmu_tx_t *tx);
 411  412  extern void     zil_destroy(zilog_t *zilog, boolean_t keep_first);
  
    | 
      ↓ open down ↓ | 
    41 lines elided | 
    
      ↑ open up ↑ | 
  
 412  413  extern void     zil_destroy_sync(zilog_t *zilog, dmu_tx_t *tx);
 413  414  extern void     zil_rollback_destroy(zilog_t *zilog, dmu_tx_t *tx);
 414  415  
 415  416  extern itx_t    *zil_itx_create(uint64_t txtype, size_t lrsize);
 416  417  extern void     zil_itx_destroy(itx_t *itx);
 417  418  extern void     zil_itx_assign(zilog_t *zilog, itx_t *itx, dmu_tx_t *tx);
 418  419  
 419  420  extern void     zil_commit(zilog_t *zilog, uint64_t oid);
 420  421  extern void     zil_commit_impl(zilog_t *zilog, uint64_t oid);
 421  422  
 422      -extern int      zil_reset(const char *osname, void *txarg);
      423 +extern int      zil_vdev_offline(const char *osname, void *txarg);
 423  424  extern int      zil_claim(struct dsl_pool *dp,
 424  425      struct dsl_dataset *ds, void *txarg);
 425  426  extern int      zil_check_log_chain(struct dsl_pool *dp,
 426  427      struct dsl_dataset *ds, void *tx);
 427  428  extern void     zil_sync(zilog_t *zilog, dmu_tx_t *tx);
 428  429  extern void     zil_clean(zilog_t *zilog, uint64_t synced_txg);
 429  430  
 430  431  extern int      zil_suspend(const char *osname, void **cookiep);
 431  432  extern void     zil_resume(void *cookie);
 432  433  
 433  434  extern void     zil_lwb_add_block(struct lwb *lwb, const blkptr_t *bp);
 434  435  extern void     zil_lwb_add_txg(struct lwb *lwb, uint64_t txg);
 435  436  extern int      zil_bp_tree_add(zilog_t *zilog, const blkptr_t *bp);
 436  437  
 437  438  extern void     zil_set_sync(zilog_t *zilog, uint64_t syncval);
 438  439  
 439  440  extern void     zil_set_logbias(zilog_t *zilog, uint64_t slogval);
 440  441  
 441  442  extern int zil_replay_disable;
 442  443  
 443  444  #ifdef  __cplusplus
 444  445  }
 445  446  #endif
 446  447  
 447  448  #endif  /* _SYS_ZIL_H */
  
    | 
      ↓ open down ↓ | 
    15 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX