/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #ifndef _ZIO_H #define _ZIO_H #pragma ident "%Z%%M% %I% %E% SMI" #include #include #include #include #include #include #ifdef __cplusplus extern "C" { #endif #define ZBT_MAGIC 0x210da7ab10c7a11ULL /* zio data bloc tail */ typedef struct zio_block_tail { uint64_t zbt_magic; /* for validation, endianness */ zio_cksum_t zbt_cksum; /* 256-bit checksum */ } zio_block_tail_t; /* * Gang block headers are self-checksumming and contain an array * of block pointers. */ #define SPA_GANGBLOCKSIZE SPA_MINBLOCKSIZE #define SPA_GBH_NBLKPTRS ((SPA_GANGBLOCKSIZE - \ sizeof (zio_block_tail_t)) / sizeof (blkptr_t)) #define SPA_GBH_FILLER ((SPA_GANGBLOCKSIZE - \ sizeof (zio_block_tail_t) - \ (SPA_GBH_NBLKPTRS * sizeof (blkptr_t))) /\ sizeof (uint64_t)) #define ZIO_GET_DVA(zio) (&(zio)->io_bp->blk_dva[(zio)->io_dva_index]) #define ZIO_GET_IOSIZE(zio) \ (DVA_GET_GANG(ZIO_GET_DVA(zio)) ? \ SPA_GANGBLOCKSIZE : BP_GET_PSIZE((zio)->io_bp)) typedef struct zio_gbh { blkptr_t zg_blkptr[SPA_GBH_NBLKPTRS]; uint64_t zg_filler[SPA_GBH_FILLER]; zio_block_tail_t zg_tail; } zio_gbh_phys_t; enum zio_checksum { ZIO_CHECKSUM_INHERIT = 0, ZIO_CHECKSUM_ON, ZIO_CHECKSUM_OFF, ZIO_CHECKSUM_LABEL, ZIO_CHECKSUM_GANG_HEADER, ZIO_CHECKSUM_ZILOG, ZIO_CHECKSUM_FLETCHER_2, ZIO_CHECKSUM_FLETCHER_4, ZIO_CHECKSUM_SHA256, ZIO_CHECKSUM_FUNCTIONS }; #define ZIO_CHECKSUM_ON_VALUE ZIO_CHECKSUM_FLETCHER_2 #define ZIO_CHECKSUM_DEFAULT ZIO_CHECKSUM_ON enum zio_compress { ZIO_COMPRESS_INHERIT = 0, ZIO_COMPRESS_ON, ZIO_COMPRESS_OFF, ZIO_COMPRESS_LZJB, ZIO_COMPRESS_FUNCTIONS }; #define ZIO_COMPRESS_ON_VALUE ZIO_COMPRESS_LZJB #define ZIO_COMPRESS_DEFAULT ZIO_COMPRESS_OFF #define ZIO_PRIORITY_NOW (zio_priority_table[0]) #define ZIO_PRIORITY_SYNC_READ (zio_priority_table[1]) #define ZIO_PRIORITY_SYNC_WRITE (zio_priority_table[2]) #define ZIO_PRIORITY_ASYNC_READ (zio_priority_table[3]) #define ZIO_PRIORITY_ASYNC_WRITE (zio_priority_table[4]) #define ZIO_PRIORITY_FREE (zio_priority_table[5]) #define ZIO_PRIORITY_CACHE_FILL (zio_priority_table[6]) #define ZIO_PRIORITY_LOG_WRITE (zio_priority_table[7]) #define ZIO_PRIORITY_RESILVER (zio_priority_table[8]) #define ZIO_PRIORITY_SCRUB (zio_priority_table[9]) #define ZIO_PRIORITY_TABLE_SIZE 10 #define ZIO_FLAG_MUSTSUCCEED 0x0000 #define ZIO_FLAG_CANFAIL 0x0001 #define ZIO_FLAG_FAILFAST 0x0002 #define ZIO_FLAG_CONFIG_HELD 0x0004 #define ZIO_FLAG_DONT_CACHE 0x0010 #define ZIO_FLAG_DONT_QUEUE 0x0020 #define ZIO_FLAG_DONT_PROPAGATE 0x0040 #define ZIO_FLAG_DONT_RETRY 0x0080 #define ZIO_FLAG_PHYSICAL 0x0100 #define ZIO_FLAG_IO_BYPASS 0x0200 #define ZIO_FLAG_IO_REPAIR 0x0400 #define ZIO_FLAG_SPECULATIVE 0x0800 #define ZIO_FLAG_RESILVER 0x1000 #define ZIO_FLAG_SCRUB 0x2000 #define ZIO_FLAG_GANG_INHERIT \ (ZIO_FLAG_CANFAIL | \ ZIO_FLAG_FAILFAST | \ ZIO_FLAG_CONFIG_HELD | \ ZIO_FLAG_DONT_RETRY | \ ZIO_FLAG_IO_REPAIR | \ ZIO_FLAG_SPECULATIVE | \ ZIO_FLAG_RESILVER | \ ZIO_FLAG_SCRUB) #define ZIO_FLAG_VDEV_INHERIT \ (ZIO_FLAG_GANG_INHERIT | \ ZIO_FLAG_DONT_CACHE | \ ZIO_FLAG_PHYSICAL) /* * We'll take the unused errno 'EBADE' (from the Convergent graveyard) * to indicate checksum errors. */ #define ECKSUM EBADE typedef struct zio zio_t; typedef void zio_done_func_t(zio_t *zio); typedef struct zio_transform zio_transform_t; extern uint8_t zio_priority_table[ZIO_PRIORITY_TABLE_SIZE]; extern char *zio_type_name[ZIO_TYPES]; struct zio { /* Core information about this I/O */ zio_t *io_parent; zio_t *io_root; spa_t *io_spa; int io_checksum; int io_compress; int io_dva_index; uint64_t io_txg; blkptr_t *io_bp; blkptr_t io_bp_copy; zio_t *io_child; zio_t *io_sibling_prev; zio_t *io_sibling_next; zio_transform_t *io_transform_stack; /* Callback info */ zio_done_func_t *io_done; void *io_private; blkptr_t io_bp_orig; /* Data represented by this I/O */ void *io_data; uint64_t io_size; /* Stuff for the vdev stack */ vdev_t *io_vd; void *io_vsd; uint64_t io_offset; uint64_t io_deadline; uint64_t io_timestamp; avl_node_t io_offset_node; avl_node_t io_deadline_node; avl_tree_t *io_vdev_tree; zio_t *io_delegate_list; zio_t *io_delegate_next; zio_t *io_retry_next; list_node_t io_pending; /* Internal pipeline state */ int io_flags; uint8_t io_type; uint8_t io_stage; uint8_t io_stalled; uint8_t io_priority; struct dk_callback io_dk_callback; int io_cmd; int io_retries; int io_error; uint32_t io_numerrors; uint32_t io_pipeline; uint32_t io_async_stages; uint64_t io_children_notready; uint64_t io_children_notdone; void *io_waiter; kmutex_t io_lock; kcondvar_t io_cv; }; extern zio_t *zio_null(zio_t *pio, spa_t *spa, zio_done_func_t *done, void *private, int flags); extern zio_t *zio_root(spa_t *spa, zio_done_func_t *done, void *private, int flags); extern zio_t *zio_read(zio_t *pio, spa_t *spa, blkptr_t *bp, void *data, uint64_t size, zio_done_func_t *done, void *private, int priority, int flags); extern zio_t *zio_write(zio_t *pio, spa_t *spa, int checksum, int compress, uint64_t txg, blkptr_t *bp, void *data, uint64_t size, zio_done_func_t *done, void *private, int priority, int flags); extern zio_t *zio_rewrite(zio_t *pio, spa_t *spa, int checksum, uint64_t txg, blkptr_t *bp, void *data, uint64_t size, zio_done_func_t *done, void *private, int priority, int flags); extern zio_t *zio_free(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp, zio_done_func_t *done, void *private); extern zio_t *zio_claim(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp, zio_done_func_t *done, void *private); extern zio_t *zio_ioctl(zio_t *pio, spa_t *spa, vdev_t *vd, int cmd, zio_done_func_t *done, void *private, int priority, int flags); extern zio_t *zio_read_phys(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size, void *data, int checksum, zio_done_func_t *done, void *private, int priority, int flags); extern zio_t *zio_write_phys(zio_t *pio, vdev_t *vd, uint64_t offset, uint64_t size, void *data, int checksum, zio_done_func_t *done, void *private, int priority, int flags); extern int zio_alloc_blk(spa_t *spa, int checksum, uint64_t size, blkptr_t *bp, uint64_t txg); extern void zio_free_blk(spa_t *spa, blkptr_t *bp, uint64_t txg); extern int zio_wait(zio_t *zio); extern void zio_nowait(zio_t *zio); extern void *zio_buf_alloc(size_t size); extern void zio_buf_free(void *buf, size_t size); /* * Move an I/O to the next stage of the pipeline and execute that stage. * There's no locking on io_stage because there's no legitimate way for * multiple threads to be attempting to process the same I/O. */ extern void zio_next_stage(zio_t *zio); extern void zio_next_stage_async(zio_t *zio); extern void zio_wait_children_done(zio_t *zio); /* * Delegate I/O to a child vdev. */ extern zio_t *zio_vdev_child_io(zio_t *zio, blkptr_t *bp, vdev_t *vd, uint64_t offset, void *data, uint64_t size, int type, int priority, int flags, zio_done_func_t *done, void *private); extern void zio_vdev_io_bypass(zio_t *zio); extern void zio_vdev_io_reissue(zio_t *zio); extern void zio_vdev_io_redone(zio_t *zio); extern void zio_checksum_verified(zio_t *zio); extern void zio_set_gang_verifier(zio_t *zio, zio_cksum_t *zcp); extern uint8_t zio_checksum_select(uint8_t child, uint8_t parent); extern uint8_t zio_compress_select(uint8_t child, uint8_t parent); /* * Initial setup and teardown. */ extern void zio_init(void); extern void zio_fini(void); #ifdef __cplusplus } #endif #endif /* _ZIO_H */