1133808Spjd/*- 2156878Spjd * Copyright (c) 2004-2006 Pawel Jakub Dawidek <pjd@FreeBSD.org> 3133808Spjd * All rights reserved. 4133808Spjd * 5133808Spjd * Redistribution and use in source and binary forms, with or without 6133808Spjd * modification, are permitted provided that the following conditions 7133808Spjd * are met: 8133808Spjd * 1. Redistributions of source code must retain the above copyright 9133808Spjd * notice, this list of conditions and the following disclaimer. 10133808Spjd * 2. Redistributions in binary form must reproduce the above copyright 11133808Spjd * notice, this list of conditions and the following disclaimer in the 12133808Spjd * documentation and/or other materials provided with the distribution. 13155174Spjd * 14133808Spjd * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15133808Spjd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16133808Spjd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17133808Spjd * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18133808Spjd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19133808Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20133808Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21133808Spjd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22133808Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23133808Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24133808Spjd * SUCH DAMAGE. 25133808Spjd * 26133808Spjd * $FreeBSD$ 27133808Spjd */ 28133808Spjd 29133808Spjd#ifndef _G_RAID3_H_ 30133808Spjd#define _G_RAID3_H_ 31133808Spjd 32133808Spjd#include <sys/endian.h> 33133808Spjd#include <sys/md5.h> 34133808Spjd 35133808Spjd#define G_RAID3_CLASS_NAME "RAID3" 36133808Spjd 37133808Spjd#define G_RAID3_MAGIC "GEOM::RAID3" 38134136Spjd/* 39134136Spjd * Version history: 40134136Spjd * 0 - Initial version number. 41134136Spjd * 1 - Added 'round-robin reading' algorithm. 42134168Spjd * 2 - Added 'verify reading' algorithm. 43139295Spjd * 3 - Added md_genid field to metadata. 44142727Spjd * 4 - Added md_provsize field to metadata. 45163888Spjd * 5 - Added 'no failure synchronization' flag. 46134136Spjd */ 47163888Spjd#define G_RAID3_VERSION 5 48133808Spjd 49133808Spjd#define G_RAID3_DISK_FLAG_DIRTY 0x0000000000000001ULL 50133808Spjd#define G_RAID3_DISK_FLAG_SYNCHRONIZING 0x0000000000000002ULL 51133808Spjd#define G_RAID3_DISK_FLAG_FORCE_SYNC 0x0000000000000004ULL 52133808Spjd#define G_RAID3_DISK_FLAG_HARDCODED 0x0000000000000008ULL 53155546Spjd#define G_RAID3_DISK_FLAG_BROKEN 0x0000000000000010ULL 54133808Spjd#define G_RAID3_DISK_FLAG_MASK (G_RAID3_DISK_FLAG_DIRTY | \ 55133808Spjd G_RAID3_DISK_FLAG_SYNCHRONIZING | \ 56133808Spjd G_RAID3_DISK_FLAG_FORCE_SYNC) 57133808Spjd 58133808Spjd#define G_RAID3_DEVICE_FLAG_NOAUTOSYNC 0x0000000000000001ULL 59134124Spjd#define G_RAID3_DEVICE_FLAG_ROUND_ROBIN 0x0000000000000002ULL 60134168Spjd#define G_RAID3_DEVICE_FLAG_VERIFY 0x0000000000000004ULL 61163888Spjd#define G_RAID3_DEVICE_FLAG_NOFAILSYNC 0x0000000000000008ULL 62134124Spjd#define G_RAID3_DEVICE_FLAG_MASK (G_RAID3_DEVICE_FLAG_NOAUTOSYNC | \ 63134168Spjd G_RAID3_DEVICE_FLAG_ROUND_ROBIN | \ 64163888Spjd G_RAID3_DEVICE_FLAG_VERIFY | \ 65163888Spjd G_RAID3_DEVICE_FLAG_NOFAILSYNC) 66133808Spjd 67133808Spjd#ifdef _KERNEL 68133808Spjdextern u_int g_raid3_debug; 69133808Spjd 70133808Spjd#define G_RAID3_DEBUG(lvl, ...) do { \ 71133808Spjd if (g_raid3_debug >= (lvl)) { \ 72133808Spjd printf("GEOM_RAID3"); \ 73133808Spjd if (g_raid3_debug > 0) \ 74133808Spjd printf("[%u]", lvl); \ 75133808Spjd printf(": "); \ 76133808Spjd printf(__VA_ARGS__); \ 77133808Spjd printf("\n"); \ 78133808Spjd } \ 79133808Spjd} while (0) 80133808Spjd#define G_RAID3_LOGREQ(lvl, bp, ...) do { \ 81133808Spjd if (g_raid3_debug >= (lvl)) { \ 82133808Spjd printf("GEOM_RAID3"); \ 83133808Spjd if (g_raid3_debug > 0) \ 84133808Spjd printf("[%u]", lvl); \ 85133808Spjd printf(": "); \ 86133808Spjd printf(__VA_ARGS__); \ 87133808Spjd printf(" "); \ 88133808Spjd g_print_bio(bp); \ 89133808Spjd printf("\n"); \ 90133808Spjd } \ 91133808Spjd} while (0) 92133808Spjd 93133808Spjd#define G_RAID3_BIO_CFLAG_REGULAR 0x01 94133808Spjd#define G_RAID3_BIO_CFLAG_SYNC 0x02 95133808Spjd#define G_RAID3_BIO_CFLAG_PARITY 0x04 96133808Spjd#define G_RAID3_BIO_CFLAG_NODISK 0x08 97133808Spjd#define G_RAID3_BIO_CFLAG_REGSYNC 0x10 98134168Spjd#define G_RAID3_BIO_CFLAG_MASK (G_RAID3_BIO_CFLAG_REGULAR | \ 99134168Spjd G_RAID3_BIO_CFLAG_SYNC | \ 100134168Spjd G_RAID3_BIO_CFLAG_PARITY | \ 101134168Spjd G_RAID3_BIO_CFLAG_NODISK | \ 102134168Spjd G_RAID3_BIO_CFLAG_REGSYNC) 103133808Spjd 104133808Spjd#define G_RAID3_BIO_PFLAG_DEGRADED 0x01 105133808Spjd#define G_RAID3_BIO_PFLAG_NOPARITY 0x02 106134168Spjd#define G_RAID3_BIO_PFLAG_VERIFY 0x04 107134168Spjd#define G_RAID3_BIO_PFLAG_MASK (G_RAID3_BIO_PFLAG_DEGRADED | \ 108134168Spjd G_RAID3_BIO_PFLAG_NOPARITY | \ 109134168Spjd G_RAID3_BIO_PFLAG_VERIFY) 110133808Spjd 111133808Spjd/* 112133808Spjd * Informations needed for synchronization. 113133808Spjd */ 114133808Spjdstruct g_raid3_disk_sync { 115133808Spjd struct g_consumer *ds_consumer; /* Consumer connected to our device. */ 116156612Spjd off_t ds_offset; /* Offset of next request to send. */ 117156612Spjd off_t ds_offset_done; /* Offset of already synchronized 118133808Spjd region. */ 119156612Spjd off_t ds_resync; /* Resynchronize from this offset. */ 120156612Spjd u_int ds_syncid; /* Disk's synchronization ID. */ 121156612Spjd u_int ds_inflight; /* Number of in-flight sync requests. */ 122156612Spjd struct bio **ds_bios; /* BIOs for synchronization I/O. */ 123133808Spjd}; 124133808Spjd 125133808Spjd/* 126133808Spjd * Informations needed for synchronization. 127133808Spjd */ 128133808Spjdstruct g_raid3_device_sync { 129133808Spjd struct g_geom *ds_geom; /* Synchronization geom. */ 130133808Spjd}; 131133808Spjd 132133808Spjd#define G_RAID3_DISK_STATE_NODISK 0 133133808Spjd#define G_RAID3_DISK_STATE_NONE 1 134133808Spjd#define G_RAID3_DISK_STATE_NEW 2 135133808Spjd#define G_RAID3_DISK_STATE_ACTIVE 3 136133808Spjd#define G_RAID3_DISK_STATE_STALE 4 137133808Spjd#define G_RAID3_DISK_STATE_SYNCHRONIZING 5 138133808Spjd#define G_RAID3_DISK_STATE_DISCONNECTED 6 139133808Spjd#define G_RAID3_DISK_STATE_DESTROY 7 140133808Spjdstruct g_raid3_disk { 141133808Spjd u_int d_no; /* Disk number. */ 142133808Spjd struct g_consumer *d_consumer; /* Consumer. */ 143133808Spjd struct g_raid3_softc *d_softc; /* Back-pointer to softc. */ 144133808Spjd int d_state; /* Disk state. */ 145133808Spjd uint64_t d_flags; /* Additional flags. */ 146139295Spjd u_int d_genid; /* Disk's generation ID. */ 147133808Spjd struct g_raid3_disk_sync d_sync; /* Sync information. */ 148133808Spjd LIST_ENTRY(g_raid3_disk) d_next; 149133808Spjd}; 150133808Spjd#define d_name d_consumer->provider->name 151133808Spjd 152133808Spjd#define G_RAID3_EVENT_DONTWAIT 0x1 153133808Spjd#define G_RAID3_EVENT_WAIT 0x2 154133808Spjd#define G_RAID3_EVENT_DEVICE 0x4 155133808Spjd#define G_RAID3_EVENT_DONE 0x8 156133808Spjdstruct g_raid3_event { 157133808Spjd struct g_raid3_disk *e_disk; 158133808Spjd int e_state; 159133808Spjd int e_flags; 160133808Spjd int e_error; 161133808Spjd TAILQ_ENTRY(g_raid3_event) e_next; 162133808Spjd}; 163133808Spjd 164133808Spjd#define G_RAID3_DEVICE_FLAG_DESTROY 0x0100000000000000ULL 165133808Spjd#define G_RAID3_DEVICE_FLAG_WAIT 0x0200000000000000ULL 166157630Spjd#define G_RAID3_DEVICE_FLAG_DESTROYING 0x0400000000000000ULL 167133808Spjd 168133808Spjd#define G_RAID3_DEVICE_STATE_STARTING 0 169133808Spjd#define G_RAID3_DEVICE_STATE_DEGRADED 1 170133808Spjd#define G_RAID3_DEVICE_STATE_COMPLETE 2 171133808Spjd 172139295Spjd/* Bump syncid on first write. */ 173139671Spjd#define G_RAID3_BUMP_SYNCID 0x1 174139295Spjd/* Bump genid immediately. */ 175139671Spjd#define G_RAID3_BUMP_GENID 0x2 176133808Spjd 177156612Spjdenum g_raid3_zones { 178156612Spjd G_RAID3_ZONE_64K, 179156612Spjd G_RAID3_ZONE_16K, 180156612Spjd G_RAID3_ZONE_4K, 181156612Spjd G_RAID3_NUM_ZONES 182156612Spjd}; 183156612Spjd 184156612Spjdstatic __inline enum g_raid3_zones 185156612Spjdg_raid3_zone(size_t nbytes) { 186200821Smav if (nbytes > 65536) 187200821Smav return (G_RAID3_NUM_ZONES); 188200821Smav else if (nbytes > 16384) 189156612Spjd return (G_RAID3_ZONE_64K); 190156612Spjd else if (nbytes > 4096) 191156612Spjd return (G_RAID3_ZONE_16K); 192156612Spjd else 193156612Spjd return (G_RAID3_ZONE_4K); 194156612Spjd}; 195156612Spjd 196133808Spjdstruct g_raid3_softc { 197133808Spjd u_int sc_state; /* Device state. */ 198133808Spjd uint64_t sc_mediasize; /* Device size. */ 199133808Spjd uint32_t sc_sectorsize; /* Sector size. */ 200133808Spjd uint64_t sc_flags; /* Additional flags. */ 201133808Spjd 202133808Spjd struct g_geom *sc_geom; 203133808Spjd struct g_provider *sc_provider; 204133808Spjd 205133808Spjd uint32_t sc_id; /* Device unique ID. */ 206133808Spjd 207156612Spjd struct sx sc_lock; 208133808Spjd struct bio_queue_head sc_queue; 209133808Spjd struct mtx sc_queue_mtx; 210133808Spjd struct proc *sc_worker; 211156612Spjd struct bio_queue_head sc_regular_delayed; /* Delayed I/O requests due 212156612Spjd collision with sync 213156612Spjd requests. */ 214156612Spjd struct bio_queue_head sc_inflight; /* In-flight regular write 215156612Spjd requests. */ 216156612Spjd struct bio_queue_head sc_sync_delayed; /* Delayed sync requests due 217156612Spjd collision with regular 218156612Spjd requests. */ 219133808Spjd 220133808Spjd struct g_raid3_disk *sc_disks; 221133808Spjd u_int sc_ndisks; /* Number of disks. */ 222134124Spjd u_int sc_round_robin; 223133808Spjd struct g_raid3_disk *sc_syncdisk; 224133808Spjd 225156612Spjd struct g_raid3_zone { 226156612Spjd uma_zone_t sz_zone; 227156612Spjd size_t sz_inuse; 228156612Spjd size_t sz_max; 229156612Spjd u_int sz_requested; 230156612Spjd u_int sz_failed; 231156612Spjd } sc_zones[G_RAID3_NUM_ZONES]; 232133808Spjd 233139295Spjd u_int sc_genid; /* Generation ID. */ 234133808Spjd u_int sc_syncid; /* Synchronization ID. */ 235139295Spjd int sc_bump_id; 236133808Spjd struct g_raid3_device_sync sc_sync; 237137258Spjd int sc_idle; /* DIRTY flags removed. */ 238155540Spjd time_t sc_last_write; 239155540Spjd u_int sc_writes; 240133808Spjd 241133808Spjd TAILQ_HEAD(, g_raid3_event) sc_events; 242133808Spjd struct mtx sc_events_mtx; 243133808Spjd 244133808Spjd struct callout sc_callout; 245148440Spjd 246148440Spjd struct root_hold_token *sc_rootmount; 247133808Spjd}; 248133808Spjd#define sc_name sc_geom->name 249133808Spjd 250133808Spjdconst char *g_raid3_get_diskname(struct g_raid3_disk *disk); 251133808Spjdu_int g_raid3_ndisks(struct g_raid3_softc *sc, int state); 252157630Spjd#define G_RAID3_DESTROY_SOFT 0 253157630Spjd#define G_RAID3_DESTROY_DELAYED 1 254157630Spjd#define G_RAID3_DESTROY_HARD 2 255157630Spjdint g_raid3_destroy(struct g_raid3_softc *sc, int how); 256133808Spjdint g_raid3_event_send(void *arg, int state, int flags); 257133808Spjdstruct g_raid3_metadata; 258139671Spjdint g_raid3_add_disk(struct g_raid3_softc *sc, struct g_provider *pp, 259139671Spjd struct g_raid3_metadata *md); 260139671Spjdint g_raid3_read_metadata(struct g_consumer *cp, struct g_raid3_metadata *md); 261133808Spjdvoid g_raid3_fill_metadata(struct g_raid3_disk *disk, 262133808Spjd struct g_raid3_metadata *md); 263133808Spjdint g_raid3_clear_metadata(struct g_raid3_disk *disk); 264133808Spjdvoid g_raid3_update_metadata(struct g_raid3_disk *disk); 265133808Spjd 266133808Spjdg_ctl_req_t g_raid3_config; 267133808Spjd#endif /* _KERNEL */ 268133808Spjd 269133808Spjdstruct g_raid3_metadata { 270133808Spjd char md_magic[16]; /* Magic value. */ 271133808Spjd uint32_t md_version; /* Version number. */ 272133808Spjd char md_name[16]; /* Device name. */ 273133808Spjd uint32_t md_id; /* Device unique ID. */ 274133808Spjd uint16_t md_no; /* Component number. */ 275133808Spjd uint16_t md_all; /* Number of disks in device. */ 276139295Spjd uint32_t md_genid; /* Generation ID. */ 277133808Spjd uint32_t md_syncid; /* Synchronization ID. */ 278133808Spjd uint64_t md_mediasize; /* Size of whole device. */ 279133808Spjd uint32_t md_sectorsize; /* Sector size. */ 280133808Spjd uint64_t md_sync_offset; /* Synchronized offset. */ 281133808Spjd uint64_t md_mflags; /* Additional device flags. */ 282133808Spjd uint64_t md_dflags; /* Additional disk flags. */ 283133808Spjd char md_provider[16]; /* Hardcoded provider. */ 284142727Spjd uint64_t md_provsize; /* Provider's size. */ 285133808Spjd u_char md_hash[16]; /* MD5 hash. */ 286133808Spjd}; 287133808Spjdstatic __inline void 288133808Spjdraid3_metadata_encode(struct g_raid3_metadata *md, u_char *data) 289133808Spjd{ 290133808Spjd MD5_CTX ctx; 291133808Spjd 292133808Spjd bcopy(md->md_magic, data, 16); 293133808Spjd le32enc(data + 16, md->md_version); 294133808Spjd bcopy(md->md_name, data + 20, 16); 295133808Spjd le32enc(data + 36, md->md_id); 296133808Spjd le16enc(data + 40, md->md_no); 297133808Spjd le16enc(data + 42, md->md_all); 298139295Spjd le32enc(data + 44, md->md_genid); 299139295Spjd le32enc(data + 48, md->md_syncid); 300139295Spjd le64enc(data + 52, md->md_mediasize); 301139295Spjd le32enc(data + 60, md->md_sectorsize); 302139295Spjd le64enc(data + 64, md->md_sync_offset); 303139295Spjd le64enc(data + 72, md->md_mflags); 304139295Spjd le64enc(data + 80, md->md_dflags); 305139295Spjd bcopy(md->md_provider, data + 88, 16); 306142727Spjd le64enc(data + 104, md->md_provsize); 307133808Spjd MD5Init(&ctx); 308142727Spjd MD5Update(&ctx, data, 112); 309133808Spjd MD5Final(md->md_hash, &ctx); 310142727Spjd bcopy(md->md_hash, data + 112, 16); 311133808Spjd} 312133808Spjdstatic __inline int 313139295Spjdraid3_metadata_decode_v0v1v2(const u_char *data, struct g_raid3_metadata *md) 314133808Spjd{ 315133808Spjd MD5_CTX ctx; 316133808Spjd 317133808Spjd bcopy(data + 20, md->md_name, 16); 318133808Spjd md->md_id = le32dec(data + 36); 319133808Spjd md->md_no = le16dec(data + 40); 320133808Spjd md->md_all = le16dec(data + 42); 321133808Spjd md->md_syncid = le32dec(data + 44); 322133808Spjd md->md_mediasize = le64dec(data + 48); 323133808Spjd md->md_sectorsize = le32dec(data + 56); 324133808Spjd md->md_sync_offset = le64dec(data + 60); 325133808Spjd md->md_mflags = le64dec(data + 68); 326133808Spjd md->md_dflags = le64dec(data + 76); 327133808Spjd bcopy(data + 84, md->md_provider, 16); 328133808Spjd bcopy(data + 100, md->md_hash, 16); 329133808Spjd MD5Init(&ctx); 330133808Spjd MD5Update(&ctx, data, 100); 331133808Spjd MD5Final(md->md_hash, &ctx); 332133808Spjd if (bcmp(md->md_hash, data + 100, 16) != 0) 333133808Spjd return (EINVAL); 334142727Spjd 335142727Spjd /* New fields. */ 336142727Spjd md->md_genid = 0; 337142727Spjd md->md_provsize = 0; 338142727Spjd 339133808Spjd return (0); 340133808Spjd} 341139295Spjdstatic __inline int 342139295Spjdraid3_metadata_decode_v3(const u_char *data, struct g_raid3_metadata *md) 343139295Spjd{ 344139295Spjd MD5_CTX ctx; 345133808Spjd 346139295Spjd bcopy(data + 20, md->md_name, 16); 347139295Spjd md->md_id = le32dec(data + 36); 348139295Spjd md->md_no = le16dec(data + 40); 349139295Spjd md->md_all = le16dec(data + 42); 350139295Spjd md->md_genid = le32dec(data + 44); 351139295Spjd md->md_syncid = le32dec(data + 48); 352139295Spjd md->md_mediasize = le64dec(data + 52); 353139295Spjd md->md_sectorsize = le32dec(data + 60); 354139295Spjd md->md_sync_offset = le64dec(data + 64); 355139295Spjd md->md_mflags = le64dec(data + 72); 356139295Spjd md->md_dflags = le64dec(data + 80); 357139295Spjd bcopy(data + 88, md->md_provider, 16); 358139295Spjd bcopy(data + 104, md->md_hash, 16); 359139295Spjd MD5Init(&ctx); 360139295Spjd MD5Update(&ctx, data, 104); 361139295Spjd MD5Final(md->md_hash, &ctx); 362139295Spjd if (bcmp(md->md_hash, data + 104, 16) != 0) 363139295Spjd return (EINVAL); 364142727Spjd 365142727Spjd /* New fields. */ 366142727Spjd md->md_provsize = 0; 367142727Spjd 368139295Spjd return (0); 369139295Spjd} 370139295Spjdstatic __inline int 371163888Spjdraid3_metadata_decode_v4v5(const u_char *data, struct g_raid3_metadata *md) 372142727Spjd{ 373142727Spjd MD5_CTX ctx; 374142727Spjd 375142727Spjd bcopy(data + 20, md->md_name, 16); 376142727Spjd md->md_id = le32dec(data + 36); 377142727Spjd md->md_no = le16dec(data + 40); 378142727Spjd md->md_all = le16dec(data + 42); 379142727Spjd md->md_genid = le32dec(data + 44); 380142727Spjd md->md_syncid = le32dec(data + 48); 381142727Spjd md->md_mediasize = le64dec(data + 52); 382142727Spjd md->md_sectorsize = le32dec(data + 60); 383142727Spjd md->md_sync_offset = le64dec(data + 64); 384142727Spjd md->md_mflags = le64dec(data + 72); 385142727Spjd md->md_dflags = le64dec(data + 80); 386142727Spjd bcopy(data + 88, md->md_provider, 16); 387142727Spjd md->md_provsize = le64dec(data + 104); 388142727Spjd bcopy(data + 112, md->md_hash, 16); 389142727Spjd MD5Init(&ctx); 390142727Spjd MD5Update(&ctx, data, 112); 391142727Spjd MD5Final(md->md_hash, &ctx); 392142727Spjd if (bcmp(md->md_hash, data + 112, 16) != 0) 393142727Spjd return (EINVAL); 394142727Spjd return (0); 395142727Spjd} 396142727Spjdstatic __inline int 397139295Spjdraid3_metadata_decode(const u_char *data, struct g_raid3_metadata *md) 398139295Spjd{ 399139295Spjd int error; 400155174Spjd 401139295Spjd bcopy(data, md->md_magic, 16); 402139295Spjd md->md_version = le32dec(data + 16); 403139295Spjd switch (md->md_version) { 404139295Spjd case 0: 405139295Spjd case 1: 406139295Spjd case 2: 407139295Spjd error = raid3_metadata_decode_v0v1v2(data, md); 408139295Spjd break; 409139295Spjd case 3: 410139295Spjd error = raid3_metadata_decode_v3(data, md); 411139295Spjd break; 412142727Spjd case 4: 413163888Spjd case 5: 414163888Spjd error = raid3_metadata_decode_v4v5(data, md); 415142727Spjd break; 416139295Spjd default: 417139295Spjd error = EINVAL; 418139295Spjd break; 419139295Spjd } 420139295Spjd return (error); 421139295Spjd} 422139295Spjd 423133808Spjdstatic __inline void 424133808Spjdraid3_metadata_dump(const struct g_raid3_metadata *md) 425133808Spjd{ 426133808Spjd static const char hex[] = "0123456789abcdef"; 427133808Spjd char hash[16 * 2 + 1]; 428133808Spjd u_int i; 429133808Spjd 430133808Spjd printf(" magic: %s\n", md->md_magic); 431133808Spjd printf(" version: %u\n", (u_int)md->md_version); 432133808Spjd printf(" name: %s\n", md->md_name); 433133808Spjd printf(" id: %u\n", (u_int)md->md_id); 434133808Spjd printf(" no: %u\n", (u_int)md->md_no); 435133808Spjd printf(" all: %u\n", (u_int)md->md_all); 436139295Spjd printf(" genid: %u\n", (u_int)md->md_genid); 437133808Spjd printf(" syncid: %u\n", (u_int)md->md_syncid); 438133808Spjd printf(" mediasize: %jd\n", (intmax_t)md->md_mediasize); 439133808Spjd printf("sectorsize: %u\n", (u_int)md->md_sectorsize); 440133808Spjd printf("syncoffset: %jd\n", (intmax_t)md->md_sync_offset); 441133808Spjd printf(" mflags:"); 442133808Spjd if (md->md_mflags == 0) 443133808Spjd printf(" NONE"); 444133808Spjd else { 445133808Spjd if ((md->md_mflags & G_RAID3_DEVICE_FLAG_NOAUTOSYNC) != 0) 446133808Spjd printf(" NOAUTOSYNC"); 447134124Spjd if ((md->md_mflags & G_RAID3_DEVICE_FLAG_ROUND_ROBIN) != 0) 448134124Spjd printf(" ROUND-ROBIN"); 449134168Spjd if ((md->md_mflags & G_RAID3_DEVICE_FLAG_VERIFY) != 0) 450134168Spjd printf(" VERIFY"); 451163888Spjd if ((md->md_mflags & G_RAID3_DEVICE_FLAG_NOFAILSYNC) != 0) 452163888Spjd printf(" NOFAILSYNC"); 453133808Spjd } 454133808Spjd printf("\n"); 455133808Spjd printf(" dflags:"); 456133808Spjd if (md->md_dflags == 0) 457133808Spjd printf(" NONE"); 458133808Spjd else { 459133808Spjd if ((md->md_dflags & G_RAID3_DISK_FLAG_DIRTY) != 0) 460133808Spjd printf(" DIRTY"); 461133808Spjd if ((md->md_dflags & G_RAID3_DISK_FLAG_SYNCHRONIZING) != 0) 462133808Spjd printf(" SYNCHRONIZING"); 463133808Spjd if ((md->md_dflags & G_RAID3_DISK_FLAG_FORCE_SYNC) != 0) 464133808Spjd printf(" FORCE_SYNC"); 465133808Spjd } 466133808Spjd printf("\n"); 467133808Spjd printf("hcprovider: %s\n", md->md_provider); 468142727Spjd printf(" provsize: %ju\n", (uintmax_t)md->md_provsize); 469133808Spjd bzero(hash, sizeof(hash)); 470133808Spjd for (i = 0; i < 16; i++) { 471133808Spjd hash[i * 2] = hex[md->md_hash[i] >> 4]; 472133808Spjd hash[i * 2 + 1] = hex[md->md_hash[i] & 0x0f]; 473133808Spjd } 474133808Spjd printf(" MD5 hash: %s\n", hash); 475133808Spjd} 476133808Spjd#endif /* !_G_RAID3_H_ */ 477