diff options
Diffstat (limited to 'sys/geom/raid3/g_raid3.h')
-rw-r--r-- | sys/geom/raid3/g_raid3.h | 90 |
1 files changed, 74 insertions, 16 deletions
diff --git a/sys/geom/raid3/g_raid3.h b/sys/geom/raid3/g_raid3.h index 1eb6e87..ffb463c 100644 --- a/sys/geom/raid3/g_raid3.h +++ b/sys/geom/raid3/g_raid3.h @@ -40,8 +40,9 @@ * 0 - Initial version number. * 1 - Added 'round-robin reading' algorithm. * 2 - Added 'verify reading' algorithm. + * 3 - Added md_genid field to metadata. */ -#define G_RAID3_VERSION 2 +#define G_RAID3_VERSION 3 #define G_RAID3_DISK_FLAG_DIRTY 0x0000000000000001ULL #define G_RAID3_DISK_FLAG_SYNCHRONIZING 0x0000000000000002ULL @@ -136,6 +137,7 @@ struct g_raid3_disk { struct g_raid3_softc *d_softc; /* Back-pointer to softc. */ int d_state; /* Disk state. */ uint64_t d_flags; /* Additional flags. */ + u_int d_genid; /* Disk's generation ID. */ struct g_raid3_disk_sync d_sync; /* Sync information. */ LIST_ENTRY(g_raid3_disk) d_next; }; @@ -160,8 +162,15 @@ struct g_raid3_event { #define G_RAID3_DEVICE_STATE_DEGRADED 1 #define G_RAID3_DEVICE_STATE_COMPLETE 2 -#define G_RAID3_BUMP_ON_FIRST_WRITE 1 -#define G_RAID3_BUMP_IMMEDIATELY 2 +/* Bump syncid on first write. */ +#define G_RAID3_BUMP_SYNCID_OFW 0x1 +/* Bump syncid immediately. */ +#define G_RAID3_BUMP_SYNCID_IMM 0x2 +#define G_RAID3_BUMP_SYNCID (G_RAID3_BUMP_SYNCID_OFW | \ + G_RAID3_BUMP_SYNCID_IMM) +/* Bump genid immediately. */ +#define G_RAID3_BUMP_GENID_IMM 0x4 +#define G_RAID3_BUMP_GENID (G_RAID3_BUMP_GENID_IMM) struct g_raid3_softc { u_int sc_state; /* Device state. */ @@ -187,8 +196,9 @@ struct g_raid3_softc { uma_zone_t sc_zone_16k; uma_zone_t sc_zone_4k; + u_int sc_genid; /* Generation ID. */ u_int sc_syncid; /* Synchronization ID. */ - int sc_bump_syncid; + int sc_bump_id; struct g_raid3_device_sync sc_sync; int sc_idle; /* DIRTY flags removed. */ @@ -219,6 +229,7 @@ struct g_raid3_metadata { uint32_t md_id; /* Device unique ID. */ uint16_t md_no; /* Component number. */ uint16_t md_all; /* Number of disks in device. */ + uint32_t md_genid; /* Generation ID. */ uint32_t md_syncid; /* Synchronization ID. */ uint64_t md_mediasize; /* Size of whole device. */ uint32_t md_sectorsize; /* Sector size. */ @@ -239,25 +250,24 @@ raid3_metadata_encode(struct g_raid3_metadata *md, u_char *data) le32enc(data + 36, md->md_id); le16enc(data + 40, md->md_no); le16enc(data + 42, md->md_all); - le32enc(data + 44, md->md_syncid); - le64enc(data + 48, md->md_mediasize); - le32enc(data + 56, md->md_sectorsize); - le64enc(data + 60, md->md_sync_offset); - le64enc(data + 68, md->md_mflags); - le64enc(data + 76, md->md_dflags); - bcopy(md->md_provider, data + 84, 16); + le32enc(data + 44, md->md_genid); + le32enc(data + 48, md->md_syncid); + le64enc(data + 52, md->md_mediasize); + le32enc(data + 60, md->md_sectorsize); + le64enc(data + 64, md->md_sync_offset); + le64enc(data + 72, md->md_mflags); + le64enc(data + 80, md->md_dflags); + bcopy(md->md_provider, data + 88, 16); MD5Init(&ctx); - MD5Update(&ctx, data, 100); + MD5Update(&ctx, data, 104); MD5Final(md->md_hash, &ctx); - bcopy(md->md_hash, data + 100, 16); + bcopy(md->md_hash, data + 104, 16); } static __inline int -raid3_metadata_decode(const u_char *data, struct g_raid3_metadata *md) +raid3_metadata_decode_v0v1v2(const u_char *data, struct g_raid3_metadata *md) { MD5_CTX ctx; - bcopy(data, md->md_magic, 16); - md->md_version = le32dec(data + 16); bcopy(data + 20, md->md_name, 16); md->md_id = le32dec(data + 36); md->md_no = le16dec(data + 40); @@ -277,6 +287,53 @@ raid3_metadata_decode(const u_char *data, struct g_raid3_metadata *md) return (EINVAL); return (0); } +static __inline int +raid3_metadata_decode_v3(const u_char *data, struct g_raid3_metadata *md) +{ + MD5_CTX ctx; + + bcopy(data + 20, md->md_name, 16); + md->md_id = le32dec(data + 36); + md->md_no = le16dec(data + 40); + md->md_all = le16dec(data + 42); + md->md_genid = le32dec(data + 44); + md->md_syncid = le32dec(data + 48); + md->md_mediasize = le64dec(data + 52); + md->md_sectorsize = le32dec(data + 60); + md->md_sync_offset = le64dec(data + 64); + md->md_mflags = le64dec(data + 72); + md->md_dflags = le64dec(data + 80); + bcopy(data + 88, md->md_provider, 16); + bcopy(data + 104, md->md_hash, 16); + MD5Init(&ctx); + MD5Update(&ctx, data, 104); + MD5Final(md->md_hash, &ctx); + if (bcmp(md->md_hash, data + 104, 16) != 0) + return (EINVAL); + return (0); +} +static __inline int +raid3_metadata_decode(const u_char *data, struct g_raid3_metadata *md) +{ + int error; + + bcopy(data, md->md_magic, 16); + md->md_version = le32dec(data + 16); + switch (md->md_version) { + case 0: + case 1: + case 2: + error = raid3_metadata_decode_v0v1v2(data, md); + break; + case 3: + error = raid3_metadata_decode_v3(data, md); + break; + default: + error = EINVAL; + break; + } + return (error); +} static __inline void raid3_metadata_dump(const struct g_raid3_metadata *md) @@ -291,6 +348,7 @@ raid3_metadata_dump(const struct g_raid3_metadata *md) printf(" id: %u\n", (u_int)md->md_id); printf(" no: %u\n", (u_int)md->md_no); printf(" all: %u\n", (u_int)md->md_all); + printf(" genid: %u\n", (u_int)md->md_genid); printf(" syncid: %u\n", (u_int)md->md_syncid); printf(" mediasize: %jd\n", (intmax_t)md->md_mediasize); printf("sectorsize: %u\n", (u_int)md->md_sectorsize); |