summaryrefslogtreecommitdiffstats
path: root/sys/geom/raid3/g_raid3.h
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2004-12-25 19:17:47 +0000
committerpjd <pjd@FreeBSD.org>2004-12-25 19:17:47 +0000
commit0bb72c3b0079d6d298270e90f40b74b0836d4dc2 (patch)
tree169e37ca71179e3cf55db841759c6cd9f5cc6b51 /sys/geom/raid3/g_raid3.h
parent9476ffbed8df3ebc72f2548f9db81306e46e27e5 (diff)
downloadFreeBSD-src-0bb72c3b0079d6d298270e90f40b74b0836d4dc2.zip
FreeBSD-src-0bb72c3b0079d6d298270e90f40b74b0836d4dc2.tar.gz
- Add genid field to the metadata which will allow to improve reliability a bit.
After this change, when component is disconnected because of an I/O error, it will not be connected and synchronized automatically, it will be logged as broken and skipped. Autosynchronization can occur, when component is disconnected (on orphan event) and connected again - there were no I/O error, so there is no need to not connected the component, but when there were writes while it wasn't connected, it will be synchronized. This fix cases, when component is disconnected because of I/O error and can be connected again and again. - Bump version number. - Implement backward compatibility mechanism. After this change when metadata in old version is detected, it is automatically upgraded to the new (current) version.
Diffstat (limited to 'sys/geom/raid3/g_raid3.h')
-rw-r--r--sys/geom/raid3/g_raid3.h90
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);
OpenPOWER on IntegriCloud