#ifndef _SYS_VDEV_IMPL_H
#define _SYS_VDEV_IMPL_H
#include <sys/avl.h>
#include <sys/bpobj.h>
#include <sys/dmu.h>
#include <sys/metaslab.h>
#include <sys/nvpair.h>
#include <sys/space_map.h>
#include <sys/vdev.h>
#include <sys/dkio.h>
#include <sys/uberblock_impl.h>
#include <sys/vdev_indirect_mapping.h>
#include <sys/vdev_indirect_births.h>
#include <sys/vdev_removal.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct vdev_queue vdev_queue_t;
typedef struct vdev_cache vdev_cache_t;
typedef struct vdev_cache_entry vdev_cache_entry_t;
struct abd;
extern int zfs_vdev_queue_depth_pct;
extern int zfs_vdev_def_queue_depth;
extern uint32_t zfs_vdev_async_write_max_active;
typedef int vdev_open_func_t(vdev_t *vd, uint64_t *size, uint64_t *max_size,
uint64_t *ashift);
typedef void vdev_close_func_t(vdev_t *vd);
typedef uint64_t vdev_asize_func_t(vdev_t *vd, uint64_t psize);
typedef void vdev_io_start_func_t(zio_t *zio);
typedef void vdev_io_done_func_t(zio_t *zio);
typedef void vdev_state_change_func_t(vdev_t *vd, int, int);
typedef boolean_t vdev_need_resilver_func_t(vdev_t *vd, uint64_t, size_t);
typedef void vdev_hold_func_t(vdev_t *vd);
typedef void vdev_rele_func_t(vdev_t *vd);
typedef void vdev_remap_cb_t(uint64_t inner_offset, vdev_t *vd,
uint64_t offset, uint64_t size, void *arg);
typedef void vdev_remap_func_t(vdev_t *vd, uint64_t offset, uint64_t size,
vdev_remap_cb_t callback, void *arg);
typedef int vdev_dumpio_func_t(vdev_t *vd, caddr_t data, size_t size,
uint64_t offset, uint64_t origoffset, boolean_t doread, boolean_t isdump);
typedef void vdev_xlation_func_t(vdev_t *cvd, const range_seg64_t *in,
range_seg64_t *res);
typedef struct vdev_ops {
vdev_open_func_t *vdev_op_open;
vdev_close_func_t *vdev_op_close;
vdev_asize_func_t *vdev_op_asize;
vdev_io_start_func_t *vdev_op_io_start;
vdev_io_done_func_t *vdev_op_io_done;
vdev_state_change_func_t *vdev_op_state_change;
vdev_need_resilver_func_t *vdev_op_need_resilver;
vdev_hold_func_t *vdev_op_hold;
vdev_rele_func_t *vdev_op_rele;
vdev_remap_func_t *vdev_op_remap;
vdev_xlation_func_t *vdev_op_xlate;
vdev_dumpio_func_t *vdev_op_dumpio;
char vdev_op_type[16];
boolean_t vdev_op_leaf;
} vdev_ops_t;
struct vdev_cache_entry {
struct abd *ve_abd;
uint64_t ve_offset;
uint64_t ve_lastused;
avl_node_t ve_offset_node;
avl_node_t ve_lastused_node;
uint32_t ve_hits;
uint16_t ve_missed_update;
zio_t *ve_fill_io;
};
struct vdev_cache {
avl_tree_t vc_offset_tree;
avl_tree_t vc_lastused_tree;
kmutex_t vc_lock;
};
typedef struct vdev_queue_class {
uint32_t vqc_active;
avl_tree_t vqc_queued_tree;
} vdev_queue_class_t;
struct vdev_queue {
vdev_t *vq_vdev;
vdev_queue_class_t vq_class[ZIO_PRIORITY_NUM_QUEUEABLE];
avl_tree_t vq_active_tree;
avl_tree_t vq_read_offset_tree;
avl_tree_t vq_write_offset_tree;
avl_tree_t vq_trim_offset_tree;
uint64_t vq_last_offset;
hrtime_t vq_io_complete_ts;
kmutex_t vq_lock;
};
typedef enum vdev_alloc_bias {
VDEV_BIAS_NONE,
VDEV_BIAS_LOG,
VDEV_BIAS_SPECIAL,
VDEV_BIAS_DEDUP
} vdev_alloc_bias_t;
typedef struct vdev_indirect_config {
uint64_t vic_mapping_object;
uint64_t vic_births_object;
uint64_t vic_prev_indirect_vdev;
} vdev_indirect_config_t;
struct vdev {
uint64_t vdev_id;
uint64_t vdev_guid;
uint64_t vdev_guid_sum;
uint64_t vdev_orig_guid;
uint64_t vdev_asize;
uint64_t vdev_min_asize;
uint64_t vdev_max_asize;
uint64_t vdev_ashift;
uint64_t vdev_state;
uint64_t vdev_prevstate;
vdev_ops_t *vdev_ops;
spa_t *vdev_spa;
void *vdev_tsd;
vnode_t *vdev_name_vp;
vnode_t *vdev_devid_vp;
vdev_t *vdev_top;
vdev_t *vdev_parent;
vdev_t **vdev_child;
uint64_t vdev_children;
vdev_stat_t vdev_stat;
vdev_stat_ex_t vdev_stat_ex;
boolean_t vdev_expanding;
boolean_t vdev_reopening;
boolean_t vdev_nonrot;
int vdev_open_error;
kthread_t *vdev_open_thread;
uint64_t vdev_crtxg;
uint64_t vdev_ms_array;
uint64_t vdev_ms_shift;
uint64_t vdev_ms_count;
metaslab_group_t *vdev_mg;
metaslab_t **vdev_ms;
txg_list_t vdev_ms_list;
txg_list_t vdev_dtl_list;
txg_node_t vdev_txg_node;
boolean_t vdev_remove_wanted;
boolean_t vdev_probe_wanted;
list_node_t vdev_config_dirty_node;
list_node_t vdev_state_dirty_node;
uint64_t vdev_deflate_ratio;
uint64_t vdev_islog;
uint64_t vdev_removing;
boolean_t vdev_ishole;
uint64_t vdev_top_zap;
vdev_alloc_bias_t vdev_alloc_bias;
space_map_t *vdev_checkpoint_sm;
boolean_t vdev_initialize_exit_wanted;
vdev_initializing_state_t vdev_initialize_state;
list_node_t vdev_initialize_node;
kthread_t *vdev_initialize_thread;
kmutex_t vdev_initialize_lock;
kcondvar_t vdev_initialize_cv;
uint64_t vdev_initialize_offset[TXG_SIZE];
uint64_t vdev_initialize_last_offset;
range_tree_t *vdev_initialize_tree;
uint64_t vdev_initialize_bytes_est;
uint64_t vdev_initialize_bytes_done;
time_t vdev_initialize_action_time;
boolean_t vdev_trim_exit_wanted;
boolean_t vdev_autotrim_exit_wanted;
vdev_trim_state_t vdev_trim_state;
list_node_t vdev_trim_node;
kmutex_t vdev_autotrim_lock;
kcondvar_t vdev_autotrim_cv;
kthread_t *vdev_autotrim_thread;
kmutex_t vdev_trim_lock;
kcondvar_t vdev_trim_cv;
kthread_t *vdev_trim_thread;
uint64_t vdev_trim_offset[TXG_SIZE];
uint64_t vdev_trim_last_offset;
uint64_t vdev_trim_bytes_est;
uint64_t vdev_trim_bytes_done;
uint64_t vdev_trim_rate;
uint64_t vdev_trim_partial;
uint64_t vdev_trim_secure;
time_t vdev_trim_action_time;
uint64_t vdev_autotrim_bytes_done;
kmutex_t vdev_initialize_io_lock;
kcondvar_t vdev_initialize_io_cv;
uint64_t vdev_initialize_inflight;
kmutex_t vdev_trim_io_lock;
kcondvar_t vdev_trim_io_cv;
uint64_t vdev_trim_inflight[2];
vdev_indirect_config_t vdev_indirect_config;
krwlock_t vdev_indirect_rwlock;
vdev_indirect_mapping_t *vdev_indirect_mapping;
vdev_indirect_births_t *vdev_indirect_births;
kmutex_t vdev_obsolete_lock;
range_tree_t *vdev_obsolete_segments;
space_map_t *vdev_obsolete_sm;
kmutex_t vdev_scan_io_queue_lock;
struct dsl_scan_io_queue *vdev_scan_io_queue;
range_tree_t *vdev_dtl[DTL_TYPES];
space_map_t *vdev_dtl_sm;
txg_node_t vdev_dtl_node;
uint64_t vdev_dtl_object;
uint64_t vdev_psize;
uint64_t vdev_wholedisk;
uint64_t vdev_offline;
uint64_t vdev_faulted;
uint64_t vdev_degraded;
uint64_t vdev_removed;
uint64_t vdev_resilver_txg;
uint64_t vdev_nparity;
char *vdev_path;
char *vdev_devid;
char *vdev_physpath;
char *vdev_fru;
uint64_t vdev_not_present;
uint64_t vdev_unspare;
boolean_t vdev_nowritecache;
boolean_t vdev_has_trim;
boolean_t vdev_has_securetrim;
boolean_t vdev_checkremove;
boolean_t vdev_forcefault;
boolean_t vdev_splitting;
boolean_t vdev_delayed_close;
boolean_t vdev_tmpoffline;
boolean_t vdev_detached;
boolean_t vdev_cant_read;
boolean_t vdev_cant_write;
boolean_t vdev_isspare;
boolean_t vdev_isl2cache;
boolean_t vdev_resilver_deferred;
vdev_queue_t vdev_queue;
vdev_cache_t vdev_cache;
spa_aux_vdev_t *vdev_aux;
zio_t *vdev_probe_zio;
vdev_aux_t vdev_label_aux;
uint64_t vdev_leaf_zap;
hrtime_t vdev_mmp_pending;
uint64_t vdev_mmp_kstat_id;
list_node_t vdev_leaf_node;
kmutex_t vdev_dtl_lock;
kmutex_t vdev_stat_lock;
kmutex_t vdev_probe_lock;
};
#define VDEV_RAIDZ_MAXPARITY 3
#define VDEV_PAD_SIZE (8 << 10)
#define VDEV_SKIP_SIZE VDEV_PAD_SIZE * 2
#define VDEV_PHYS_SIZE (112 << 10)
#define VDEV_UBERBLOCK_RING (128 << 10)
#define MMP_BLOCKS_PER_LABEL 1
#define MAX_UBERBLOCK_SHIFT (13)
#define VDEV_UBERBLOCK_SHIFT(vd) \
MIN(MAX((vd)->vdev_top->vdev_ashift, UBERBLOCK_SHIFT), \
MAX_UBERBLOCK_SHIFT)
#define VDEV_UBERBLOCK_COUNT(vd) \
(VDEV_UBERBLOCK_RING >> VDEV_UBERBLOCK_SHIFT(vd))
#define VDEV_UBERBLOCK_OFFSET(vd, n) \
offsetof(vdev_label_t, vl_uberblock[(n) << VDEV_UBERBLOCK_SHIFT(vd)])
#define VDEV_UBERBLOCK_SIZE(vd) (1ULL << VDEV_UBERBLOCK_SHIFT(vd))
typedef struct vdev_phys {
char vp_nvlist[VDEV_PHYS_SIZE - sizeof (zio_eck_t)];
zio_eck_t vp_zbt;
} vdev_phys_t;
typedef enum vbe_vers {
VB_RAW = 0,
VB_NVLIST = 1
} vbe_vers_t;
typedef struct vdev_boot_envblock {
uint64_t vbe_version;
char vbe_bootenv[VDEV_PAD_SIZE - sizeof (uint64_t) -
sizeof (zio_eck_t)];
zio_eck_t vbe_zbt;
} vdev_boot_envblock_t;
CTASSERT(sizeof (vdev_boot_envblock_t) == VDEV_PAD_SIZE);
typedef struct vdev_label {
char vl_pad1[VDEV_PAD_SIZE];
vdev_boot_envblock_t vl_be;
vdev_phys_t vl_vdev_phys;
char vl_uberblock[VDEV_UBERBLOCK_RING];
} vdev_label_t;
#define VDD_METASLAB 0x01
#define VDD_DTL 0x02
#define VDEV_BOOT_OFFSET (2 * sizeof (vdev_label_t))
#define VDEV_BOOT_SIZE (7ULL << 19)
#define VDEV_LABEL_START_SIZE (2 * sizeof (vdev_label_t) + VDEV_BOOT_SIZE)
#define VDEV_LABEL_END_SIZE (2 * sizeof (vdev_label_t))
#define VDEV_LABELS 4
#define VDEV_BEST_LABEL VDEV_LABELS
#define VDEV_ALLOC_LOAD 0
#define VDEV_ALLOC_ADD 1
#define VDEV_ALLOC_SPARE 2
#define VDEV_ALLOC_L2CACHE 3
#define VDEV_ALLOC_ROOTPOOL 4
#define VDEV_ALLOC_SPLIT 5
#define VDEV_ALLOC_ATTACH 6
extern vdev_t *vdev_alloc_common(spa_t *spa, uint_t id, uint64_t guid,
vdev_ops_t *ops);
extern int vdev_alloc(spa_t *spa, vdev_t **vdp, nvlist_t *config,
vdev_t *parent, uint_t id, int alloctype);
extern void vdev_free(vdev_t *vd);
extern void vdev_add_child(vdev_t *pvd, vdev_t *cvd);
extern void vdev_remove_child(vdev_t *pvd, vdev_t *cvd);
extern void vdev_compact_children(vdev_t *pvd);
extern vdev_t *vdev_add_parent(vdev_t *cvd, vdev_ops_t *ops);
extern void vdev_remove_parent(vdev_t *cvd);
extern boolean_t vdev_log_state_valid(vdev_t *vd);
extern int vdev_load(vdev_t *vd);
extern int vdev_dtl_load(vdev_t *vd);
extern void vdev_sync(vdev_t *vd, uint64_t txg);
extern void vdev_sync_done(vdev_t *vd, uint64_t txg);
extern void vdev_dirty(vdev_t *vd, int flags, void *arg, uint64_t txg);
extern void vdev_dirty_leaves(vdev_t *vd, int flags, uint64_t txg);
extern vdev_ops_t vdev_root_ops;
extern vdev_ops_t vdev_mirror_ops;
extern vdev_ops_t vdev_replacing_ops;
extern vdev_ops_t vdev_raidz_ops;
extern vdev_ops_t vdev_disk_ops;
extern vdev_ops_t vdev_file_ops;
extern vdev_ops_t vdev_missing_ops;
extern vdev_ops_t vdev_hole_ops;
extern vdev_ops_t vdev_spare_ops;
extern vdev_ops_t vdev_indirect_ops;
extern void vdev_default_xlate(vdev_t *vd, const range_seg64_t *in,
range_seg64_t *out);
extern uint64_t vdev_default_asize(vdev_t *vd, uint64_t psize);
extern uint64_t vdev_get_min_asize(vdev_t *vd);
extern void vdev_set_min_asize(vdev_t *vd);
extern int zfs_vdev_standard_sm_blksz;
extern int zfs_vdev_cache_size;
extern void vdev_indirect_sync_obsolete(vdev_t *vd, dmu_tx_t *tx);
extern boolean_t vdev_indirect_should_condense(vdev_t *vd);
extern void spa_condense_indirect_start_sync(vdev_t *vd, dmu_tx_t *tx);
extern int vdev_obsolete_sm_object(vdev_t *vd);
extern boolean_t vdev_obsolete_counts_are_precise(vdev_t *vd);
int vdev_checkpoint_sm_object(vdev_t *vd);
typedef struct vdev_buf {
buf_t vb_buf;
zio_t *vb_io;
} vdev_buf_t;
extern int vdev_disk_read_rootlabel(const char *, const char *, nvlist_t **);
extern void vdev_disk_preroot_init(const char *);
extern void vdev_disk_preroot_fini(void);
extern const char *vdev_disk_preroot_lookup(uint64_t, uint64_t);
extern const char *vdev_disk_preroot_force_path(void);
#ifdef __cplusplus
}
#endif
#endif