1168404Spjd/* 2168404Spjd * CDDL HEADER START 3168404Spjd * 4168404Spjd * The contents of this file are subject to the terms of the 5168404Spjd * Common Development and Distribution License (the "License"). 6168404Spjd * You may not use this file except in compliance with the License. 7168404Spjd * 8168404Spjd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9168404Spjd * or http://www.opensolaris.org/os/licensing. 10168404Spjd * See the License for the specific language governing permissions 11168404Spjd * and limitations under the License. 12168404Spjd * 13168404Spjd * When distributing Covered Code, include this CDDL HEADER in each 14168404Spjd * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15168404Spjd * If applicable, add the following below this CDDL HEADER, with the 16168404Spjd * fields enclosed by brackets "[]" replaced with your own identifying 17168404Spjd * information: Portions Copyright [yyyy] [name of copyright owner] 18168404Spjd * 19168404Spjd * CDDL HEADER END 20168404Spjd */ 21168404Spjd/* 22219089Spjd * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 23239620Smm * Copyright (c) 2012 by Delphix. All rights reserved. 24297112Smav * Copyright (c) 2014 Integros [integros.com] 25168404Spjd */ 26168404Spjd 27219089Spjd/* Portions Copyright 2010 Robert Milkowski */ 28219089Spjd 29168404Spjd#ifndef _SYS_ZIL_IMPL_H 30168404Spjd#define _SYS_ZIL_IMPL_H 31168404Spjd 32168404Spjd#include <sys/zil.h> 33168404Spjd#include <sys/dmu_objset.h> 34168404Spjd 35168404Spjd#ifdef __cplusplus 36168404Spjdextern "C" { 37168404Spjd#endif 38168404Spjd 39168404Spjd/* 40168404Spjd * Log write buffer. 41168404Spjd */ 42168404Spjdtypedef struct lwb { 43168404Spjd zilog_t *lwb_zilog; /* back pointer to log struct */ 44168404Spjd blkptr_t lwb_blk; /* on disk address of this log blk */ 45320496Savg boolean_t lwb_slog; /* lwb_blk is on SLOG device */ 46168404Spjd int lwb_nused; /* # used bytes in buffer */ 47168404Spjd int lwb_sz; /* size of block and buffer */ 48168404Spjd char *lwb_buf; /* log write buffer */ 49168404Spjd zio_t *lwb_zio; /* zio for this buffer */ 50219089Spjd dmu_tx_t *lwb_tx; /* tx for log block allocation */ 51168404Spjd uint64_t lwb_max_txg; /* highest txg in this lwb */ 52168404Spjd list_node_t lwb_node; /* zilog->zl_lwb_list linkage */ 53168404Spjd} lwb_t; 54168404Spjd 55168404Spjd/* 56219089Spjd * Intent log transaction lists 57219089Spjd */ 58219089Spjdtypedef struct itxs { 59219089Spjd list_t i_sync_list; /* list of synchronous itxs */ 60219089Spjd avl_tree_t i_async_tree; /* tree of foids for async itxs */ 61219089Spjd} itxs_t; 62219089Spjd 63219089Spjdtypedef struct itxg { 64219089Spjd kmutex_t itxg_lock; /* lock for this structure */ 65219089Spjd uint64_t itxg_txg; /* txg for this chain */ 66219089Spjd itxs_t *itxg_itxs; /* sync and async itxs */ 67219089Spjd} itxg_t; 68219089Spjd 69219089Spjd/* for async nodes we build up an AVL tree of lists of async itxs per file */ 70219089Spjdtypedef struct itx_async_node { 71219089Spjd uint64_t ia_foid; /* file object id */ 72219089Spjd list_t ia_list; /* list of async itxs for this foid */ 73219089Spjd avl_node_t ia_node; /* AVL tree linkage */ 74219089Spjd} itx_async_node_t; 75219089Spjd 76219089Spjd/* 77185029Spjd * Vdev flushing: during a zil_commit(), we build up an AVL tree of the vdevs 78185029Spjd * we've touched so we know which ones need a write cache flush at the end. 79168404Spjd */ 80185029Spjdtypedef struct zil_vdev_node { 81185029Spjd uint64_t zv_vdev; /* vdev to be flushed */ 82185029Spjd avl_node_t zv_node; /* AVL tree linkage */ 83185029Spjd} zil_vdev_node_t; 84168404Spjd 85219089Spjd#define ZIL_PREV_BLKS 16 86219089Spjd 87168404Spjd/* 88168404Spjd * Stable storage intent log management structure. One per dataset. 89168404Spjd */ 90168404Spjdstruct zilog { 91168404Spjd kmutex_t zl_lock; /* protects most zilog_t fields */ 92168404Spjd struct dsl_pool *zl_dmu_pool; /* DSL pool */ 93168404Spjd spa_t *zl_spa; /* handle for read/write log */ 94168404Spjd const zil_header_t *zl_header; /* log header buffer */ 95168404Spjd objset_t *zl_os; /* object set we're logging */ 96168404Spjd zil_get_data_t *zl_get_data; /* callback to get object content */ 97168404Spjd zio_t *zl_root_zio; /* log writer root zio */ 98219089Spjd uint64_t zl_lr_seq; /* on-disk log record sequence number */ 99219089Spjd uint64_t zl_commit_lr_seq; /* last committed on-disk lr seq */ 100168404Spjd uint64_t zl_destroy_txg; /* txg of last zil_destroy() */ 101209962Smm uint64_t zl_replayed_seq[TXG_SIZE]; /* last replayed rec seq */ 102209962Smm uint64_t zl_replaying_seq; /* current replay seq number */ 103168404Spjd uint32_t zl_suspend; /* log suspend count */ 104168404Spjd kcondvar_t zl_cv_writer; /* log writer thread completion */ 105168404Spjd kcondvar_t zl_cv_suspend; /* log suspend completion */ 106168404Spjd uint8_t zl_suspending; /* log is currently suspending */ 107168404Spjd uint8_t zl_keep_first; /* keep first log block in destroy */ 108209962Smm uint8_t zl_replay; /* replaying records while set */ 109168404Spjd uint8_t zl_stop_sync; /* for debugging */ 110168404Spjd uint8_t zl_writer; /* boolean: write setup in progress */ 111219089Spjd uint8_t zl_logbias; /* latency or throughput */ 112219089Spjd uint8_t zl_sync; /* synchronous or asynchronous */ 113219089Spjd int zl_parse_error; /* last zil_parse() error */ 114219089Spjd uint64_t zl_parse_blk_seq; /* highest blk seq on last parse */ 115219089Spjd uint64_t zl_parse_lr_seq; /* highest lr seq on last parse */ 116219089Spjd uint64_t zl_parse_blk_count; /* number of blocks parsed */ 117219089Spjd uint64_t zl_parse_lr_count; /* number of log records parsed */ 118219089Spjd uint64_t zl_next_batch; /* next batch number */ 119219089Spjd uint64_t zl_com_batch; /* committed batch number */ 120219089Spjd kcondvar_t zl_cv_batch[2]; /* batch condition variables */ 121219089Spjd itxg_t zl_itxg[TXG_SIZE]; /* intent log txg chains */ 122219089Spjd list_t zl_itx_commit_list; /* itx list to be committed */ 123168404Spjd uint64_t zl_cur_used; /* current commit log size used */ 124168404Spjd list_t zl_lwb_list; /* in-flight log write list */ 125185029Spjd kmutex_t zl_vdev_lock; /* protects zl_vdev_tree */ 126185029Spjd avl_tree_t zl_vdev_tree; /* vdevs to flush in zil_commit() */ 127168404Spjd taskq_t *zl_clean_taskq; /* runs lwb and itx clean tasks */ 128219089Spjd avl_tree_t zl_bp_tree; /* track bps during log parse */ 129168404Spjd clock_t zl_replay_time; /* lbolt of when replay started */ 130168404Spjd uint64_t zl_replay_blks; /* number of log blocks replayed */ 131219089Spjd zil_header_t zl_old_header; /* debugging aid */ 132219089Spjd uint_t zl_prev_blks[ZIL_PREV_BLKS]; /* size - sector rounded */ 133219089Spjd uint_t zl_prev_rotor; /* rotor for zl_prev[] */ 134239620Smm txg_node_t zl_dirty_link; /* protected by dp_dirty_zilogs list */ 135168404Spjd}; 136168404Spjd 137219089Spjdtypedef struct zil_bp_node { 138168404Spjd dva_t zn_dva; 139168404Spjd avl_node_t zn_node; 140219089Spjd} zil_bp_node_t; 141168404Spjd 142276081Sdelphij#define ZIL_MAX_LOG_DATA (SPA_OLD_MAXBLOCKSIZE - sizeof (zil_chain_t) - \ 143219089Spjd sizeof (lr_write_t)) 144320496Savg#define ZIL_MAX_COPIED_DATA \ 145320496Savg ((SPA_OLD_MAXBLOCKSIZE - sizeof (zil_chain_t)) / 2 - sizeof (lr_write_t)) 146219089Spjd 147168404Spjd#ifdef __cplusplus 148168404Spjd} 149168404Spjd#endif 150168404Spjd 151168404Spjd#endif /* _SYS_ZIL_IMPL_H */ 152