12d1661a5SPawel Jakub Dawidek /*- 22d1661a5SPawel Jakub Dawidek * Copyright (c) 2004 Pawel Jakub Dawidek <pjd@FreeBSD.org> 32d1661a5SPawel Jakub Dawidek * All rights reserved. 42d1661a5SPawel Jakub Dawidek * 52d1661a5SPawel Jakub Dawidek * Redistribution and use in source and binary forms, with or without 62d1661a5SPawel Jakub Dawidek * modification, are permitted provided that the following conditions 72d1661a5SPawel Jakub Dawidek * are met: 82d1661a5SPawel Jakub Dawidek * 1. Redistributions of source code must retain the above copyright 92d1661a5SPawel Jakub Dawidek * notice, this list of conditions and the following disclaimer. 102d1661a5SPawel Jakub Dawidek * 2. Redistributions in binary form must reproduce the above copyright 112d1661a5SPawel Jakub Dawidek * notice, this list of conditions and the following disclaimer in the 122d1661a5SPawel Jakub Dawidek * documentation and/or other materials provided with the distribution. 132d1661a5SPawel Jakub Dawidek * 142d1661a5SPawel Jakub Dawidek * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 152d1661a5SPawel Jakub Dawidek * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 162d1661a5SPawel Jakub Dawidek * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 172d1661a5SPawel Jakub Dawidek * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 182d1661a5SPawel Jakub Dawidek * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 192d1661a5SPawel Jakub Dawidek * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 202d1661a5SPawel Jakub Dawidek * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 212d1661a5SPawel Jakub Dawidek * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 222d1661a5SPawel Jakub Dawidek * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 232d1661a5SPawel Jakub Dawidek * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 242d1661a5SPawel Jakub Dawidek * SUCH DAMAGE. 252d1661a5SPawel Jakub Dawidek * 262d1661a5SPawel Jakub Dawidek * $FreeBSD$ 272d1661a5SPawel Jakub Dawidek */ 282d1661a5SPawel Jakub Dawidek 292d1661a5SPawel Jakub Dawidek #ifndef _G_RAID3_H_ 302d1661a5SPawel Jakub Dawidek #define _G_RAID3_H_ 312d1661a5SPawel Jakub Dawidek 322d1661a5SPawel Jakub Dawidek #include <sys/endian.h> 332d1661a5SPawel Jakub Dawidek #include <sys/md5.h> 342d1661a5SPawel Jakub Dawidek 352d1661a5SPawel Jakub Dawidek #define G_RAID3_CLASS_NAME "RAID3" 362d1661a5SPawel Jakub Dawidek 372d1661a5SPawel Jakub Dawidek #define G_RAID3_MAGIC "GEOM::RAID3" 38d12bd83eSPawel Jakub Dawidek /* 39d12bd83eSPawel Jakub Dawidek * Version history: 40d12bd83eSPawel Jakub Dawidek * 0 - Initial version number. 41d12bd83eSPawel Jakub Dawidek * 1 - Added 'round-robin reading' algorithm. 42dba915cfSPawel Jakub Dawidek * 2 - Added 'verify reading' algorithm. 43d12bd83eSPawel Jakub Dawidek */ 44dba915cfSPawel Jakub Dawidek #define G_RAID3_VERSION 2 452d1661a5SPawel Jakub Dawidek 462d1661a5SPawel Jakub Dawidek #define G_RAID3_DISK_FLAG_DIRTY 0x0000000000000001ULL 472d1661a5SPawel Jakub Dawidek #define G_RAID3_DISK_FLAG_SYNCHRONIZING 0x0000000000000002ULL 482d1661a5SPawel Jakub Dawidek #define G_RAID3_DISK_FLAG_FORCE_SYNC 0x0000000000000004ULL 492d1661a5SPawel Jakub Dawidek #define G_RAID3_DISK_FLAG_HARDCODED 0x0000000000000008ULL 502d1661a5SPawel Jakub Dawidek #define G_RAID3_DISK_FLAG_MASK (G_RAID3_DISK_FLAG_DIRTY | \ 512d1661a5SPawel Jakub Dawidek G_RAID3_DISK_FLAG_SYNCHRONIZING | \ 522d1661a5SPawel Jakub Dawidek G_RAID3_DISK_FLAG_FORCE_SYNC) 532d1661a5SPawel Jakub Dawidek 542d1661a5SPawel Jakub Dawidek #define G_RAID3_DEVICE_FLAG_NOAUTOSYNC 0x0000000000000001ULL 55f5a2f7feSPawel Jakub Dawidek #define G_RAID3_DEVICE_FLAG_ROUND_ROBIN 0x0000000000000002ULL 56dba915cfSPawel Jakub Dawidek #define G_RAID3_DEVICE_FLAG_VERIFY 0x0000000000000004ULL 57f5a2f7feSPawel Jakub Dawidek #define G_RAID3_DEVICE_FLAG_MASK (G_RAID3_DEVICE_FLAG_NOAUTOSYNC | \ 58dba915cfSPawel Jakub Dawidek G_RAID3_DEVICE_FLAG_ROUND_ROBIN | \ 59dba915cfSPawel Jakub Dawidek G_RAID3_DEVICE_FLAG_VERIFY) 602d1661a5SPawel Jakub Dawidek 612d1661a5SPawel Jakub Dawidek #ifdef _KERNEL 622d1661a5SPawel Jakub Dawidek extern u_int g_raid3_debug; 632d1661a5SPawel Jakub Dawidek 642d1661a5SPawel Jakub Dawidek #define G_RAID3_DEBUG(lvl, ...) do { \ 652d1661a5SPawel Jakub Dawidek if (g_raid3_debug >= (lvl)) { \ 662d1661a5SPawel Jakub Dawidek printf("GEOM_RAID3"); \ 672d1661a5SPawel Jakub Dawidek if (g_raid3_debug > 0) \ 682d1661a5SPawel Jakub Dawidek printf("[%u]", lvl); \ 692d1661a5SPawel Jakub Dawidek printf(": "); \ 702d1661a5SPawel Jakub Dawidek printf(__VA_ARGS__); \ 712d1661a5SPawel Jakub Dawidek printf("\n"); \ 722d1661a5SPawel Jakub Dawidek } \ 732d1661a5SPawel Jakub Dawidek } while (0) 742d1661a5SPawel Jakub Dawidek #define G_RAID3_LOGREQ(lvl, bp, ...) do { \ 752d1661a5SPawel Jakub Dawidek if (g_raid3_debug >= (lvl)) { \ 762d1661a5SPawel Jakub Dawidek printf("GEOM_RAID3"); \ 772d1661a5SPawel Jakub Dawidek if (g_raid3_debug > 0) \ 782d1661a5SPawel Jakub Dawidek printf("[%u]", lvl); \ 792d1661a5SPawel Jakub Dawidek printf(": "); \ 802d1661a5SPawel Jakub Dawidek printf(__VA_ARGS__); \ 812d1661a5SPawel Jakub Dawidek printf(" "); \ 822d1661a5SPawel Jakub Dawidek g_print_bio(bp); \ 832d1661a5SPawel Jakub Dawidek printf("\n"); \ 842d1661a5SPawel Jakub Dawidek } \ 852d1661a5SPawel Jakub Dawidek } while (0) 862d1661a5SPawel Jakub Dawidek 872d1661a5SPawel Jakub Dawidek #define G_RAID3_MAX_IO_SIZE (DFLTPHYS * 2) 882d1661a5SPawel Jakub Dawidek 892d1661a5SPawel Jakub Dawidek #define G_RAID3_BIO_CFLAG_REGULAR 0x01 902d1661a5SPawel Jakub Dawidek #define G_RAID3_BIO_CFLAG_SYNC 0x02 912d1661a5SPawel Jakub Dawidek #define G_RAID3_BIO_CFLAG_PARITY 0x04 922d1661a5SPawel Jakub Dawidek #define G_RAID3_BIO_CFLAG_NODISK 0x08 932d1661a5SPawel Jakub Dawidek #define G_RAID3_BIO_CFLAG_REGSYNC 0x10 94dba915cfSPawel Jakub Dawidek #define G_RAID3_BIO_CFLAG_MASK (G_RAID3_BIO_CFLAG_REGULAR | \ 95dba915cfSPawel Jakub Dawidek G_RAID3_BIO_CFLAG_SYNC | \ 96dba915cfSPawel Jakub Dawidek G_RAID3_BIO_CFLAG_PARITY | \ 97dba915cfSPawel Jakub Dawidek G_RAID3_BIO_CFLAG_NODISK | \ 98dba915cfSPawel Jakub Dawidek G_RAID3_BIO_CFLAG_REGSYNC) 992d1661a5SPawel Jakub Dawidek 1002d1661a5SPawel Jakub Dawidek #define G_RAID3_BIO_PFLAG_DEGRADED 0x01 1012d1661a5SPawel Jakub Dawidek #define G_RAID3_BIO_PFLAG_NOPARITY 0x02 102dba915cfSPawel Jakub Dawidek #define G_RAID3_BIO_PFLAG_VERIFY 0x04 103dba915cfSPawel Jakub Dawidek #define G_RAID3_BIO_PFLAG_MASK (G_RAID3_BIO_PFLAG_DEGRADED | \ 104dba915cfSPawel Jakub Dawidek G_RAID3_BIO_PFLAG_NOPARITY | \ 105dba915cfSPawel Jakub Dawidek G_RAID3_BIO_PFLAG_VERIFY) 1062d1661a5SPawel Jakub Dawidek 1072d1661a5SPawel Jakub Dawidek /* 1082d1661a5SPawel Jakub Dawidek * Informations needed for synchronization. 1092d1661a5SPawel Jakub Dawidek */ 1102d1661a5SPawel Jakub Dawidek struct g_raid3_disk_sync { 1112d1661a5SPawel Jakub Dawidek struct g_consumer *ds_consumer; /* Consumer connected to our device. */ 1122d1661a5SPawel Jakub Dawidek off_t ds_offset; /* Offset of next request to send. */ 1132d1661a5SPawel Jakub Dawidek off_t ds_offset_done; /* Offset of already synchronized 1142d1661a5SPawel Jakub Dawidek region. */ 115d2fb9c62SPawel Jakub Dawidek off_t ds_resync; /* Resynchronize from this offset. */ 1162d1661a5SPawel Jakub Dawidek u_int ds_syncid; /* Disk's synchronization ID. */ 1172d1661a5SPawel Jakub Dawidek u_char *ds_data; 1182d1661a5SPawel Jakub Dawidek }; 1192d1661a5SPawel Jakub Dawidek 1202d1661a5SPawel Jakub Dawidek /* 1212d1661a5SPawel Jakub Dawidek * Informations needed for synchronization. 1222d1661a5SPawel Jakub Dawidek */ 1232d1661a5SPawel Jakub Dawidek struct g_raid3_device_sync { 1242d1661a5SPawel Jakub Dawidek struct g_geom *ds_geom; /* Synchronization geom. */ 1252d1661a5SPawel Jakub Dawidek }; 1262d1661a5SPawel Jakub Dawidek 1272d1661a5SPawel Jakub Dawidek #define G_RAID3_DISK_STATE_NODISK 0 1282d1661a5SPawel Jakub Dawidek #define G_RAID3_DISK_STATE_NONE 1 1292d1661a5SPawel Jakub Dawidek #define G_RAID3_DISK_STATE_NEW 2 1302d1661a5SPawel Jakub Dawidek #define G_RAID3_DISK_STATE_ACTIVE 3 1312d1661a5SPawel Jakub Dawidek #define G_RAID3_DISK_STATE_STALE 4 1322d1661a5SPawel Jakub Dawidek #define G_RAID3_DISK_STATE_SYNCHRONIZING 5 1332d1661a5SPawel Jakub Dawidek #define G_RAID3_DISK_STATE_DISCONNECTED 6 1342d1661a5SPawel Jakub Dawidek #define G_RAID3_DISK_STATE_DESTROY 7 1352d1661a5SPawel Jakub Dawidek struct g_raid3_disk { 1362d1661a5SPawel Jakub Dawidek u_int d_no; /* Disk number. */ 1372d1661a5SPawel Jakub Dawidek struct g_consumer *d_consumer; /* Consumer. */ 1382d1661a5SPawel Jakub Dawidek struct g_raid3_softc *d_softc; /* Back-pointer to softc. */ 1392d1661a5SPawel Jakub Dawidek int d_state; /* Disk state. */ 1402d1661a5SPawel Jakub Dawidek uint64_t d_flags; /* Additional flags. */ 1412d1661a5SPawel Jakub Dawidek struct g_raid3_disk_sync d_sync; /* Sync information. */ 1422d1661a5SPawel Jakub Dawidek LIST_ENTRY(g_raid3_disk) d_next; 1432d1661a5SPawel Jakub Dawidek }; 1442d1661a5SPawel Jakub Dawidek #define d_name d_consumer->provider->name 1452d1661a5SPawel Jakub Dawidek 1462d1661a5SPawel Jakub Dawidek #define G_RAID3_EVENT_DONTWAIT 0x1 1472d1661a5SPawel Jakub Dawidek #define G_RAID3_EVENT_WAIT 0x2 1482d1661a5SPawel Jakub Dawidek #define G_RAID3_EVENT_DEVICE 0x4 1492d1661a5SPawel Jakub Dawidek #define G_RAID3_EVENT_DONE 0x8 1502d1661a5SPawel Jakub Dawidek struct g_raid3_event { 1512d1661a5SPawel Jakub Dawidek struct g_raid3_disk *e_disk; 1522d1661a5SPawel Jakub Dawidek int e_state; 1532d1661a5SPawel Jakub Dawidek int e_flags; 1542d1661a5SPawel Jakub Dawidek int e_error; 1552d1661a5SPawel Jakub Dawidek TAILQ_ENTRY(g_raid3_event) e_next; 1562d1661a5SPawel Jakub Dawidek }; 1572d1661a5SPawel Jakub Dawidek 1582d1661a5SPawel Jakub Dawidek #define G_RAID3_DEVICE_FLAG_DESTROY 0x0100000000000000ULL 1592d1661a5SPawel Jakub Dawidek #define G_RAID3_DEVICE_FLAG_WAIT 0x0200000000000000ULL 1602d1661a5SPawel Jakub Dawidek 1612d1661a5SPawel Jakub Dawidek #define G_RAID3_DEVICE_STATE_STARTING 0 1622d1661a5SPawel Jakub Dawidek #define G_RAID3_DEVICE_STATE_DEGRADED 1 1632d1661a5SPawel Jakub Dawidek #define G_RAID3_DEVICE_STATE_COMPLETE 2 1642d1661a5SPawel Jakub Dawidek 1652d1661a5SPawel Jakub Dawidek #define G_RAID3_BUMP_ON_FIRST_WRITE 1 1662d1661a5SPawel Jakub Dawidek #define G_RAID3_BUMP_IMMEDIATELY 2 1672d1661a5SPawel Jakub Dawidek 1682d1661a5SPawel Jakub Dawidek struct g_raid3_softc { 1692d1661a5SPawel Jakub Dawidek u_int sc_state; /* Device state. */ 1702d1661a5SPawel Jakub Dawidek uint64_t sc_mediasize; /* Device size. */ 1712d1661a5SPawel Jakub Dawidek uint32_t sc_sectorsize; /* Sector size. */ 1722d1661a5SPawel Jakub Dawidek uint64_t sc_flags; /* Additional flags. */ 1732d1661a5SPawel Jakub Dawidek 1742d1661a5SPawel Jakub Dawidek struct g_geom *sc_geom; 1752d1661a5SPawel Jakub Dawidek struct g_provider *sc_provider; 1762d1661a5SPawel Jakub Dawidek 1772d1661a5SPawel Jakub Dawidek uint32_t sc_id; /* Device unique ID. */ 1782d1661a5SPawel Jakub Dawidek 1792d1661a5SPawel Jakub Dawidek struct bio_queue_head sc_queue; 1802d1661a5SPawel Jakub Dawidek struct mtx sc_queue_mtx; 1812d1661a5SPawel Jakub Dawidek struct proc *sc_worker; 1822d1661a5SPawel Jakub Dawidek 1832d1661a5SPawel Jakub Dawidek struct g_raid3_disk *sc_disks; 1842d1661a5SPawel Jakub Dawidek u_int sc_ndisks; /* Number of disks. */ 185f5a2f7feSPawel Jakub Dawidek u_int sc_round_robin; 1862d1661a5SPawel Jakub Dawidek struct g_raid3_disk *sc_syncdisk; 1872d1661a5SPawel Jakub Dawidek 1882d1661a5SPawel Jakub Dawidek uma_zone_t sc_zone_64k; 1892d1661a5SPawel Jakub Dawidek uma_zone_t sc_zone_16k; 1902d1661a5SPawel Jakub Dawidek uma_zone_t sc_zone_4k; 1912d1661a5SPawel Jakub Dawidek 1922d1661a5SPawel Jakub Dawidek u_int sc_syncid; /* Synchronization ID. */ 1932d1661a5SPawel Jakub Dawidek int sc_bump_syncid; 1942d1661a5SPawel Jakub Dawidek struct g_raid3_device_sync sc_sync; 1952d1661a5SPawel Jakub Dawidek 1962d1661a5SPawel Jakub Dawidek TAILQ_HEAD(, g_raid3_event) sc_events; 1972d1661a5SPawel Jakub Dawidek struct mtx sc_events_mtx; 1982d1661a5SPawel Jakub Dawidek 1992d1661a5SPawel Jakub Dawidek struct callout sc_callout; 2002d1661a5SPawel Jakub Dawidek }; 2012d1661a5SPawel Jakub Dawidek #define sc_name sc_geom->name 2022d1661a5SPawel Jakub Dawidek 2032d1661a5SPawel Jakub Dawidek const char *g_raid3_get_diskname(struct g_raid3_disk *disk); 2042d1661a5SPawel Jakub Dawidek u_int g_raid3_ndisks(struct g_raid3_softc *sc, int state); 2052d1661a5SPawel Jakub Dawidek int g_raid3_destroy(struct g_raid3_softc *sc, boolean_t force); 2062d1661a5SPawel Jakub Dawidek int g_raid3_event_send(void *arg, int state, int flags); 2072d1661a5SPawel Jakub Dawidek struct g_raid3_metadata; 2082d1661a5SPawel Jakub Dawidek void g_raid3_fill_metadata(struct g_raid3_disk *disk, 2092d1661a5SPawel Jakub Dawidek struct g_raid3_metadata *md); 2102d1661a5SPawel Jakub Dawidek int g_raid3_clear_metadata(struct g_raid3_disk *disk); 2112d1661a5SPawel Jakub Dawidek void g_raid3_update_metadata(struct g_raid3_disk *disk); 2122d1661a5SPawel Jakub Dawidek 2132d1661a5SPawel Jakub Dawidek g_ctl_req_t g_raid3_config; 2142d1661a5SPawel Jakub Dawidek #endif /* _KERNEL */ 2152d1661a5SPawel Jakub Dawidek 2162d1661a5SPawel Jakub Dawidek struct g_raid3_metadata { 2172d1661a5SPawel Jakub Dawidek char md_magic[16]; /* Magic value. */ 2182d1661a5SPawel Jakub Dawidek uint32_t md_version; /* Version number. */ 2192d1661a5SPawel Jakub Dawidek char md_name[16]; /* Device name. */ 2202d1661a5SPawel Jakub Dawidek uint32_t md_id; /* Device unique ID. */ 2212d1661a5SPawel Jakub Dawidek uint16_t md_no; /* Component number. */ 2222d1661a5SPawel Jakub Dawidek uint16_t md_all; /* Number of disks in device. */ 2232d1661a5SPawel Jakub Dawidek uint32_t md_syncid; /* Synchronization ID. */ 2242d1661a5SPawel Jakub Dawidek uint64_t md_mediasize; /* Size of whole device. */ 2252d1661a5SPawel Jakub Dawidek uint32_t md_sectorsize; /* Sector size. */ 2262d1661a5SPawel Jakub Dawidek uint64_t md_sync_offset; /* Synchronized offset. */ 2272d1661a5SPawel Jakub Dawidek uint64_t md_mflags; /* Additional device flags. */ 2282d1661a5SPawel Jakub Dawidek uint64_t md_dflags; /* Additional disk flags. */ 2292d1661a5SPawel Jakub Dawidek char md_provider[16]; /* Hardcoded provider. */ 2302d1661a5SPawel Jakub Dawidek u_char md_hash[16]; /* MD5 hash. */ 2312d1661a5SPawel Jakub Dawidek }; 2322d1661a5SPawel Jakub Dawidek static __inline void 2332d1661a5SPawel Jakub Dawidek raid3_metadata_encode(struct g_raid3_metadata *md, u_char *data) 2342d1661a5SPawel Jakub Dawidek { 2352d1661a5SPawel Jakub Dawidek MD5_CTX ctx; 2362d1661a5SPawel Jakub Dawidek 2372d1661a5SPawel Jakub Dawidek bcopy(md->md_magic, data, 16); 2382d1661a5SPawel Jakub Dawidek le32enc(data + 16, md->md_version); 2392d1661a5SPawel Jakub Dawidek bcopy(md->md_name, data + 20, 16); 2402d1661a5SPawel Jakub Dawidek le32enc(data + 36, md->md_id); 2412d1661a5SPawel Jakub Dawidek le16enc(data + 40, md->md_no); 2422d1661a5SPawel Jakub Dawidek le16enc(data + 42, md->md_all); 2432d1661a5SPawel Jakub Dawidek le32enc(data + 44, md->md_syncid); 2442d1661a5SPawel Jakub Dawidek le64enc(data + 48, md->md_mediasize); 2452d1661a5SPawel Jakub Dawidek le32enc(data + 56, md->md_sectorsize); 2462d1661a5SPawel Jakub Dawidek le64enc(data + 60, md->md_sync_offset); 2472d1661a5SPawel Jakub Dawidek le64enc(data + 68, md->md_mflags); 2482d1661a5SPawel Jakub Dawidek le64enc(data + 76, md->md_dflags); 2492d1661a5SPawel Jakub Dawidek bcopy(md->md_provider, data + 84, 16); 2502d1661a5SPawel Jakub Dawidek MD5Init(&ctx); 2512d1661a5SPawel Jakub Dawidek MD5Update(&ctx, data, 100); 2522d1661a5SPawel Jakub Dawidek MD5Final(md->md_hash, &ctx); 2532d1661a5SPawel Jakub Dawidek bcopy(md->md_hash, data + 100, 16); 2542d1661a5SPawel Jakub Dawidek } 2552d1661a5SPawel Jakub Dawidek static __inline int 2562d1661a5SPawel Jakub Dawidek raid3_metadata_decode(const u_char *data, struct g_raid3_metadata *md) 2572d1661a5SPawel Jakub Dawidek { 2582d1661a5SPawel Jakub Dawidek MD5_CTX ctx; 2592d1661a5SPawel Jakub Dawidek 2602d1661a5SPawel Jakub Dawidek bcopy(data, md->md_magic, 16); 2612d1661a5SPawel Jakub Dawidek md->md_version = le32dec(data + 16); 2622d1661a5SPawel Jakub Dawidek bcopy(data + 20, md->md_name, 16); 2632d1661a5SPawel Jakub Dawidek md->md_id = le32dec(data + 36); 2642d1661a5SPawel Jakub Dawidek md->md_no = le16dec(data + 40); 2652d1661a5SPawel Jakub Dawidek md->md_all = le16dec(data + 42); 2662d1661a5SPawel Jakub Dawidek md->md_syncid = le32dec(data + 44); 2672d1661a5SPawel Jakub Dawidek md->md_mediasize = le64dec(data + 48); 2682d1661a5SPawel Jakub Dawidek md->md_sectorsize = le32dec(data + 56); 2692d1661a5SPawel Jakub Dawidek md->md_sync_offset = le64dec(data + 60); 2702d1661a5SPawel Jakub Dawidek md->md_mflags = le64dec(data + 68); 2712d1661a5SPawel Jakub Dawidek md->md_dflags = le64dec(data + 76); 2722d1661a5SPawel Jakub Dawidek bcopy(data + 84, md->md_provider, 16); 2732d1661a5SPawel Jakub Dawidek bcopy(data + 100, md->md_hash, 16); 2742d1661a5SPawel Jakub Dawidek MD5Init(&ctx); 2752d1661a5SPawel Jakub Dawidek MD5Update(&ctx, data, 100); 2762d1661a5SPawel Jakub Dawidek MD5Final(md->md_hash, &ctx); 2772d1661a5SPawel Jakub Dawidek if (bcmp(md->md_hash, data + 100, 16) != 0) 2782d1661a5SPawel Jakub Dawidek return (EINVAL); 2792d1661a5SPawel Jakub Dawidek return (0); 2802d1661a5SPawel Jakub Dawidek } 2812d1661a5SPawel Jakub Dawidek 2822d1661a5SPawel Jakub Dawidek static __inline void 2832d1661a5SPawel Jakub Dawidek raid3_metadata_dump(const struct g_raid3_metadata *md) 2842d1661a5SPawel Jakub Dawidek { 2852d1661a5SPawel Jakub Dawidek static const char hex[] = "0123456789abcdef"; 2862d1661a5SPawel Jakub Dawidek char hash[16 * 2 + 1]; 2872d1661a5SPawel Jakub Dawidek u_int i; 2882d1661a5SPawel Jakub Dawidek 2892d1661a5SPawel Jakub Dawidek printf(" magic: %s\n", md->md_magic); 2902d1661a5SPawel Jakub Dawidek printf(" version: %u\n", (u_int)md->md_version); 2912d1661a5SPawel Jakub Dawidek printf(" name: %s\n", md->md_name); 2922d1661a5SPawel Jakub Dawidek printf(" id: %u\n", (u_int)md->md_id); 2932d1661a5SPawel Jakub Dawidek printf(" no: %u\n", (u_int)md->md_no); 2942d1661a5SPawel Jakub Dawidek printf(" all: %u\n", (u_int)md->md_all); 2952d1661a5SPawel Jakub Dawidek printf(" syncid: %u\n", (u_int)md->md_syncid); 2962d1661a5SPawel Jakub Dawidek printf(" mediasize: %jd\n", (intmax_t)md->md_mediasize); 2972d1661a5SPawel Jakub Dawidek printf("sectorsize: %u\n", (u_int)md->md_sectorsize); 2982d1661a5SPawel Jakub Dawidek printf("syncoffset: %jd\n", (intmax_t)md->md_sync_offset); 2992d1661a5SPawel Jakub Dawidek printf(" mflags:"); 3002d1661a5SPawel Jakub Dawidek if (md->md_mflags == 0) 3012d1661a5SPawel Jakub Dawidek printf(" NONE"); 3022d1661a5SPawel Jakub Dawidek else { 3032d1661a5SPawel Jakub Dawidek if ((md->md_mflags & G_RAID3_DEVICE_FLAG_NOAUTOSYNC) != 0) 3042d1661a5SPawel Jakub Dawidek printf(" NOAUTOSYNC"); 305f5a2f7feSPawel Jakub Dawidek if ((md->md_mflags & G_RAID3_DEVICE_FLAG_ROUND_ROBIN) != 0) 306f5a2f7feSPawel Jakub Dawidek printf(" ROUND-ROBIN"); 307dba915cfSPawel Jakub Dawidek if ((md->md_mflags & G_RAID3_DEVICE_FLAG_VERIFY) != 0) 308dba915cfSPawel Jakub Dawidek printf(" VERIFY"); 3092d1661a5SPawel Jakub Dawidek } 3102d1661a5SPawel Jakub Dawidek printf("\n"); 3112d1661a5SPawel Jakub Dawidek printf(" dflags:"); 3122d1661a5SPawel Jakub Dawidek if (md->md_dflags == 0) 3132d1661a5SPawel Jakub Dawidek printf(" NONE"); 3142d1661a5SPawel Jakub Dawidek else { 3152d1661a5SPawel Jakub Dawidek if ((md->md_dflags & G_RAID3_DISK_FLAG_DIRTY) != 0) 3162d1661a5SPawel Jakub Dawidek printf(" DIRTY"); 3172d1661a5SPawel Jakub Dawidek if ((md->md_dflags & G_RAID3_DISK_FLAG_SYNCHRONIZING) != 0) 3182d1661a5SPawel Jakub Dawidek printf(" SYNCHRONIZING"); 3192d1661a5SPawel Jakub Dawidek if ((md->md_dflags & G_RAID3_DISK_FLAG_FORCE_SYNC) != 0) 3202d1661a5SPawel Jakub Dawidek printf(" FORCE_SYNC"); 3212d1661a5SPawel Jakub Dawidek } 3222d1661a5SPawel Jakub Dawidek printf("\n"); 3232d1661a5SPawel Jakub Dawidek printf("hcprovider: %s\n", md->md_provider); 3242d1661a5SPawel Jakub Dawidek bzero(hash, sizeof(hash)); 3252d1661a5SPawel Jakub Dawidek for (i = 0; i < 16; i++) { 3262d1661a5SPawel Jakub Dawidek hash[i * 2] = hex[md->md_hash[i] >> 4]; 3272d1661a5SPawel Jakub Dawidek hash[i * 2 + 1] = hex[md->md_hash[i] & 0x0f]; 3282d1661a5SPawel Jakub Dawidek } 3292d1661a5SPawel Jakub Dawidek printf(" MD5 hash: %s\n", hash); 3302d1661a5SPawel Jakub Dawidek } 3312d1661a5SPawel Jakub Dawidek #endif /* !_G_RAID3_H_ */ 332