1*5b6e6e1eSkn /* $OpenBSD: softraidvar.h,v 1.176 2022/12/19 15:27:06 kn Exp $ */ 27195049bSmarco /* 3989b6914Sgrunk * Copyright (c) 2006 Marco Peereboom <marco@peereboom.us> 47fe2bdbeSckuethe * Copyright (c) 2008 Chris Kuethe <ckuethe@openbsd.org> 57195049bSmarco * 67195049bSmarco * Permission to use, copy, modify, and distribute this software for any 77195049bSmarco * purpose with or without fee is hereby granted, provided that the above 87195049bSmarco * copyright notice and this permission notice appear in all copies. 97195049bSmarco * 107195049bSmarco * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 117195049bSmarco * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 127195049bSmarco * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 137195049bSmarco * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 147195049bSmarco * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 157195049bSmarco * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 167195049bSmarco * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 177195049bSmarco */ 187195049bSmarco 19f18dcc9cStedu #ifndef SOFTRAIDVAR_H 20f18dcc9cStedu #define SOFTRAIDVAR_H 21f18dcc9cStedu 22bccb2f38Skrw #define SR_META_VERSION 6 /* bump when sr_metadata changes */ 23f6e5141fSjsing #define SR_META_SIZE 64 /* save space at chunk beginning */ 24f6e5141fSjsing #define SR_META_OFFSET 16 /* skip 8192 bytes at chunk beginning */ 25f6e5141fSjsing 26f6e5141fSjsing #define SR_BOOT_OFFSET (SR_META_OFFSET + SR_META_SIZE) 27f6e5141fSjsing #define SR_BOOT_LOADER_SIZE 320 /* Size of boot loader storage. */ 28f6e5141fSjsing #define SR_BOOT_LOADER_OFFSET SR_BOOT_OFFSET 29f6e5141fSjsing #define SR_BOOT_BLOCKS_SIZE 128 /* Size of boot block storage. */ 30f6e5141fSjsing #define SR_BOOT_BLOCKS_OFFSET (SR_BOOT_LOADER_OFFSET + SR_BOOT_LOADER_SIZE) 31f6e5141fSjsing #define SR_BOOT_SIZE (SR_BOOT_LOADER_SIZE + SR_BOOT_BLOCKS_SIZE) 32f6e5141fSjsing 33e7d4f752Sderaadt #define SR_CRYPTO_MAXKEYBYTES 32 /* max bytes in a key (AES-XTS-256) */ 34e7d4f752Sderaadt #define SR_CRYPTO_MAXKEYS 32 /* max keys per volume */ 35e7d4f752Sderaadt #define SR_CRYPTO_KEYBITS 512 /* AES-XTS with 2 * 256 bit keys */ 36e7d4f752Sderaadt #define SR_CRYPTO_KEYBYTES (SR_CRYPTO_KEYBITS >> 3) 37e7d4f752Sderaadt #define SR_CRYPTO_KDFHINTBYTES 256 /* size of opaque KDF hint */ 38e7d4f752Sderaadt #define SR_CRYPTO_CHECKBYTES 64 /* size of generic key chksum struct */ 39e7d4f752Sderaadt #define SR_CRYPTO_KEY_BLKSHIFT 30 /* 0.5TB per key */ 404fe5a5deSjsing #define SR_CRYPTO_KEY_BLKSIZE (1ULL << SR_CRYPTO_KEY_BLKSHIFT) 414fe5a5deSjsing #define SR_CRYPTO_MAXSIZE (SR_CRYPTO_KEY_BLKSIZE * SR_CRYPTO_MAXKEYS) 42e7d4f752Sderaadt 4345d888eeSjsing /* 4445d888eeSjsing * sr_crypto_genkdf is a generic hint for the KDF performed in userland and 4545d888eeSjsing * is not interpreted by the kernel. 4645d888eeSjsing */ 47e7d4f752Sderaadt struct sr_crypto_genkdf { 48e7d4f752Sderaadt u_int32_t len; 49e7d4f752Sderaadt u_int32_t type; 50e7d4f752Sderaadt #define SR_CRYPTOKDFT_INVALID 0 51ea67ad9aSjsing #define SR_CRYPTOKDFT_PKCS5_PBKDF2 1 52e7d4f752Sderaadt #define SR_CRYPTOKDFT_KEYDISK 2 533487a6b1Sjsing #define SR_CRYPTOKDFT_BCRYPT_PBKDF 3 54e7d4f752Sderaadt }; 55e7d4f752Sderaadt 5645d888eeSjsing /* 573487a6b1Sjsing * sr_crypto_pbkdf is a hint for a PBKDF performed in userland and is not 583487a6b1Sjsing * interpreted by the kernel. 5945d888eeSjsing */ 603487a6b1Sjsing struct sr_crypto_pbkdf { 613487a6b1Sjsing struct sr_crypto_genkdf generic; 62e7d4f752Sderaadt u_int32_t rounds; 63e7d4f752Sderaadt u_int8_t salt[128]; 64e7d4f752Sderaadt }; 65e7d4f752Sderaadt 66e7d4f752Sderaadt /* 6745d888eeSjsing * sr_crypto_kdfinfo is used to copy masking keys and KDF hints from/to 6845d888eeSjsing * userland. The embedded hint structures are not interpreted by the kernel. 69e7d4f752Sderaadt */ 70e7d4f752Sderaadt struct sr_crypto_kdfinfo { 71e7d4f752Sderaadt u_int32_t len; 72e7d4f752Sderaadt u_int32_t flags; 73e7d4f752Sderaadt #define SR_CRYPTOKDF_INVALID (0) 74e7d4f752Sderaadt #define SR_CRYPTOKDF_KEY (1<<0) 75e7d4f752Sderaadt #define SR_CRYPTOKDF_HINT (1<<1) 76e7d4f752Sderaadt u_int8_t maskkey[SR_CRYPTO_MAXKEYBYTES]; 77e7d4f752Sderaadt union { 78e7d4f752Sderaadt struct sr_crypto_genkdf generic; 793487a6b1Sjsing struct sr_crypto_pbkdf pbkdf; 80e7d4f752Sderaadt } _kdfhint; 81e7d4f752Sderaadt #define genkdf _kdfhint.generic 823487a6b1Sjsing #define pbkdf _kdfhint.pbkdf 83e7d4f752Sderaadt }; 84e7d4f752Sderaadt 85e7d4f752Sderaadt #define SR_IOCTL_GET_KDFHINT 0x01 /* Get KDF hint. */ 864b1a56afSjsg #define SR_IOCTL_CHANGE_PASSPHRASE 0x02 /* Change passphrase. */ 87e7d4f752Sderaadt 88e7d4f752Sderaadt struct sr_crypto_kdfpair { 893487a6b1Sjsing struct sr_crypto_kdfinfo *kdfinfo1; 90e7d4f752Sderaadt u_int32_t kdfsize1; 913487a6b1Sjsing struct sr_crypto_kdfinfo *kdfinfo2; 92e7d4f752Sderaadt u_int32_t kdfsize2; 93e7d4f752Sderaadt }; 94e7d4f752Sderaadt 95e7d4f752Sderaadt #if defined(_KERNEL) || defined(_STANDALONE) 96e7d4f752Sderaadt 97e7d4f752Sderaadt #include <crypto/md5.h> 98e7d4f752Sderaadt 99e7d4f752Sderaadt #define SR_META_V3_SIZE 64 100e7d4f752Sderaadt #define SR_META_V3_OFFSET 16 101e7d4f752Sderaadt #define SR_META_V3_DATA_OFFSET (SR_META_V3_OFFSET + SR_META_V3_SIZE) 102e7d4f752Sderaadt 103e7d4f752Sderaadt #define SR_META_F_NATIVE 0 /* Native metadata format. */ 104e7d4f752Sderaadt #define SR_META_F_INVALID -1 105e7d4f752Sderaadt 106f6e5141fSjsing #define SR_HEADER_SIZE (SR_META_SIZE + SR_BOOT_SIZE) 107f6e5141fSjsing #define SR_DATA_OFFSET (SR_META_OFFSET + SR_HEADER_SIZE) 108c8c45af3Sdjm 1091e4909a2Sjsing #define SR_HOTSPARE_LEVEL 0xffffffff 1101e4909a2Sjsing #define SR_HOTSPARE_VOLID 0xffffffff 1110054cd36Sjsing #define SR_KEYDISK_LEVEL 0xfffffffe 1120054cd36Sjsing #define SR_KEYDISK_VOLID 0xfffffffe 1131e4909a2Sjsing 114f6e5141fSjsing #define SR_UUID_MAX 16 115f6e5141fSjsing struct sr_uuid { 116f6e5141fSjsing u_int8_t sui_id[SR_UUID_MAX]; 117f6e5141fSjsing } __packed; 1180054cd36Sjsing 119f4a5ffb3Sjsing struct sr_disk { 120f4a5ffb3Sjsing dev_t sdk_devno; 121f4a5ffb3Sjsing SLIST_ENTRY(sr_disk) sdk_link; 122f4a5ffb3Sjsing }; 123f4a5ffb3Sjsing SLIST_HEAD(sr_disk_head, sr_disk); 124f4a5ffb3Sjsing 125c8c45af3Sdjm struct sr_metadata { 126080cddd5Smarco struct sr_meta_invariant { 127080cddd5Smarco /* do not change order of ssd_magic, ssd_version */ 128c8c45af3Sdjm u_int64_t ssd_magic; /* magic id */ 129c8c45af3Sdjm #define SR_MAGIC 0x4d4152436372616dLLU 130080cddd5Smarco u_int32_t ssd_version; /* meta data version */ 131e5ea34d9Sjsing u_int32_t ssd_vol_flags; /* volume specific flags. */ 132c8c45af3Sdjm struct sr_uuid ssd_uuid; /* unique identifier */ 133c8c45af3Sdjm 134080cddd5Smarco /* chunks */ 135c8c45af3Sdjm u_int32_t ssd_chunk_no; /* number of chunks */ 136c8c45af3Sdjm u_int32_t ssd_chunk_id; /* chunk identifier */ 137c8c45af3Sdjm 138080cddd5Smarco /* optional */ 139eed14ba3Smarco u_int32_t ssd_opt_no; /* nr of optional md elements */ 140bccb2f38Skrw u_int32_t ssd_secsize; 141080cddd5Smarco 142080cddd5Smarco /* volume metadata */ 143080cddd5Smarco u_int32_t ssd_volid; /* volume id */ 144080cddd5Smarco u_int32_t ssd_level; /* raid level */ 145080cddd5Smarco int64_t ssd_size; /* virt disk size in blocks */ 146080cddd5Smarco char ssd_vendor[8]; /* scsi vendor */ 147080cddd5Smarco char ssd_product[16];/* scsi product */ 148080cddd5Smarco char ssd_revision[4];/* scsi revision */ 149080cddd5Smarco /* optional volume members */ 150080cddd5Smarco u_int32_t ssd_strip_size; /* strip size */ 151080cddd5Smarco } _sdd_invariant; 152080cddd5Smarco #define ssdi _sdd_invariant 153080cddd5Smarco /* MD5 of invariant metadata */ 154080cddd5Smarco u_int8_t ssd_checksum[MD5_DIGEST_LENGTH]; 155080cddd5Smarco char ssd_devname[32];/* /dev/XXXXX */ 156080cddd5Smarco u_int32_t ssd_meta_flags; 157080cddd5Smarco #define SR_META_DIRTY 0x1 158d9ec6765Skrw u_int32_t ssd_data_blkno; 159080cddd5Smarco u_int64_t ssd_ondisk; /* on disk version counter */ 160eed14ba3Smarco int64_t ssd_rebuild; /* last block of rebuild */ 161c8c45af3Sdjm } __packed; 162c8c45af3Sdjm 163080cddd5Smarco struct sr_meta_chunk { 164080cddd5Smarco struct sr_meta_chunk_invariant { 165c8c45af3Sdjm u_int32_t scm_volid; /* vd we belong to */ 166c8c45af3Sdjm u_int32_t scm_chunk_id; /* chunk id */ 167c8c45af3Sdjm char scm_devname[32];/* /dev/XXXXX */ 168c8c45af3Sdjm int64_t scm_size; /* size of partition in blocks*/ 169c8c45af3Sdjm int64_t scm_coerced_size; /* coerced sz of part in blk*/ 170c8c45af3Sdjm struct sr_uuid scm_uuid; /* unique identifier */ 171080cddd5Smarco } _scm_invariant; 172080cddd5Smarco #define scmi _scm_invariant 173080cddd5Smarco /* MD5 of invariant chunk metadata */ 174080cddd5Smarco u_int8_t scm_checksum[MD5_DIGEST_LENGTH]; 175080cddd5Smarco u_int32_t scm_status; /* use bio bioc_disk status */ 176c8c45af3Sdjm } __packed; 177c8c45af3Sdjm 178080cddd5Smarco /* 179080cddd5Smarco * Check that HMAC-SHA1_k(decrypted scm_key) == sch_mac, where 180080cddd5Smarco * k = SHA1(masking key) 181080cddd5Smarco */ 182080cddd5Smarco struct sr_crypto_chk_hmac_sha1 { 183080cddd5Smarco u_int8_t sch_mac[20]; 184080cddd5Smarco } __packed; 185080cddd5Smarco 186ee4e3de1Sjsing #define SR_OPT_INVALID 0x00 187ee4e3de1Sjsing #define SR_OPT_CRYPTO 0x01 188ee4e3de1Sjsing #define SR_OPT_BOOT 0x02 189ee4e3de1Sjsing #define SR_OPT_KEYDISK 0x03 190ee4e3de1Sjsing 191ee4e3de1Sjsing struct sr_meta_opt_hdr { 192ee4e3de1Sjsing u_int32_t som_type; /* optional metadata type. */ 193ee4e3de1Sjsing u_int32_t som_length; /* optional metadata length. */ 194ee4e3de1Sjsing u_int8_t som_checksum[MD5_DIGEST_LENGTH]; 195ee4e3de1Sjsing } __packed; 196ee4e3de1Sjsing 197080cddd5Smarco struct sr_meta_crypto { 198ee4e3de1Sjsing struct sr_meta_opt_hdr scm_hdr; 199080cddd5Smarco u_int32_t scm_alg; /* vol crypto algorithm */ 200080cddd5Smarco #define SR_CRYPTOA_AES_XTS_128 1 201080cddd5Smarco #define SR_CRYPTOA_AES_XTS_256 2 202080cddd5Smarco u_int32_t scm_flags; /* key & kdfhint valid */ 203080cddd5Smarco #define SR_CRYPTOF_INVALID (0) 204080cddd5Smarco #define SR_CRYPTOF_KEY (1<<0) 205080cddd5Smarco #define SR_CRYPTOF_KDFHINT (1<<1) 206080cddd5Smarco u_int32_t scm_mask_alg; /* disk key masking crypt alg */ 207080cddd5Smarco #define SR_CRYPTOM_AES_ECB_256 1 208080cddd5Smarco u_int32_t scm_pad1; 209080cddd5Smarco u_int8_t scm_reserved[64]; 210080cddd5Smarco 211080cddd5Smarco /* symmetric keys used for disk encryption */ 212080cddd5Smarco u_int8_t scm_key[SR_CRYPTO_MAXKEYS][SR_CRYPTO_KEYBYTES]; 213080cddd5Smarco /* hint to kdf algorithm (opaque to kernel) */ 214080cddd5Smarco u_int8_t scm_kdfhint[SR_CRYPTO_KDFHINTBYTES]; 215080cddd5Smarco 216080cddd5Smarco u_int32_t scm_check_alg; /* key chksum algorithm */ 217080cddd5Smarco #define SR_CRYPTOC_HMAC_SHA1 1 218080cddd5Smarco u_int32_t scm_pad2; 219080cddd5Smarco union { 220080cddd5Smarco struct sr_crypto_chk_hmac_sha1 chk_hmac_sha1; 221080cddd5Smarco u_int8_t chk_reserved2[64]; 222080cddd5Smarco } _scm_chk; 223080cddd5Smarco #define chk_hmac_sha1 _scm_chk.chk_hmac_sha1 224080cddd5Smarco } __packed; 225080cddd5Smarco 2268fdeb3fdSjsing #define SR_MAX_BOOT_DISKS 16 227f6e5141fSjsing struct sr_meta_boot { 228ee4e3de1Sjsing struct sr_meta_opt_hdr sbm_hdr; 229f6e5141fSjsing u_int32_t sbm_bootblk_size; 230f6e5141fSjsing u_int32_t sbm_bootldr_size; 2318fdeb3fdSjsing u_char sbm_root_duid[8]; 2328fdeb3fdSjsing u_char sbm_boot_duid[SR_MAX_BOOT_DISKS][8]; 233f6e5141fSjsing } __packed; 234f6e5141fSjsing 235b36cc235Sjsing struct sr_meta_keydisk { 236ee4e3de1Sjsing struct sr_meta_opt_hdr skm_hdr; 237b36cc235Sjsing u_int8_t skm_maskkey[SR_CRYPTO_MAXKEYBYTES]; 238b36cc235Sjsing } __packed; 239b36cc235Sjsing 240ee4e3de1Sjsing #define SR_OLD_META_OPT_SIZE 2480 241ee4e3de1Sjsing #define SR_OLD_META_OPT_OFFSET 8 242ee4e3de1Sjsing #define SR_OLD_META_OPT_MD5 (SR_OLD_META_OPT_SIZE - MD5_DIGEST_LENGTH) 243080cddd5Smarco 244c907def9Sjsing struct sr_meta_opt_item { 245ee4e3de1Sjsing struct sr_meta_opt_hdr *omi_som; 246c907def9Sjsing SLIST_ENTRY(sr_meta_opt_item) omi_link; 247c907def9Sjsing }; 248c907def9Sjsing 249c907def9Sjsing SLIST_HEAD(sr_meta_opt_head, sr_meta_opt_item); 250c907def9Sjsing 251074ca811Sjsing struct sr_boot_chunk { 252074ca811Sjsing struct sr_metadata *sbc_metadata; 253b7072a3fSjsing dev_t sbc_mm; /* Device major/minor. */ 254074ca811Sjsing 255074ca811Sjsing u_int32_t sbc_chunk_id; /* Chunk ID. */ 256074ca811Sjsing u_int32_t sbc_state; /* Chunk state. */ 257074ca811Sjsing u_int32_t sbc_disk; /* Disk number. */ 258074ca811Sjsing int sbc_part; /* Partition number. */ 259074ca811Sjsing u_int64_t sbc_ondisk; /* Ondisk version. */ 260074ca811Sjsing 261074ca811Sjsing void *sbc_diskinfo; /* MD disk information. */ 262074ca811Sjsing 263074ca811Sjsing SLIST_ENTRY(sr_boot_chunk) sbc_link; 264074ca811Sjsing }; 265074ca811Sjsing 266074ca811Sjsing SLIST_HEAD(sr_boot_chunk_head, sr_boot_chunk); 267074ca811Sjsing 268074ca811Sjsing struct sr_boot_volume { 269074ca811Sjsing struct sr_uuid sbv_uuid; /* Volume UUID. */ 270074ca811Sjsing u_int32_t sbv_level; /* RAID Level. */ 271074ca811Sjsing u_int32_t sbv_volid; /* Volume ID. */ 272074ca811Sjsing u_int32_t sbv_chunk_no; /* Number of chunks. */ 273074ca811Sjsing u_int32_t sbv_flags; /* Volume specific flags. */ 274074ca811Sjsing u_int32_t sbv_state; /* Volume state. */ 275074ca811Sjsing int64_t sbv_size; /* Virtual disk size. */ 276f252f90fSyasuoka u_int32_t sbv_secsize; /* Sector size */ 277d9ec6765Skrw u_int32_t sbv_data_blkno; /* Data offset. */ 278074ca811Sjsing u_int64_t sbv_ondisk; /* Ondisk version. */ 279074ca811Sjsing 280074ca811Sjsing u_int32_t sbv_chunks_found; /* Number of chunks found. */ 281074ca811Sjsing u_int32_t sbv_unit; /* Disk unit number. */ 282074ca811Sjsing char sbv_part; /* Partition opened. */ 283074ca811Sjsing void *sbv_diskinfo; /* MD disk information. */ 284074ca811Sjsing 28570197c51Sjsing u_int8_t *sbv_keys; /* Disk keys for volume. */ 28670197c51Sjsing u_int8_t *sbv_maskkey; /* Mask key for disk keys. */ 28770197c51Sjsing 288074ca811Sjsing struct sr_boot_chunk_head sbv_chunks; /* List of chunks. */ 28970197c51Sjsing struct sr_meta_opt_head sbv_meta_opt; /* List of optional metadata. */ 290074ca811Sjsing 291074ca811Sjsing SLIST_ENTRY(sr_boot_volume) sbv_link; 292074ca811Sjsing }; 293074ca811Sjsing 294074ca811Sjsing SLIST_HEAD(sr_boot_volume_head, sr_boot_volume); 2951576da7bStedu 296e7d4f752Sderaadt #endif /* _KERNEL | _STANDALONE */ 297e7d4f752Sderaadt 298c8c45af3Sdjm #ifdef _KERNEL 299e7d4f752Sderaadt 3007195049bSmarco #include <dev/biovar.h> 3017195049bSmarco 3027195049bSmarco #include <sys/buf.h> 3037195049bSmarco #include <sys/queue.h> 3047195049bSmarco #include <sys/rwlock.h> 3051f300c94Sjsing #include <sys/task.h> 3067195049bSmarco 3077195049bSmarco #include <scsi/scsi_all.h> 3087195049bSmarco #include <scsi/scsi_disk.h> 3097195049bSmarco #include <scsi/scsiconf.h> 3107195049bSmarco 3117195049bSmarco #define DEVNAME(_s) ((_s)->sc_dev.dv_xname) 3127195049bSmarco 3132360bd90Smarco /* #define SR_DEBUG */ 3147195049bSmarco #ifdef SR_DEBUG 3157195049bSmarco extern u_int32_t sr_debug; 3167195049bSmarco #define DNPRINTF(n,x...) do { if (sr_debug & n) printf(x); } while(0) 3177195049bSmarco #define SR_D_CMD 0x0001 3187195049bSmarco #define SR_D_INTR 0x0002 3197195049bSmarco #define SR_D_MISC 0x0004 3207195049bSmarco #define SR_D_IOCTL 0x0008 3217195049bSmarco #define SR_D_CCB 0x0010 3227195049bSmarco #define SR_D_WU 0x0020 3237195049bSmarco #define SR_D_META 0x0040 3247195049bSmarco #define SR_D_DIS 0x0080 325e665884eSmarco #define SR_D_STATE 0x0100 326d3808055Sjsing #define SR_D_REBUILD 0x0200 3277195049bSmarco #else 3287195049bSmarco #define DNPRINTF(n,x...) 3297195049bSmarco #endif 3307195049bSmarco 3311baf7721Smatthew #define SR_MAX_LD 256 3327195049bSmarco #define SR_MAX_CMDS 16 3333d417dfdSmarco #define SR_MAX_STATES 7 334080cddd5Smarco #define SR_VM_IGNORE_DIRTY 1 335fe9ba17fSmarco #define SR_REBUILD_IO_SIZE 128 /* blocks */ 3367195049bSmarco 337b7072a3fSjsing extern struct sr_uuid sr_bootuuid; 338b7072a3fSjsing extern u_int8_t sr_bootkey[SR_CRYPTO_MAXKEYBYTES]; 339b7072a3fSjsing 3407195049bSmarco /* forward define to prevent dependency goo */ 3417195049bSmarco struct sr_softc; 3427195049bSmarco 3437195049bSmarco struct sr_ccb { 3447195049bSmarco struct buf ccb_buf; /* MUST BE FIRST!! */ 3457195049bSmarco 3467195049bSmarco struct sr_workunit *ccb_wu; 3477195049bSmarco struct sr_discipline *ccb_dis; 3487195049bSmarco 34965c38a59Smarco int ccb_target; 3507195049bSmarco int ccb_state; 3517195049bSmarco #define SR_CCB_FREE 0 3527195049bSmarco #define SR_CCB_INPROGRESS 1 3537195049bSmarco #define SR_CCB_OK 2 3547195049bSmarco #define SR_CCB_FAILED 3 3557195049bSmarco 356b8c2831aSjsing int ccb_flags; 35791dbade8Sjordan #define SR_CCBF_FREEBUF (1<<0) /* free ccb_buf.b_data */ 35891dbade8Sjordan 3592cfeccc5Smarco void *ccb_opaque; /* discipline usable pointer */ 3602cfeccc5Smarco 3617195049bSmarco TAILQ_ENTRY(sr_ccb) ccb_link; 3629a5bbe9dSmarco }; 3637195049bSmarco 3647195049bSmarco TAILQ_HEAD(sr_ccb_list, sr_ccb); 3657195049bSmarco 3667195049bSmarco struct sr_workunit { 3677195049bSmarco struct scsi_xfer *swu_xs; 3687195049bSmarco struct sr_discipline *swu_dis; 3697195049bSmarco 3707195049bSmarco int swu_state; 3717195049bSmarco #define SR_WU_FREE 0 3727195049bSmarco #define SR_WU_INPROGRESS 1 3737195049bSmarco #define SR_WU_OK 2 3747195049bSmarco #define SR_WU_FAILED 3 3757195049bSmarco #define SR_WU_PARTIALLYFAILED 4 37606ef7550Smarco #define SR_WU_DEFERRED 5 37706ef7550Smarco #define SR_WU_PENDING 6 37830ad50a2Smarco #define SR_WU_RESTART 7 37930ad50a2Smarco #define SR_WU_REQUEUE 8 38097ec8a20Sjsing #define SR_WU_CONSTRUCT 9 38106ef7550Smarco 382fe9ba17fSmarco int swu_flags; /* additional hints */ 383b0eaba70Smarco #define SR_WUF_REBUILD (1<<0) /* rebuild io */ 38451e9de4cSjsing #define SR_WUF_REBUILDIOCOMP (1<<1) /* rebuild io complete */ 385f3b9c4eeSjordan #define SR_WUF_FAIL (1<<2) /* RAID6: failure */ 386f3b9c4eeSjordan #define SR_WUF_FAILIOCOMP (1<<3) 38751e9de4cSjsing #define SR_WUF_WAKEUP (1<<4) /* Wakeup on I/O completion. */ 38819d58073Sjsing #define SR_WUF_DISCIPLINE (1<<5) /* Discipline specific I/O. */ 3892b887710Sjsing #define SR_WUF_FAKE (1<<6) /* Faked workunit. */ 390fe9ba17fSmarco 39106ef7550Smarco /* workunit io range */ 3921abdbfdeSderaadt daddr_t swu_blk_start; 3931abdbfdeSderaadt daddr_t swu_blk_end; 3947195049bSmarco 39598b789a9Sjsing /* number of ios that makes up the whole work unit */ 39698b789a9Sjsing u_int32_t swu_io_count; 39798b789a9Sjsing 3987195049bSmarco /* in flight totals */ 3997195049bSmarco u_int32_t swu_ios_complete; 4007195049bSmarco u_int32_t swu_ios_failed; 4017195049bSmarco u_int32_t swu_ios_succeeded; 4027195049bSmarco 40306ef7550Smarco /* colliding wu */ 40406ef7550Smarco struct sr_workunit *swu_collider; 40506ef7550Smarco 40606ef7550Smarco /* all ios that make up this workunit */ 40706ef7550Smarco struct sr_ccb_list swu_ccb; 4087195049bSmarco 4097af3f0fdSmarco /* task memory */ 4101f300c94Sjsing struct task swu_task; 4117af3f0fdSmarco int swu_cb_active; /* in callback */ 4127af3f0fdSmarco 41398b789a9Sjsing TAILQ_ENTRY(sr_workunit) swu_link; /* Link in processing queue. */ 41498b789a9Sjsing TAILQ_ENTRY(sr_workunit) swu_next; /* Next work unit in chain. */ 4157195049bSmarco }; 4167195049bSmarco 4177195049bSmarco TAILQ_HEAD(sr_wu_list, sr_workunit); 4187195049bSmarco 41984e48fabSmarco /* RAID 0 */ 42084e48fabSmarco #define SR_RAID0_NOWU 16 42184e48fabSmarco struct sr_raid0 { 422a7791af9Smarco int32_t sr0_strip_bits; 42384e48fabSmarco }; 42484e48fabSmarco 425bcca2540Smarco /* RAID 1 */ 426bcca2540Smarco #define SR_RAID1_NOWU 16 427bcca2540Smarco struct sr_raid1 { 428bcca2540Smarco u_int32_t sr1_counter; 429bcca2540Smarco }; 430bcca2540Smarco 431f8000896Sjsing /* RAID 5 */ 432f8000896Sjsing #define SR_RAID5_NOWU 16 433f8000896Sjsing struct sr_raid5 { 434f8000896Sjsing int32_t sr5_strip_bits; 435c390bdbdSmarco }; 436c390bdbdSmarco 437f3b9c4eeSjordan /* RAID 6 */ 438f3b9c4eeSjordan #define SR_RAID6_NOWU 16 439f3b9c4eeSjordan struct sr_raid6 { 440f3b9c4eeSjordan int32_t sr6_strip_bits; 441f3b9c4eeSjordan }; 442f3b9c4eeSjordan 4438c887097Smarco /* CRYPTO */ 444117fae6fSoga TAILQ_HEAD(sr_crypto_wu_head, sr_crypto_wu); 4453f700ba0Smarco #define SR_CRYPTO_NOWU 16 446117fae6fSoga 44701de20b5Sstsp /* 44801de20b5Sstsp * The per-I/O data that we need to preallocate. We cannot afford to allow I/O 44901de20b5Sstsp * to start failing when memory pressure kicks in. We can store this in the WU 45001de20b5Sstsp * because we assert that only one ccb per WU will ever be active during crypto. 45101de20b5Sstsp */ 45201de20b5Sstsp struct sr_crypto_wu { 45301de20b5Sstsp struct sr_workunit cr_wu; /* Must be first. */ 45401de20b5Sstsp struct uio cr_uio; 45501de20b5Sstsp struct iovec cr_iov; 45601de20b5Sstsp struct cryptop *cr_crp; 45701de20b5Sstsp void *cr_dmabuf; 45801de20b5Sstsp }; 45901de20b5Sstsp 460f18dcc9cStedu struct sr_crypto { 461c907def9Sjsing struct sr_meta_crypto *scr_meta; 4620054cd36Sjsing struct sr_chunk *key_disk; 4638c887097Smarco 4646d198fe3Sjsing int scr_alg; 4656d198fe3Sjsing int scr_klen; 4666d198fe3Sjsing 467080cddd5Smarco /* XXX only keep scr_sid over time */ 4681a9d6c4eShshoexer u_int8_t scr_key[SR_CRYPTO_MAXKEYS][SR_CRYPTO_KEYBYTES]; 469c8c45af3Sdjm u_int8_t scr_maskkey[SR_CRYPTO_MAXKEYBYTES]; 47075b43c32Sdjm u_int64_t scr_sid[SR_CRYPTO_MAXKEYS]; 471bcca2540Smarco }; 4727195049bSmarco 4732b5fc845Sjsing #define SR_CONCAT_NOWU 16 4742b5fc845Sjsing struct sr_concat { 4752b5fc845Sjsing }; 4762b5fc845Sjsing 47701de20b5Sstsp /* RAID 1C */ 47801de20b5Sstsp #define SR_RAID1C_NOWU 16 479eb0e73bdSstsp struct sr_raid1c { 480eb0e73bdSstsp struct sr_crypto sr1c_crypto; 481eb0e73bdSstsp struct sr_raid1 sr1c_raid1; 482eb0e73bdSstsp }; 48301de20b5Sstsp 4847195049bSmarco struct sr_chunk { 485080cddd5Smarco struct sr_meta_chunk src_meta; /* chunk meta data */ 4867195049bSmarco 4877195049bSmarco /* runtime data */ 4887195049bSmarco dev_t src_dev_mm; /* major/minor */ 4894b7d3c47Smarco struct vnode *src_vn; /* vnode */ 4907195049bSmarco 49197d19cbbSmarco /* helper members before metadata makes it onto the chunk */ 49297d19cbbSmarco int src_meta_ondisk;/* set when meta is on disk */ 49397d19cbbSmarco char src_devname[32]; 4948fdeb3fdSjsing u_char src_duid[8]; /* Chunk disklabel UID. */ 495496b32c3Smarco int64_t src_size; /* in blocks */ 496bccb2f38Skrw u_int32_t src_secsize; 49797d19cbbSmarco 4987195049bSmarco SLIST_ENTRY(sr_chunk) src_link; 4997195049bSmarco }; 5007195049bSmarco 5017195049bSmarco SLIST_HEAD(sr_chunk_head, sr_chunk); 5027195049bSmarco 5037195049bSmarco struct sr_volume { 5047195049bSmarco /* runtime data */ 5057195049bSmarco struct sr_chunk_head sv_chunk_list; /* linked list of all chunks */ 5067195049bSmarco struct sr_chunk **sv_chunks; /* array to same chunks */ 50752a49d95Sjsing int64_t sv_chunk_minsz; /* Size of smallest chunk. */ 50852a49d95Sjsing int64_t sv_chunk_maxsz; /* Size of largest chunk. */ 509b80f645dSmarco 510b80f645dSmarco /* sensors */ 511b80f645dSmarco struct ksensor sv_sensor; 51213b6ba62Sjsing int sv_sensor_attached; 5137195049bSmarco }; 5147195049bSmarco 5157195049bSmarco struct sr_discipline { 5167195049bSmarco struct sr_softc *sd_sc; /* link back to sr softc */ 5172d9211fdSbluhm size_t sd_wu_size; /* alloc and free size */ 5187195049bSmarco u_int8_t sd_type; /* type of discipline */ 5197195049bSmarco #define SR_MD_RAID0 0 5207195049bSmarco #define SR_MD_RAID1 1 5217195049bSmarco #define SR_MD_RAID5 2 5227195049bSmarco #define SR_MD_CACHE 3 5233f700ba0Smarco #define SR_MD_CRYPTO 4 524a8232f4aStedu /* AOE was 5 and 6. */ 5250db2cd39Sjsing /* SR_MD_RAID4 was 7. */ 526f3b9c4eeSjordan #define SR_MD_RAID6 8 5272b5fc845Sjsing #define SR_MD_CONCAT 9 52801de20b5Sstsp #define SR_MD_RAID1C 10 529556bc6c4Skn char sd_name[10]; /* human readable discipline name */ 5301baf7721Smatthew u_int16_t sd_target; /* scsibus target discipline uses */ 5317195049bSmarco 532ac774743Sjsing u_int32_t sd_capabilities; 5332b5fc845Sjsing #define SR_CAP_SYSTEM_DISK 0x00000001 /* Attaches as a system disk. */ 5342b5fc845Sjsing #define SR_CAP_AUTO_ASSEMBLE 0x00000002 /* Can auto assemble. */ 5352b5fc845Sjsing #define SR_CAP_REBUILD 0x00000004 /* Supports rebuild. */ 5362b5fc845Sjsing #define SR_CAP_NON_COERCED 0x00000008 /* Uses non-coerced size. */ 5374848162aSjsing #define SR_CAP_REDUNDANT 0x00000010 /* Redundant copies of data. */ 538ac774743Sjsing 5397195049bSmarco union { 54084e48fabSmarco struct sr_raid0 mdd_raid0; 5417195049bSmarco struct sr_raid1 mdd_raid1; 542f8000896Sjsing struct sr_raid5 mdd_raid5; 543f3b9c4eeSjordan struct sr_raid6 mdd_raid6; 5442b5fc845Sjsing struct sr_concat mdd_concat; 5452b5fc845Sjsing #ifdef CRYPTO 546f18dcc9cStedu struct sr_crypto mdd_crypto; 547eb0e73bdSstsp struct sr_raid1c mdd_raid1c; 5482b5fc845Sjsing #endif /* CRYPTO */ 5497195049bSmarco } sd_dis_specific;/* dis specific members */ 5507195049bSmarco #define mds sd_dis_specific 5517195049bSmarco 5521f300c94Sjsing struct taskq *sd_taskq; 5537af3f0fdSmarco 554dcd22300Smarco /* discipline metadata */ 555dcd22300Smarco struct sr_metadata *sd_meta; /* in memory copy of metadata */ 556080cddd5Smarco void *sd_meta_foreign; /* non native metadata */ 557e8a57fdeSmarco u_int32_t sd_meta_flags; 558080cddd5Smarco int sd_meta_type; /* metadata functions */ 559c907def9Sjsing struct sr_meta_opt_head sd_meta_opt; /* optional metadata. */ 5600580dc1dSmarco 5619b9d9f36Smarco int sd_sync; 562585d81f0Smarco int sd_must_flush; 563585d81f0Smarco 564c7c3e8aaSmarco int sd_deleted; 565c7c3e8aaSmarco 5667195049bSmarco /* discipline volume */ 5677195049bSmarco struct sr_volume sd_vol; /* volume associated */ 568080cddd5Smarco int sd_vol_status; /* runtime vol status */ 5697195049bSmarco /* discipline resources */ 5707195049bSmarco struct sr_ccb *sd_ccb; 5717195049bSmarco struct sr_ccb_list sd_ccb_freeq; 5727195049bSmarco u_int32_t sd_max_ccb_per_wu; 5737195049bSmarco 57498b789a9Sjsing struct sr_wu_list sd_wu; /* all workunits */ 5757195049bSmarco u_int32_t sd_max_wu; 5761f35e705Smarco int sd_reb_active; /* rebuild in progress */ 5778989bbe9Sjsing int sd_reb_abort; /* abort rebuild */ 5789b1bb5e7Smarco int sd_ready; /* fully operational */ 5797195049bSmarco 58006ef7550Smarco struct sr_wu_list sd_wu_freeq; /* free wu queue */ 58106ef7550Smarco struct sr_wu_list sd_wu_pendq; /* pending wu queue */ 58206ef7550Smarco struct sr_wu_list sd_wu_defq; /* deferred wu queue */ 583e13e110eSkrw 584e13e110eSkrw struct mutex sd_wu_mtx; 585e13e110eSkrw struct scsi_iopool sd_iopool; 58606ef7550Smarco 58718e03cc6Smarco /* discipline stats */ 58818e03cc6Smarco int sd_wu_pending; 58918e03cc6Smarco u_int64_t sd_wu_collisions; 59018e03cc6Smarco 5917195049bSmarco /* discipline functions */ 5929847360bSjsing int (*sd_create)(struct sr_discipline *, 5939847360bSjsing struct bioc_createraid *, int, int64_t); 5949847360bSjsing int (*sd_assemble)(struct sr_discipline *, 5957c003ea3Sjsing struct bioc_createraid *, int, void *); 5967195049bSmarco int (*sd_alloc_resources)(struct sr_discipline *); 597820ef724Sjsing void (*sd_free_resources)(struct sr_discipline *); 598d9594f12Sjsing int (*sd_ioctl_handler)(struct sr_discipline *, 599da289b8bSjsing struct bioc_discipline *); 600787a479aSmarco int (*sd_start_discipline)(struct sr_discipline *); 601e665884eSmarco void (*sd_set_chunk_state)(struct sr_discipline *, 602e665884eSmarco int, int); 603e665884eSmarco void (*sd_set_vol_state)(struct sr_discipline *); 60419e286b0Smarco int (*sd_openings)(struct sr_discipline *); 605573449ddSjsing int (*sd_meta_opt_handler)(struct sr_discipline *, 606ee4e3de1Sjsing struct sr_meta_opt_hdr *); 6075d8df638Sjsing void (*sd_rebuild)(struct sr_discipline *); 6087195049bSmarco 6097195049bSmarco /* SCSI emulation */ 6107195049bSmarco struct scsi_sense_data sd_scsi_sense; 6117195049bSmarco int (*sd_scsi_rw)(struct sr_workunit *); 612148cc3e1Sjsing void (*sd_scsi_intr)(struct buf *); 61338cf722eSjsing int (*sd_scsi_wu_done)(struct sr_workunit *); 614d01dc9afSjsing void (*sd_scsi_done)(struct sr_workunit *); 6157195049bSmarco int (*sd_scsi_sync)(struct sr_workunit *); 6167195049bSmarco int (*sd_scsi_tur)(struct sr_workunit *); 6177195049bSmarco int (*sd_scsi_start_stop)(struct sr_workunit *); 6187195049bSmarco int (*sd_scsi_inquiry)(struct sr_workunit *); 6197195049bSmarco int (*sd_scsi_read_cap)(struct sr_workunit *); 6207195049bSmarco int (*sd_scsi_req_sense)(struct sr_workunit *); 621fe9ba17fSmarco 622fe9ba17fSmarco /* background operation */ 623fe9ba17fSmarco struct proc *sd_background_proc; 624dd2d4a89Sjsing 625e328a933Sjsing /* Tasks. */ 626e328a933Sjsing struct task sd_meta_save_task; 6273b545d8fSblambert struct task sd_hotspare_rebuild_task; 628e328a933Sjsing 629dd2d4a89Sjsing TAILQ_ENTRY(sr_discipline) sd_link; 6307195049bSmarco }; 6317195049bSmarco 632dd2d4a89Sjsing TAILQ_HEAD(sr_discipline_list, sr_discipline); 633dd2d4a89Sjsing 6347195049bSmarco struct sr_softc { 6357195049bSmarco struct device sc_dev; 6367195049bSmarco 6377195049bSmarco struct rwlock sc_lock; 638b80f645dSmarco 639313b4264Sjsing struct bio_status sc_status; /* Status and messages. */ 640313b4264Sjsing 6411e4909a2Sjsing struct sr_chunk_head sc_hotspare_list; /* List of hotspares. */ 6421e4909a2Sjsing struct rwlock sc_hs_lock; /* Lock for hotspares list. */ 6431e4909a2Sjsing int sc_hotspare_no; /* Number of hotspares. */ 6441e4909a2Sjsing 64513b6ba62Sjsing struct ksensordev sc_sensordev; 6461d7cd2d4Sjsing struct sensor_task *sc_sensor_task; 64713b6ba62Sjsing 6481baf7721Smatthew struct scsibus_softc *sc_scsibus; 649b80f645dSmarco 650dd2d4a89Sjsing /* The target lookup has to be cheap since it happens for each I/O. */ 651f7b72a91Sjsing struct sr_discipline *sc_targets[SR_MAX_LD]; 652dd2d4a89Sjsing struct sr_discipline_list sc_dis_list; 6537195049bSmarco }; 654f18dcc9cStedu 6559b1bb5e7Smarco /* hotplug */ 6569b1bb5e7Smarco void sr_hotplug_register(struct sr_discipline *, void *); 6579b1bb5e7Smarco void sr_hotplug_unregister(struct sr_discipline *, void *); 6589b1bb5e7Smarco 6591e4909a2Sjsing /* Hotspare and rebuild. */ 660e4195480Sdlg void sr_hotspare_rebuild_callback(void *); 6611e4909a2Sjsing 662f18dcc9cStedu /* work units & ccbs */ 663080cddd5Smarco int sr_ccb_alloc(struct sr_discipline *); 664080cddd5Smarco void sr_ccb_free(struct sr_discipline *); 665080cddd5Smarco struct sr_ccb *sr_ccb_get(struct sr_discipline *); 666080cddd5Smarco void sr_ccb_put(struct sr_ccb *); 6671abdbfdeSderaadt struct sr_ccb *sr_ccb_rw(struct sr_discipline *, int, daddr_t, 668c804f705Skrw long, u_int8_t *, int, int); 6698868790bSjsing void sr_ccb_done(struct sr_ccb *); 6702d9211fdSbluhm int sr_wu_alloc(struct sr_discipline *); 671080cddd5Smarco void sr_wu_free(struct sr_discipline *); 672e13e110eSkrw void *sr_wu_get(void *); 673e13e110eSkrw void sr_wu_put(void *, void *); 674cbf13d71Sjsing void sr_wu_init(struct sr_discipline *, 675cbf13d71Sjsing struct sr_workunit *); 676de0f89e8Sjsing void sr_wu_enqueue_ccb(struct sr_workunit *, 6776ffa9fd1Sjsing struct sr_ccb *); 678de0f89e8Sjsing void sr_wu_release_ccbs(struct sr_workunit *); 679d01dc9afSjsing void sr_wu_done(struct sr_workunit *); 680f18dcc9cStedu 681f09486a6Smarco /* misc functions */ 682313b4264Sjsing void sr_info(struct sr_softc *, const char *, ...); 683313b4264Sjsing void sr_warn(struct sr_softc *, const char *, ...); 684313b4264Sjsing void sr_error(struct sr_softc *, const char *, ...); 685f09486a6Smarco int32_t sr_validate_stripsize(u_int32_t); 6860054cd36Sjsing int sr_meta_read(struct sr_discipline *); 6870054cd36Sjsing int sr_meta_native_read(struct sr_discipline *, dev_t, 6880054cd36Sjsing struct sr_metadata *, void *); 6890054cd36Sjsing int sr_meta_validate(struct sr_discipline *, dev_t, 6900054cd36Sjsing struct sr_metadata *, void *); 691e4195480Sdlg void sr_meta_save_callback(void *); 692c6446370Sjsing int sr_meta_save(struct sr_discipline *, u_int32_t); 6930054cd36Sjsing void sr_meta_getdevname(struct sr_softc *, dev_t, char *, 6940054cd36Sjsing int); 695573449ddSjsing void sr_meta_opt_load(struct sr_softc *, 696573449ddSjsing struct sr_metadata *, struct sr_meta_opt_head *); 697c804f705Skrw void *sr_block_get(struct sr_discipline *, long); 6984c26ac15Sjsing void sr_block_put(struct sr_discipline *, void *, int); 699c6446370Sjsing void sr_checksum(struct sr_softc *, void *, void *, 700c6446370Sjsing u_int32_t); 7011abdbfdeSderaadt int sr_validate_io(struct sr_workunit *, daddr_t *, 7024ce7339fSmarco char *); 70360781f8cSjsing void sr_schedule_wu(struct sr_workunit *); 7043864d2ceSmarco void sr_scsi_done(struct sr_discipline *, 7053864d2ceSmarco struct scsi_xfer *); 7067bf8e677Sjsing struct sr_workunit *sr_scsi_wu_get(struct sr_discipline *, int); 7077bf8e677Sjsing void sr_scsi_wu_put(struct sr_discipline *, 7087bf8e677Sjsing struct sr_workunit *); 7090054cd36Sjsing int sr_chunk_in_use(struct sr_softc *, dev_t); 71038301a9fSjsing int sr_rebuild_percent(struct sr_discipline *); 711f09486a6Smarco 712f18dcc9cStedu /* discipline functions */ 713f18dcc9cStedu int sr_raid_inquiry(struct sr_workunit *); 714f18dcc9cStedu int sr_raid_read_cap(struct sr_workunit *); 715f18dcc9cStedu int sr_raid_tur(struct sr_workunit *); 716f18dcc9cStedu int sr_raid_request_sense( struct sr_workunit *); 717f18dcc9cStedu int sr_raid_start_stop(struct sr_workunit *); 718f18dcc9cStedu int sr_raid_sync(struct sr_workunit *); 71971dbe7f2Sjsing void sr_raid_intr(struct buf *); 720f18dcc9cStedu void sr_raid_startwu(struct sr_workunit *); 7214eafb073Sjsing void sr_raid_recreate_wu(struct sr_workunit *); 722f18dcc9cStedu 723edc270aeSjsing /* Discipline specific initialisation. */ 724edc270aeSjsing void sr_raid0_discipline_init(struct sr_discipline *); 725edc270aeSjsing void sr_raid1_discipline_init(struct sr_discipline *); 726f8000896Sjsing void sr_raid5_discipline_init(struct sr_discipline *); 727f3b9c4eeSjordan void sr_raid6_discipline_init(struct sr_discipline *); 728edc270aeSjsing void sr_crypto_discipline_init(struct sr_discipline *); 7292b5fc845Sjsing void sr_concat_discipline_init(struct sr_discipline *); 73001de20b5Sstsp void sr_raid1c_discipline_init(struct sr_discipline *); 73184e48fabSmarco 732edc270aeSjsing /* Crypto discipline hooks. */ 733f05efa1dShshoexer int sr_crypto_get_kdf(struct bioc_createraid *, 734eb0e73bdSstsp struct sr_discipline *, struct sr_crypto *); 735eb0e73bdSstsp int sr_crypto_create_keys(struct sr_discipline *, 736eb0e73bdSstsp struct sr_crypto *); 737eb0e73bdSstsp struct sr_chunk * sr_crypto_create_key_disk(struct sr_discipline *, 738eb0e73bdSstsp struct sr_crypto *, dev_t); 739eb0e73bdSstsp struct sr_chunk * sr_crypto_read_key_disk(struct sr_discipline *, 740eb0e73bdSstsp struct sr_crypto *, dev_t); 7418c887097Smarco 7427b90f98fSmlarkin /* Hibernate I/O function */ 7437b90f98fSmlarkin int sr_hibernate_io(dev_t dev, daddr_t blkno, vaddr_t addr, 7447b90f98fSmlarkin size_t size, int op, void *page); 7457b90f98fSmlarkin 7468c887097Smarco #ifdef SR_DEBUG 747f5040c40Sjsing void sr_dump_block(void *, int); 7488c887097Smarco void sr_dump_mem(u_int8_t *, int); 7498c887097Smarco #endif 750f18dcc9cStedu 751c8c45af3Sdjm #endif /* _KERNEL */ 752c8c45af3Sdjm 75384e48fabSmarco #endif /* SOFTRAIDVAR_H */ 754