/* $OpenBSD: softraidvar.h,v 1.176 2022/12/19 15:27:06 kn Exp $ */ /* * Copyright (c) 2006 Marco Peereboom * Copyright (c) 2008 Chris Kuethe * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef SOFTRAIDVAR_H #define SOFTRAIDVAR_H #define SR_META_VERSION 6 /* bump when sr_metadata changes */ #define SR_META_SIZE 64 /* save space at chunk beginning */ #define SR_META_OFFSET 16 /* skip 8192 bytes at chunk beginning */ #define SR_BOOT_OFFSET (SR_META_OFFSET + SR_META_SIZE) #define SR_BOOT_LOADER_SIZE 320 /* Size of boot loader storage. */ #define SR_BOOT_LOADER_OFFSET SR_BOOT_OFFSET #define SR_BOOT_BLOCKS_SIZE 128 /* Size of boot block storage. */ #define SR_BOOT_BLOCKS_OFFSET (SR_BOOT_LOADER_OFFSET + SR_BOOT_LOADER_SIZE) #define SR_BOOT_SIZE (SR_BOOT_LOADER_SIZE + SR_BOOT_BLOCKS_SIZE) #define SR_CRYPTO_MAXKEYBYTES 32 /* max bytes in a key (AES-XTS-256) */ #define SR_CRYPTO_MAXKEYS 32 /* max keys per volume */ #define SR_CRYPTO_KEYBITS 512 /* AES-XTS with 2 * 256 bit keys */ #define SR_CRYPTO_KEYBYTES (SR_CRYPTO_KEYBITS >> 3) #define SR_CRYPTO_KDFHINTBYTES 256 /* size of opaque KDF hint */ #define SR_CRYPTO_CHECKBYTES 64 /* size of generic key chksum struct */ #define SR_CRYPTO_KEY_BLKSHIFT 30 /* 0.5TB per key */ #define SR_CRYPTO_KEY_BLKSIZE (1ULL << SR_CRYPTO_KEY_BLKSHIFT) #define SR_CRYPTO_MAXSIZE (SR_CRYPTO_KEY_BLKSIZE * SR_CRYPTO_MAXKEYS) /* * sr_crypto_genkdf is a generic hint for the KDF performed in userland and * is not interpreted by the kernel. */ struct sr_crypto_genkdf { u_int32_t len; u_int32_t type; #define SR_CRYPTOKDFT_INVALID 0 #define SR_CRYPTOKDFT_PKCS5_PBKDF2 1 #define SR_CRYPTOKDFT_KEYDISK 2 #define SR_CRYPTOKDFT_BCRYPT_PBKDF 3 }; /* * sr_crypto_pbkdf is a hint for a PBKDF performed in userland and is not * interpreted by the kernel. */ struct sr_crypto_pbkdf { struct sr_crypto_genkdf generic; u_int32_t rounds; u_int8_t salt[128]; }; /* * sr_crypto_kdfinfo is used to copy masking keys and KDF hints from/to * userland. The embedded hint structures are not interpreted by the kernel. */ struct sr_crypto_kdfinfo { u_int32_t len; u_int32_t flags; #define SR_CRYPTOKDF_INVALID (0) #define SR_CRYPTOKDF_KEY (1<<0) #define SR_CRYPTOKDF_HINT (1<<1) u_int8_t maskkey[SR_CRYPTO_MAXKEYBYTES]; union { struct sr_crypto_genkdf generic; struct sr_crypto_pbkdf pbkdf; } _kdfhint; #define genkdf _kdfhint.generic #define pbkdf _kdfhint.pbkdf }; #define SR_IOCTL_GET_KDFHINT 0x01 /* Get KDF hint. */ #define SR_IOCTL_CHANGE_PASSPHRASE 0x02 /* Change passphrase. */ struct sr_crypto_kdfpair { struct sr_crypto_kdfinfo *kdfinfo1; u_int32_t kdfsize1; struct sr_crypto_kdfinfo *kdfinfo2; u_int32_t kdfsize2; }; #if defined(_KERNEL) || defined(_STANDALONE) #include #define SR_META_V3_SIZE 64 #define SR_META_V3_OFFSET 16 #define SR_META_V3_DATA_OFFSET (SR_META_V3_OFFSET + SR_META_V3_SIZE) #define SR_META_F_NATIVE 0 /* Native metadata format. */ #define SR_META_F_INVALID -1 #define SR_HEADER_SIZE (SR_META_SIZE + SR_BOOT_SIZE) #define SR_DATA_OFFSET (SR_META_OFFSET + SR_HEADER_SIZE) #define SR_HOTSPARE_LEVEL 0xffffffff #define SR_HOTSPARE_VOLID 0xffffffff #define SR_KEYDISK_LEVEL 0xfffffffe #define SR_KEYDISK_VOLID 0xfffffffe #define SR_UUID_MAX 16 struct sr_uuid { u_int8_t sui_id[SR_UUID_MAX]; } __packed; struct sr_disk { dev_t sdk_devno; SLIST_ENTRY(sr_disk) sdk_link; }; SLIST_HEAD(sr_disk_head, sr_disk); struct sr_metadata { struct sr_meta_invariant { /* do not change order of ssd_magic, ssd_version */ u_int64_t ssd_magic; /* magic id */ #define SR_MAGIC 0x4d4152436372616dLLU u_int32_t ssd_version; /* meta data version */ u_int32_t ssd_vol_flags; /* volume specific flags. */ struct sr_uuid ssd_uuid; /* unique identifier */ /* chunks */ u_int32_t ssd_chunk_no; /* number of chunks */ u_int32_t ssd_chunk_id; /* chunk identifier */ /* optional */ u_int32_t ssd_opt_no; /* nr of optional md elements */ u_int32_t ssd_secsize; /* volume metadata */ u_int32_t ssd_volid; /* volume id */ u_int32_t ssd_level; /* raid level */ int64_t ssd_size; /* virt disk size in blocks */ char ssd_vendor[8]; /* scsi vendor */ char ssd_product[16];/* scsi product */ char ssd_revision[4];/* scsi revision */ /* optional volume members */ u_int32_t ssd_strip_size; /* strip size */ } _sdd_invariant; #define ssdi _sdd_invariant /* MD5 of invariant metadata */ u_int8_t ssd_checksum[MD5_DIGEST_LENGTH]; char ssd_devname[32];/* /dev/XXXXX */ u_int32_t ssd_meta_flags; #define SR_META_DIRTY 0x1 u_int32_t ssd_data_blkno; u_int64_t ssd_ondisk; /* on disk version counter */ int64_t ssd_rebuild; /* last block of rebuild */ } __packed; struct sr_meta_chunk { struct sr_meta_chunk_invariant { u_int32_t scm_volid; /* vd we belong to */ u_int32_t scm_chunk_id; /* chunk id */ char scm_devname[32];/* /dev/XXXXX */ int64_t scm_size; /* size of partition in blocks*/ int64_t scm_coerced_size; /* coerced sz of part in blk*/ struct sr_uuid scm_uuid; /* unique identifier */ } _scm_invariant; #define scmi _scm_invariant /* MD5 of invariant chunk metadata */ u_int8_t scm_checksum[MD5_DIGEST_LENGTH]; u_int32_t scm_status; /* use bio bioc_disk status */ } __packed; /* * Check that HMAC-SHA1_k(decrypted scm_key) == sch_mac, where * k = SHA1(masking key) */ struct sr_crypto_chk_hmac_sha1 { u_int8_t sch_mac[20]; } __packed; #define SR_OPT_INVALID 0x00 #define SR_OPT_CRYPTO 0x01 #define SR_OPT_BOOT 0x02 #define SR_OPT_KEYDISK 0x03 struct sr_meta_opt_hdr { u_int32_t som_type; /* optional metadata type. */ u_int32_t som_length; /* optional metadata length. */ u_int8_t som_checksum[MD5_DIGEST_LENGTH]; } __packed; struct sr_meta_crypto { struct sr_meta_opt_hdr scm_hdr; u_int32_t scm_alg; /* vol crypto algorithm */ #define SR_CRYPTOA_AES_XTS_128 1 #define SR_CRYPTOA_AES_XTS_256 2 u_int32_t scm_flags; /* key & kdfhint valid */ #define SR_CRYPTOF_INVALID (0) #define SR_CRYPTOF_KEY (1<<0) #define SR_CRYPTOF_KDFHINT (1<<1) u_int32_t scm_mask_alg; /* disk key masking crypt alg */ #define SR_CRYPTOM_AES_ECB_256 1 u_int32_t scm_pad1; u_int8_t scm_reserved[64]; /* symmetric keys used for disk encryption */ u_int8_t scm_key[SR_CRYPTO_MAXKEYS][SR_CRYPTO_KEYBYTES]; /* hint to kdf algorithm (opaque to kernel) */ u_int8_t scm_kdfhint[SR_CRYPTO_KDFHINTBYTES]; u_int32_t scm_check_alg; /* key chksum algorithm */ #define SR_CRYPTOC_HMAC_SHA1 1 u_int32_t scm_pad2; union { struct sr_crypto_chk_hmac_sha1 chk_hmac_sha1; u_int8_t chk_reserved2[64]; } _scm_chk; #define chk_hmac_sha1 _scm_chk.chk_hmac_sha1 } __packed; #define SR_MAX_BOOT_DISKS 16 struct sr_meta_boot { struct sr_meta_opt_hdr sbm_hdr; u_int32_t sbm_bootblk_size; u_int32_t sbm_bootldr_size; u_char sbm_root_duid[8]; u_char sbm_boot_duid[SR_MAX_BOOT_DISKS][8]; } __packed; struct sr_meta_keydisk { struct sr_meta_opt_hdr skm_hdr; u_int8_t skm_maskkey[SR_CRYPTO_MAXKEYBYTES]; } __packed; #define SR_OLD_META_OPT_SIZE 2480 #define SR_OLD_META_OPT_OFFSET 8 #define SR_OLD_META_OPT_MD5 (SR_OLD_META_OPT_SIZE - MD5_DIGEST_LENGTH) struct sr_meta_opt_item { struct sr_meta_opt_hdr *omi_som; SLIST_ENTRY(sr_meta_opt_item) omi_link; }; SLIST_HEAD(sr_meta_opt_head, sr_meta_opt_item); struct sr_boot_chunk { struct sr_metadata *sbc_metadata; dev_t sbc_mm; /* Device major/minor. */ u_int32_t sbc_chunk_id; /* Chunk ID. */ u_int32_t sbc_state; /* Chunk state. */ u_int32_t sbc_disk; /* Disk number. */ int sbc_part; /* Partition number. */ u_int64_t sbc_ondisk; /* Ondisk version. */ void *sbc_diskinfo; /* MD disk information. */ SLIST_ENTRY(sr_boot_chunk) sbc_link; }; SLIST_HEAD(sr_boot_chunk_head, sr_boot_chunk); struct sr_boot_volume { struct sr_uuid sbv_uuid; /* Volume UUID. */ u_int32_t sbv_level; /* RAID Level. */ u_int32_t sbv_volid; /* Volume ID. */ u_int32_t sbv_chunk_no; /* Number of chunks. */ u_int32_t sbv_flags; /* Volume specific flags. */ u_int32_t sbv_state; /* Volume state. */ int64_t sbv_size; /* Virtual disk size. */ u_int32_t sbv_secsize; /* Sector size */ u_int32_t sbv_data_blkno; /* Data offset. */ u_int64_t sbv_ondisk; /* Ondisk version. */ u_int32_t sbv_chunks_found; /* Number of chunks found. */ u_int32_t sbv_unit; /* Disk unit number. */ char sbv_part; /* Partition opened. */ void *sbv_diskinfo; /* MD disk information. */ u_int8_t *sbv_keys; /* Disk keys for volume. */ u_int8_t *sbv_maskkey; /* Mask key for disk keys. */ struct sr_boot_chunk_head sbv_chunks; /* List of chunks. */ struct sr_meta_opt_head sbv_meta_opt; /* List of optional metadata. */ SLIST_ENTRY(sr_boot_volume) sbv_link; }; SLIST_HEAD(sr_boot_volume_head, sr_boot_volume); #endif /* _KERNEL | _STANDALONE */ #ifdef _KERNEL #include #include #include #include #include #include #include #include #define DEVNAME(_s) ((_s)->sc_dev.dv_xname) /* #define SR_DEBUG */ #ifdef SR_DEBUG extern u_int32_t sr_debug; #define DNPRINTF(n,x...) do { if (sr_debug & n) printf(x); } while(0) #define SR_D_CMD 0x0001 #define SR_D_INTR 0x0002 #define SR_D_MISC 0x0004 #define SR_D_IOCTL 0x0008 #define SR_D_CCB 0x0010 #define SR_D_WU 0x0020 #define SR_D_META 0x0040 #define SR_D_DIS 0x0080 #define SR_D_STATE 0x0100 #define SR_D_REBUILD 0x0200 #else #define DNPRINTF(n,x...) #endif #define SR_MAX_LD 256 #define SR_MAX_CMDS 16 #define SR_MAX_STATES 7 #define SR_VM_IGNORE_DIRTY 1 #define SR_REBUILD_IO_SIZE 128 /* blocks */ extern struct sr_uuid sr_bootuuid; extern u_int8_t sr_bootkey[SR_CRYPTO_MAXKEYBYTES]; /* forward define to prevent dependency goo */ struct sr_softc; struct sr_ccb { struct buf ccb_buf; /* MUST BE FIRST!! */ struct sr_workunit *ccb_wu; struct sr_discipline *ccb_dis; int ccb_target; int ccb_state; #define SR_CCB_FREE 0 #define SR_CCB_INPROGRESS 1 #define SR_CCB_OK 2 #define SR_CCB_FAILED 3 int ccb_flags; #define SR_CCBF_FREEBUF (1<<0) /* free ccb_buf.b_data */ void *ccb_opaque; /* discipline usable pointer */ TAILQ_ENTRY(sr_ccb) ccb_link; }; TAILQ_HEAD(sr_ccb_list, sr_ccb); struct sr_workunit { struct scsi_xfer *swu_xs; struct sr_discipline *swu_dis; int swu_state; #define SR_WU_FREE 0 #define SR_WU_INPROGRESS 1 #define SR_WU_OK 2 #define SR_WU_FAILED 3 #define SR_WU_PARTIALLYFAILED 4 #define SR_WU_DEFERRED 5 #define SR_WU_PENDING 6 #define SR_WU_RESTART 7 #define SR_WU_REQUEUE 8 #define SR_WU_CONSTRUCT 9 int swu_flags; /* additional hints */ #define SR_WUF_REBUILD (1<<0) /* rebuild io */ #define SR_WUF_REBUILDIOCOMP (1<<1) /* rebuild io complete */ #define SR_WUF_FAIL (1<<2) /* RAID6: failure */ #define SR_WUF_FAILIOCOMP (1<<3) #define SR_WUF_WAKEUP (1<<4) /* Wakeup on I/O completion. */ #define SR_WUF_DISCIPLINE (1<<5) /* Discipline specific I/O. */ #define SR_WUF_FAKE (1<<6) /* Faked workunit. */ /* workunit io range */ daddr_t swu_blk_start; daddr_t swu_blk_end; /* number of ios that makes up the whole work unit */ u_int32_t swu_io_count; /* in flight totals */ u_int32_t swu_ios_complete; u_int32_t swu_ios_failed; u_int32_t swu_ios_succeeded; /* colliding wu */ struct sr_workunit *swu_collider; /* all ios that make up this workunit */ struct sr_ccb_list swu_ccb; /* task memory */ struct task swu_task; int swu_cb_active; /* in callback */ TAILQ_ENTRY(sr_workunit) swu_link; /* Link in processing queue. */ TAILQ_ENTRY(sr_workunit) swu_next; /* Next work unit in chain. */ }; TAILQ_HEAD(sr_wu_list, sr_workunit); /* RAID 0 */ #define SR_RAID0_NOWU 16 struct sr_raid0 { int32_t sr0_strip_bits; }; /* RAID 1 */ #define SR_RAID1_NOWU 16 struct sr_raid1 { u_int32_t sr1_counter; }; /* RAID 5 */ #define SR_RAID5_NOWU 16 struct sr_raid5 { int32_t sr5_strip_bits; }; /* RAID 6 */ #define SR_RAID6_NOWU 16 struct sr_raid6 { int32_t sr6_strip_bits; }; /* CRYPTO */ TAILQ_HEAD(sr_crypto_wu_head, sr_crypto_wu); #define SR_CRYPTO_NOWU 16 /* * The per-I/O data that we need to preallocate. We cannot afford to allow I/O * to start failing when memory pressure kicks in. We can store this in the WU * because we assert that only one ccb per WU will ever be active during crypto. */ struct sr_crypto_wu { struct sr_workunit cr_wu; /* Must be first. */ struct uio cr_uio; struct iovec cr_iov; struct cryptop *cr_crp; void *cr_dmabuf; }; struct sr_crypto { struct sr_meta_crypto *scr_meta; struct sr_chunk *key_disk; int scr_alg; int scr_klen; /* XXX only keep scr_sid over time */ u_int8_t scr_key[SR_CRYPTO_MAXKEYS][SR_CRYPTO_KEYBYTES]; u_int8_t scr_maskkey[SR_CRYPTO_MAXKEYBYTES]; u_int64_t scr_sid[SR_CRYPTO_MAXKEYS]; }; #define SR_CONCAT_NOWU 16 struct sr_concat { }; /* RAID 1C */ #define SR_RAID1C_NOWU 16 struct sr_raid1c { struct sr_crypto sr1c_crypto; struct sr_raid1 sr1c_raid1; }; struct sr_chunk { struct sr_meta_chunk src_meta; /* chunk meta data */ /* runtime data */ dev_t src_dev_mm; /* major/minor */ struct vnode *src_vn; /* vnode */ /* helper members before metadata makes it onto the chunk */ int src_meta_ondisk;/* set when meta is on disk */ char src_devname[32]; u_char src_duid[8]; /* Chunk disklabel UID. */ int64_t src_size; /* in blocks */ u_int32_t src_secsize; SLIST_ENTRY(sr_chunk) src_link; }; SLIST_HEAD(sr_chunk_head, sr_chunk); struct sr_volume { /* runtime data */ struct sr_chunk_head sv_chunk_list; /* linked list of all chunks */ struct sr_chunk **sv_chunks; /* array to same chunks */ int64_t sv_chunk_minsz; /* Size of smallest chunk. */ int64_t sv_chunk_maxsz; /* Size of largest chunk. */ /* sensors */ struct ksensor sv_sensor; int sv_sensor_attached; }; struct sr_discipline { struct sr_softc *sd_sc; /* link back to sr softc */ size_t sd_wu_size; /* alloc and free size */ u_int8_t sd_type; /* type of discipline */ #define SR_MD_RAID0 0 #define SR_MD_RAID1 1 #define SR_MD_RAID5 2 #define SR_MD_CACHE 3 #define SR_MD_CRYPTO 4 /* AOE was 5 and 6. */ /* SR_MD_RAID4 was 7. */ #define SR_MD_RAID6 8 #define SR_MD_CONCAT 9 #define SR_MD_RAID1C 10 char sd_name[10]; /* human readable discipline name */ u_int16_t sd_target; /* scsibus target discipline uses */ u_int32_t sd_capabilities; #define SR_CAP_SYSTEM_DISK 0x00000001 /* Attaches as a system disk. */ #define SR_CAP_AUTO_ASSEMBLE 0x00000002 /* Can auto assemble. */ #define SR_CAP_REBUILD 0x00000004 /* Supports rebuild. */ #define SR_CAP_NON_COERCED 0x00000008 /* Uses non-coerced size. */ #define SR_CAP_REDUNDANT 0x00000010 /* Redundant copies of data. */ union { struct sr_raid0 mdd_raid0; struct sr_raid1 mdd_raid1; struct sr_raid5 mdd_raid5; struct sr_raid6 mdd_raid6; struct sr_concat mdd_concat; #ifdef CRYPTO struct sr_crypto mdd_crypto; struct sr_raid1c mdd_raid1c; #endif /* CRYPTO */ } sd_dis_specific;/* dis specific members */ #define mds sd_dis_specific struct taskq *sd_taskq; /* discipline metadata */ struct sr_metadata *sd_meta; /* in memory copy of metadata */ void *sd_meta_foreign; /* non native metadata */ u_int32_t sd_meta_flags; int sd_meta_type; /* metadata functions */ struct sr_meta_opt_head sd_meta_opt; /* optional metadata. */ int sd_sync; int sd_must_flush; int sd_deleted; /* discipline volume */ struct sr_volume sd_vol; /* volume associated */ int sd_vol_status; /* runtime vol status */ /* discipline resources */ struct sr_ccb *sd_ccb; struct sr_ccb_list sd_ccb_freeq; u_int32_t sd_max_ccb_per_wu; struct sr_wu_list sd_wu; /* all workunits */ u_int32_t sd_max_wu; int sd_reb_active; /* rebuild in progress */ int sd_reb_abort; /* abort rebuild */ int sd_ready; /* fully operational */ struct sr_wu_list sd_wu_freeq; /* free wu queue */ struct sr_wu_list sd_wu_pendq; /* pending wu queue */ struct sr_wu_list sd_wu_defq; /* deferred wu queue */ struct mutex sd_wu_mtx; struct scsi_iopool sd_iopool; /* discipline stats */ int sd_wu_pending; u_int64_t sd_wu_collisions; /* discipline functions */ int (*sd_create)(struct sr_discipline *, struct bioc_createraid *, int, int64_t); int (*sd_assemble)(struct sr_discipline *, struct bioc_createraid *, int, void *); int (*sd_alloc_resources)(struct sr_discipline *); void (*sd_free_resources)(struct sr_discipline *); int (*sd_ioctl_handler)(struct sr_discipline *, struct bioc_discipline *); int (*sd_start_discipline)(struct sr_discipline *); void (*sd_set_chunk_state)(struct sr_discipline *, int, int); void (*sd_set_vol_state)(struct sr_discipline *); int (*sd_openings)(struct sr_discipline *); int (*sd_meta_opt_handler)(struct sr_discipline *, struct sr_meta_opt_hdr *); void (*sd_rebuild)(struct sr_discipline *); /* SCSI emulation */ struct scsi_sense_data sd_scsi_sense; int (*sd_scsi_rw)(struct sr_workunit *); void (*sd_scsi_intr)(struct buf *); int (*sd_scsi_wu_done)(struct sr_workunit *); void (*sd_scsi_done)(struct sr_workunit *); int (*sd_scsi_sync)(struct sr_workunit *); int (*sd_scsi_tur)(struct sr_workunit *); int (*sd_scsi_start_stop)(struct sr_workunit *); int (*sd_scsi_inquiry)(struct sr_workunit *); int (*sd_scsi_read_cap)(struct sr_workunit *); int (*sd_scsi_req_sense)(struct sr_workunit *); /* background operation */ struct proc *sd_background_proc; /* Tasks. */ struct task sd_meta_save_task; struct task sd_hotspare_rebuild_task; TAILQ_ENTRY(sr_discipline) sd_link; }; TAILQ_HEAD(sr_discipline_list, sr_discipline); struct sr_softc { struct device sc_dev; struct rwlock sc_lock; struct bio_status sc_status; /* Status and messages. */ struct sr_chunk_head sc_hotspare_list; /* List of hotspares. */ struct rwlock sc_hs_lock; /* Lock for hotspares list. */ int sc_hotspare_no; /* Number of hotspares. */ struct ksensordev sc_sensordev; struct sensor_task *sc_sensor_task; struct scsibus_softc *sc_scsibus; /* The target lookup has to be cheap since it happens for each I/O. */ struct sr_discipline *sc_targets[SR_MAX_LD]; struct sr_discipline_list sc_dis_list; }; /* hotplug */ void sr_hotplug_register(struct sr_discipline *, void *); void sr_hotplug_unregister(struct sr_discipline *, void *); /* Hotspare and rebuild. */ void sr_hotspare_rebuild_callback(void *); /* work units & ccbs */ int sr_ccb_alloc(struct sr_discipline *); void sr_ccb_free(struct sr_discipline *); struct sr_ccb *sr_ccb_get(struct sr_discipline *); void sr_ccb_put(struct sr_ccb *); struct sr_ccb *sr_ccb_rw(struct sr_discipline *, int, daddr_t, long, u_int8_t *, int, int); void sr_ccb_done(struct sr_ccb *); int sr_wu_alloc(struct sr_discipline *); void sr_wu_free(struct sr_discipline *); void *sr_wu_get(void *); void sr_wu_put(void *, void *); void sr_wu_init(struct sr_discipline *, struct sr_workunit *); void sr_wu_enqueue_ccb(struct sr_workunit *, struct sr_ccb *); void sr_wu_release_ccbs(struct sr_workunit *); void sr_wu_done(struct sr_workunit *); /* misc functions */ void sr_info(struct sr_softc *, const char *, ...); void sr_warn(struct sr_softc *, const char *, ...); void sr_error(struct sr_softc *, const char *, ...); int32_t sr_validate_stripsize(u_int32_t); int sr_meta_read(struct sr_discipline *); int sr_meta_native_read(struct sr_discipline *, dev_t, struct sr_metadata *, void *); int sr_meta_validate(struct sr_discipline *, dev_t, struct sr_metadata *, void *); void sr_meta_save_callback(void *); int sr_meta_save(struct sr_discipline *, u_int32_t); void sr_meta_getdevname(struct sr_softc *, dev_t, char *, int); void sr_meta_opt_load(struct sr_softc *, struct sr_metadata *, struct sr_meta_opt_head *); void *sr_block_get(struct sr_discipline *, long); void sr_block_put(struct sr_discipline *, void *, int); void sr_checksum(struct sr_softc *, void *, void *, u_int32_t); int sr_validate_io(struct sr_workunit *, daddr_t *, char *); void sr_schedule_wu(struct sr_workunit *); void sr_scsi_done(struct sr_discipline *, struct scsi_xfer *); struct sr_workunit *sr_scsi_wu_get(struct sr_discipline *, int); void sr_scsi_wu_put(struct sr_discipline *, struct sr_workunit *); int sr_chunk_in_use(struct sr_softc *, dev_t); int sr_rebuild_percent(struct sr_discipline *); /* discipline functions */ int sr_raid_inquiry(struct sr_workunit *); int sr_raid_read_cap(struct sr_workunit *); int sr_raid_tur(struct sr_workunit *); int sr_raid_request_sense( struct sr_workunit *); int sr_raid_start_stop(struct sr_workunit *); int sr_raid_sync(struct sr_workunit *); void sr_raid_intr(struct buf *); void sr_raid_startwu(struct sr_workunit *); void sr_raid_recreate_wu(struct sr_workunit *); /* Discipline specific initialisation. */ void sr_raid0_discipline_init(struct sr_discipline *); void sr_raid1_discipline_init(struct sr_discipline *); void sr_raid5_discipline_init(struct sr_discipline *); void sr_raid6_discipline_init(struct sr_discipline *); void sr_crypto_discipline_init(struct sr_discipline *); void sr_concat_discipline_init(struct sr_discipline *); void sr_raid1c_discipline_init(struct sr_discipline *); /* Crypto discipline hooks. */ int sr_crypto_get_kdf(struct bioc_createraid *, struct sr_discipline *, struct sr_crypto *); int sr_crypto_create_keys(struct sr_discipline *, struct sr_crypto *); struct sr_chunk * sr_crypto_create_key_disk(struct sr_discipline *, struct sr_crypto *, dev_t); struct sr_chunk * sr_crypto_read_key_disk(struct sr_discipline *, struct sr_crypto *, dev_t); /* Hibernate I/O function */ int sr_hibernate_io(dev_t dev, daddr_t blkno, vaddr_t addr, size_t size, int op, void *page); #ifdef SR_DEBUG void sr_dump_block(void *, int); void sr_dump_mem(u_int8_t *, int); #endif #endif /* _KERNEL */ #endif /* SOFTRAIDVAR_H */