Deleted Added
full compact
g_raid3.h (133808) g_raid3.h (134124)
1/*-
2 * Copyright (c) 2004 Pawel Jakub Dawidek <pjd@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*-
2 * Copyright (c) 2004 Pawel Jakub Dawidek <pjd@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/geom/raid3/g_raid3.h 133808 2004-08-16 06:23:14Z pjd $
26 * $FreeBSD: head/sys/geom/raid3/g_raid3.h 134124 2004-08-21 18:11:46Z pjd $
27 */
28
29#ifndef _G_RAID3_H_
30#define _G_RAID3_H_
31
32#include <sys/endian.h>
33#include <sys/md5.h>
34
35#define G_RAID3_CLASS_NAME "RAID3"
36
37#define G_RAID3_MAGIC "GEOM::RAID3"
27 */
28
29#ifndef _G_RAID3_H_
30#define _G_RAID3_H_
31
32#include <sys/endian.h>
33#include <sys/md5.h>
34
35#define G_RAID3_CLASS_NAME "RAID3"
36
37#define G_RAID3_MAGIC "GEOM::RAID3"
38#define G_RAID3_VERSION 0
38#define G_RAID3_VERSION 1
39
40#define G_RAID3_DISK_FLAG_DIRTY 0x0000000000000001ULL
41#define G_RAID3_DISK_FLAG_SYNCHRONIZING 0x0000000000000002ULL
42#define G_RAID3_DISK_FLAG_FORCE_SYNC 0x0000000000000004ULL
43#define G_RAID3_DISK_FLAG_HARDCODED 0x0000000000000008ULL
44#define G_RAID3_DISK_FLAG_MASK (G_RAID3_DISK_FLAG_DIRTY | \
45 G_RAID3_DISK_FLAG_SYNCHRONIZING | \
46 G_RAID3_DISK_FLAG_FORCE_SYNC)
47
48#define G_RAID3_DEVICE_FLAG_NOAUTOSYNC 0x0000000000000001ULL
39
40#define G_RAID3_DISK_FLAG_DIRTY 0x0000000000000001ULL
41#define G_RAID3_DISK_FLAG_SYNCHRONIZING 0x0000000000000002ULL
42#define G_RAID3_DISK_FLAG_FORCE_SYNC 0x0000000000000004ULL
43#define G_RAID3_DISK_FLAG_HARDCODED 0x0000000000000008ULL
44#define G_RAID3_DISK_FLAG_MASK (G_RAID3_DISK_FLAG_DIRTY | \
45 G_RAID3_DISK_FLAG_SYNCHRONIZING | \
46 G_RAID3_DISK_FLAG_FORCE_SYNC)
47
48#define G_RAID3_DEVICE_FLAG_NOAUTOSYNC 0x0000000000000001ULL
49#define G_RAID3_DEVICE_FLAG_MASK (G_RAID3_DEVICE_FLAG_NOAUTOSYNC)
49#define G_RAID3_DEVICE_FLAG_ROUND_ROBIN 0x0000000000000002ULL
50#define G_RAID3_DEVICE_FLAG_MASK (G_RAID3_DEVICE_FLAG_NOAUTOSYNC | \
51 G_RAID3_DEVICE_FLAG_ROUND_ROBIN)
50
51#ifdef _KERNEL
52extern u_int g_raid3_debug;
53
54#define G_RAID3_DEBUG(lvl, ...) do { \
55 if (g_raid3_debug >= (lvl)) { \
56 printf("GEOM_RAID3"); \
57 if (g_raid3_debug > 0) \
58 printf("[%u]", lvl); \
59 printf(": "); \
60 printf(__VA_ARGS__); \
61 printf("\n"); \
62 } \
63} while (0)
64#define G_RAID3_LOGREQ(lvl, bp, ...) do { \
65 if (g_raid3_debug >= (lvl)) { \
66 printf("GEOM_RAID3"); \
67 if (g_raid3_debug > 0) \
68 printf("[%u]", lvl); \
69 printf(": "); \
70 printf(__VA_ARGS__); \
71 printf(" "); \
72 g_print_bio(bp); \
73 printf("\n"); \
74 } \
75} while (0)
76
77#define G_RAID3_MAX_IO_SIZE (DFLTPHYS * 2)
78
79#define G_RAID3_BIO_CFLAG_REGULAR 0x01
80#define G_RAID3_BIO_CFLAG_SYNC 0x02
81#define G_RAID3_BIO_CFLAG_PARITY 0x04
82#define G_RAID3_BIO_CFLAG_NODISK 0x08
83#define G_RAID3_BIO_CFLAG_REGSYNC 0x10
84
85#define G_RAID3_BIO_PFLAG_DEGRADED 0x01
86#define G_RAID3_BIO_PFLAG_NOPARITY 0x02
87
88/*
89 * Informations needed for synchronization.
90 */
91struct g_raid3_disk_sync {
92 struct g_consumer *ds_consumer; /* Consumer connected to our device. */
93 off_t ds_offset; /* Offset of next request to send. */
94 off_t ds_offset_done; /* Offset of already synchronized
95 region. */
96 u_int ds_syncid; /* Disk's synchronization ID. */
97 u_char *ds_data;
98};
99
100/*
101 * Informations needed for synchronization.
102 */
103struct g_raid3_device_sync {
104 struct g_geom *ds_geom; /* Synchronization geom. */
105};
106
107#define G_RAID3_DISK_STATE_NODISK 0
108#define G_RAID3_DISK_STATE_NONE 1
109#define G_RAID3_DISK_STATE_NEW 2
110#define G_RAID3_DISK_STATE_ACTIVE 3
111#define G_RAID3_DISK_STATE_STALE 4
112#define G_RAID3_DISK_STATE_SYNCHRONIZING 5
113#define G_RAID3_DISK_STATE_DISCONNECTED 6
114#define G_RAID3_DISK_STATE_DESTROY 7
115struct g_raid3_disk {
116 u_int d_no; /* Disk number. */
117 struct g_consumer *d_consumer; /* Consumer. */
118 struct g_raid3_softc *d_softc; /* Back-pointer to softc. */
119 int d_state; /* Disk state. */
120 uint64_t d_flags; /* Additional flags. */
121 struct g_raid3_disk_sync d_sync; /* Sync information. */
122 LIST_ENTRY(g_raid3_disk) d_next;
123};
124#define d_name d_consumer->provider->name
125
126#define G_RAID3_EVENT_DONTWAIT 0x1
127#define G_RAID3_EVENT_WAIT 0x2
128#define G_RAID3_EVENT_DEVICE 0x4
129#define G_RAID3_EVENT_DONE 0x8
130struct g_raid3_event {
131 struct g_raid3_disk *e_disk;
132 int e_state;
133 int e_flags;
134 int e_error;
135 TAILQ_ENTRY(g_raid3_event) e_next;
136};
137
138#define G_RAID3_DEVICE_FLAG_DESTROY 0x0100000000000000ULL
139#define G_RAID3_DEVICE_FLAG_WAIT 0x0200000000000000ULL
140
141#define G_RAID3_DEVICE_STATE_STARTING 0
142#define G_RAID3_DEVICE_STATE_DEGRADED 1
143#define G_RAID3_DEVICE_STATE_COMPLETE 2
144
145#define G_RAID3_BUMP_ON_FIRST_WRITE 1
146#define G_RAID3_BUMP_IMMEDIATELY 2
147
148struct g_raid3_softc {
149 u_int sc_state; /* Device state. */
150 uint64_t sc_mediasize; /* Device size. */
151 uint32_t sc_sectorsize; /* Sector size. */
152 uint64_t sc_flags; /* Additional flags. */
153
154 struct g_geom *sc_geom;
155 struct g_provider *sc_provider;
156
157 uint32_t sc_id; /* Device unique ID. */
158
159 struct bio_queue_head sc_queue;
160 struct mtx sc_queue_mtx;
161 struct proc *sc_worker;
162
163 struct g_raid3_disk *sc_disks;
164 u_int sc_ndisks; /* Number of disks. */
52
53#ifdef _KERNEL
54extern u_int g_raid3_debug;
55
56#define G_RAID3_DEBUG(lvl, ...) do { \
57 if (g_raid3_debug >= (lvl)) { \
58 printf("GEOM_RAID3"); \
59 if (g_raid3_debug > 0) \
60 printf("[%u]", lvl); \
61 printf(": "); \
62 printf(__VA_ARGS__); \
63 printf("\n"); \
64 } \
65} while (0)
66#define G_RAID3_LOGREQ(lvl, bp, ...) do { \
67 if (g_raid3_debug >= (lvl)) { \
68 printf("GEOM_RAID3"); \
69 if (g_raid3_debug > 0) \
70 printf("[%u]", lvl); \
71 printf(": "); \
72 printf(__VA_ARGS__); \
73 printf(" "); \
74 g_print_bio(bp); \
75 printf("\n"); \
76 } \
77} while (0)
78
79#define G_RAID3_MAX_IO_SIZE (DFLTPHYS * 2)
80
81#define G_RAID3_BIO_CFLAG_REGULAR 0x01
82#define G_RAID3_BIO_CFLAG_SYNC 0x02
83#define G_RAID3_BIO_CFLAG_PARITY 0x04
84#define G_RAID3_BIO_CFLAG_NODISK 0x08
85#define G_RAID3_BIO_CFLAG_REGSYNC 0x10
86
87#define G_RAID3_BIO_PFLAG_DEGRADED 0x01
88#define G_RAID3_BIO_PFLAG_NOPARITY 0x02
89
90/*
91 * Informations needed for synchronization.
92 */
93struct g_raid3_disk_sync {
94 struct g_consumer *ds_consumer; /* Consumer connected to our device. */
95 off_t ds_offset; /* Offset of next request to send. */
96 off_t ds_offset_done; /* Offset of already synchronized
97 region. */
98 u_int ds_syncid; /* Disk's synchronization ID. */
99 u_char *ds_data;
100};
101
102/*
103 * Informations needed for synchronization.
104 */
105struct g_raid3_device_sync {
106 struct g_geom *ds_geom; /* Synchronization geom. */
107};
108
109#define G_RAID3_DISK_STATE_NODISK 0
110#define G_RAID3_DISK_STATE_NONE 1
111#define G_RAID3_DISK_STATE_NEW 2
112#define G_RAID3_DISK_STATE_ACTIVE 3
113#define G_RAID3_DISK_STATE_STALE 4
114#define G_RAID3_DISK_STATE_SYNCHRONIZING 5
115#define G_RAID3_DISK_STATE_DISCONNECTED 6
116#define G_RAID3_DISK_STATE_DESTROY 7
117struct g_raid3_disk {
118 u_int d_no; /* Disk number. */
119 struct g_consumer *d_consumer; /* Consumer. */
120 struct g_raid3_softc *d_softc; /* Back-pointer to softc. */
121 int d_state; /* Disk state. */
122 uint64_t d_flags; /* Additional flags. */
123 struct g_raid3_disk_sync d_sync; /* Sync information. */
124 LIST_ENTRY(g_raid3_disk) d_next;
125};
126#define d_name d_consumer->provider->name
127
128#define G_RAID3_EVENT_DONTWAIT 0x1
129#define G_RAID3_EVENT_WAIT 0x2
130#define G_RAID3_EVENT_DEVICE 0x4
131#define G_RAID3_EVENT_DONE 0x8
132struct g_raid3_event {
133 struct g_raid3_disk *e_disk;
134 int e_state;
135 int e_flags;
136 int e_error;
137 TAILQ_ENTRY(g_raid3_event) e_next;
138};
139
140#define G_RAID3_DEVICE_FLAG_DESTROY 0x0100000000000000ULL
141#define G_RAID3_DEVICE_FLAG_WAIT 0x0200000000000000ULL
142
143#define G_RAID3_DEVICE_STATE_STARTING 0
144#define G_RAID3_DEVICE_STATE_DEGRADED 1
145#define G_RAID3_DEVICE_STATE_COMPLETE 2
146
147#define G_RAID3_BUMP_ON_FIRST_WRITE 1
148#define G_RAID3_BUMP_IMMEDIATELY 2
149
150struct g_raid3_softc {
151 u_int sc_state; /* Device state. */
152 uint64_t sc_mediasize; /* Device size. */
153 uint32_t sc_sectorsize; /* Sector size. */
154 uint64_t sc_flags; /* Additional flags. */
155
156 struct g_geom *sc_geom;
157 struct g_provider *sc_provider;
158
159 uint32_t sc_id; /* Device unique ID. */
160
161 struct bio_queue_head sc_queue;
162 struct mtx sc_queue_mtx;
163 struct proc *sc_worker;
164
165 struct g_raid3_disk *sc_disks;
166 u_int sc_ndisks; /* Number of disks. */
167 u_int sc_round_robin;
165 struct g_raid3_disk *sc_syncdisk;
166
167 uma_zone_t sc_zone_64k;
168 uma_zone_t sc_zone_16k;
169 uma_zone_t sc_zone_4k;
170
171 u_int sc_syncid; /* Synchronization ID. */
172 int sc_bump_syncid;
173 struct g_raid3_device_sync sc_sync;
174
175 TAILQ_HEAD(, g_raid3_event) sc_events;
176 struct mtx sc_events_mtx;
177
178 struct callout sc_callout;
179};
180#define sc_name sc_geom->name
181
182const char *g_raid3_get_diskname(struct g_raid3_disk *disk);
183u_int g_raid3_ndisks(struct g_raid3_softc *sc, int state);
184int g_raid3_destroy(struct g_raid3_softc *sc, boolean_t force);
185int g_raid3_event_send(void *arg, int state, int flags);
186struct g_raid3_metadata;
187void g_raid3_fill_metadata(struct g_raid3_disk *disk,
188 struct g_raid3_metadata *md);
189int g_raid3_clear_metadata(struct g_raid3_disk *disk);
190void g_raid3_update_metadata(struct g_raid3_disk *disk);
191
192g_ctl_req_t g_raid3_config;
193#endif /* _KERNEL */
194
195struct g_raid3_metadata {
196 char md_magic[16]; /* Magic value. */
197 uint32_t md_version; /* Version number. */
198 char md_name[16]; /* Device name. */
199 uint32_t md_id; /* Device unique ID. */
200 uint16_t md_no; /* Component number. */
201 uint16_t md_all; /* Number of disks in device. */
202 uint32_t md_syncid; /* Synchronization ID. */
203 uint64_t md_mediasize; /* Size of whole device. */
204 uint32_t md_sectorsize; /* Sector size. */
205 uint64_t md_sync_offset; /* Synchronized offset. */
206 uint64_t md_mflags; /* Additional device flags. */
207 uint64_t md_dflags; /* Additional disk flags. */
208 char md_provider[16]; /* Hardcoded provider. */
209 u_char md_hash[16]; /* MD5 hash. */
210};
211static __inline void
212raid3_metadata_encode(struct g_raid3_metadata *md, u_char *data)
213{
214 MD5_CTX ctx;
215
216 bcopy(md->md_magic, data, 16);
217 le32enc(data + 16, md->md_version);
218 bcopy(md->md_name, data + 20, 16);
219 le32enc(data + 36, md->md_id);
220 le16enc(data + 40, md->md_no);
221 le16enc(data + 42, md->md_all);
222 le32enc(data + 44, md->md_syncid);
223 le64enc(data + 48, md->md_mediasize);
224 le32enc(data + 56, md->md_sectorsize);
225 le64enc(data + 60, md->md_sync_offset);
226 le64enc(data + 68, md->md_mflags);
227 le64enc(data + 76, md->md_dflags);
228 bcopy(md->md_provider, data + 84, 16);
229 MD5Init(&ctx);
230 MD5Update(&ctx, data, 100);
231 MD5Final(md->md_hash, &ctx);
232 bcopy(md->md_hash, data + 100, 16);
233}
234static __inline int
235raid3_metadata_decode(const u_char *data, struct g_raid3_metadata *md)
236{
237 MD5_CTX ctx;
238
239 bcopy(data, md->md_magic, 16);
240 md->md_version = le32dec(data + 16);
241 bcopy(data + 20, md->md_name, 16);
242 md->md_id = le32dec(data + 36);
243 md->md_no = le16dec(data + 40);
244 md->md_all = le16dec(data + 42);
245 md->md_syncid = le32dec(data + 44);
246 md->md_mediasize = le64dec(data + 48);
247 md->md_sectorsize = le32dec(data + 56);
248 md->md_sync_offset = le64dec(data + 60);
249 md->md_mflags = le64dec(data + 68);
250 md->md_dflags = le64dec(data + 76);
251 bcopy(data + 84, md->md_provider, 16);
252 bcopy(data + 100, md->md_hash, 16);
253 MD5Init(&ctx);
254 MD5Update(&ctx, data, 100);
255 MD5Final(md->md_hash, &ctx);
256 if (bcmp(md->md_hash, data + 100, 16) != 0)
257 return (EINVAL);
258 return (0);
259}
260
261static __inline void
262raid3_metadata_dump(const struct g_raid3_metadata *md)
263{
264 static const char hex[] = "0123456789abcdef";
265 char hash[16 * 2 + 1];
266 u_int i;
267
268 printf(" magic: %s\n", md->md_magic);
269 printf(" version: %u\n", (u_int)md->md_version);
270 printf(" name: %s\n", md->md_name);
271 printf(" id: %u\n", (u_int)md->md_id);
272 printf(" no: %u\n", (u_int)md->md_no);
273 printf(" all: %u\n", (u_int)md->md_all);
274 printf(" syncid: %u\n", (u_int)md->md_syncid);
275 printf(" mediasize: %jd\n", (intmax_t)md->md_mediasize);
276 printf("sectorsize: %u\n", (u_int)md->md_sectorsize);
277 printf("syncoffset: %jd\n", (intmax_t)md->md_sync_offset);
278 printf(" mflags:");
279 if (md->md_mflags == 0)
280 printf(" NONE");
281 else {
282 if ((md->md_mflags & G_RAID3_DEVICE_FLAG_NOAUTOSYNC) != 0)
283 printf(" NOAUTOSYNC");
168 struct g_raid3_disk *sc_syncdisk;
169
170 uma_zone_t sc_zone_64k;
171 uma_zone_t sc_zone_16k;
172 uma_zone_t sc_zone_4k;
173
174 u_int sc_syncid; /* Synchronization ID. */
175 int sc_bump_syncid;
176 struct g_raid3_device_sync sc_sync;
177
178 TAILQ_HEAD(, g_raid3_event) sc_events;
179 struct mtx sc_events_mtx;
180
181 struct callout sc_callout;
182};
183#define sc_name sc_geom->name
184
185const char *g_raid3_get_diskname(struct g_raid3_disk *disk);
186u_int g_raid3_ndisks(struct g_raid3_softc *sc, int state);
187int g_raid3_destroy(struct g_raid3_softc *sc, boolean_t force);
188int g_raid3_event_send(void *arg, int state, int flags);
189struct g_raid3_metadata;
190void g_raid3_fill_metadata(struct g_raid3_disk *disk,
191 struct g_raid3_metadata *md);
192int g_raid3_clear_metadata(struct g_raid3_disk *disk);
193void g_raid3_update_metadata(struct g_raid3_disk *disk);
194
195g_ctl_req_t g_raid3_config;
196#endif /* _KERNEL */
197
198struct g_raid3_metadata {
199 char md_magic[16]; /* Magic value. */
200 uint32_t md_version; /* Version number. */
201 char md_name[16]; /* Device name. */
202 uint32_t md_id; /* Device unique ID. */
203 uint16_t md_no; /* Component number. */
204 uint16_t md_all; /* Number of disks in device. */
205 uint32_t md_syncid; /* Synchronization ID. */
206 uint64_t md_mediasize; /* Size of whole device. */
207 uint32_t md_sectorsize; /* Sector size. */
208 uint64_t md_sync_offset; /* Synchronized offset. */
209 uint64_t md_mflags; /* Additional device flags. */
210 uint64_t md_dflags; /* Additional disk flags. */
211 char md_provider[16]; /* Hardcoded provider. */
212 u_char md_hash[16]; /* MD5 hash. */
213};
214static __inline void
215raid3_metadata_encode(struct g_raid3_metadata *md, u_char *data)
216{
217 MD5_CTX ctx;
218
219 bcopy(md->md_magic, data, 16);
220 le32enc(data + 16, md->md_version);
221 bcopy(md->md_name, data + 20, 16);
222 le32enc(data + 36, md->md_id);
223 le16enc(data + 40, md->md_no);
224 le16enc(data + 42, md->md_all);
225 le32enc(data + 44, md->md_syncid);
226 le64enc(data + 48, md->md_mediasize);
227 le32enc(data + 56, md->md_sectorsize);
228 le64enc(data + 60, md->md_sync_offset);
229 le64enc(data + 68, md->md_mflags);
230 le64enc(data + 76, md->md_dflags);
231 bcopy(md->md_provider, data + 84, 16);
232 MD5Init(&ctx);
233 MD5Update(&ctx, data, 100);
234 MD5Final(md->md_hash, &ctx);
235 bcopy(md->md_hash, data + 100, 16);
236}
237static __inline int
238raid3_metadata_decode(const u_char *data, struct g_raid3_metadata *md)
239{
240 MD5_CTX ctx;
241
242 bcopy(data, md->md_magic, 16);
243 md->md_version = le32dec(data + 16);
244 bcopy(data + 20, md->md_name, 16);
245 md->md_id = le32dec(data + 36);
246 md->md_no = le16dec(data + 40);
247 md->md_all = le16dec(data + 42);
248 md->md_syncid = le32dec(data + 44);
249 md->md_mediasize = le64dec(data + 48);
250 md->md_sectorsize = le32dec(data + 56);
251 md->md_sync_offset = le64dec(data + 60);
252 md->md_mflags = le64dec(data + 68);
253 md->md_dflags = le64dec(data + 76);
254 bcopy(data + 84, md->md_provider, 16);
255 bcopy(data + 100, md->md_hash, 16);
256 MD5Init(&ctx);
257 MD5Update(&ctx, data, 100);
258 MD5Final(md->md_hash, &ctx);
259 if (bcmp(md->md_hash, data + 100, 16) != 0)
260 return (EINVAL);
261 return (0);
262}
263
264static __inline void
265raid3_metadata_dump(const struct g_raid3_metadata *md)
266{
267 static const char hex[] = "0123456789abcdef";
268 char hash[16 * 2 + 1];
269 u_int i;
270
271 printf(" magic: %s\n", md->md_magic);
272 printf(" version: %u\n", (u_int)md->md_version);
273 printf(" name: %s\n", md->md_name);
274 printf(" id: %u\n", (u_int)md->md_id);
275 printf(" no: %u\n", (u_int)md->md_no);
276 printf(" all: %u\n", (u_int)md->md_all);
277 printf(" syncid: %u\n", (u_int)md->md_syncid);
278 printf(" mediasize: %jd\n", (intmax_t)md->md_mediasize);
279 printf("sectorsize: %u\n", (u_int)md->md_sectorsize);
280 printf("syncoffset: %jd\n", (intmax_t)md->md_sync_offset);
281 printf(" mflags:");
282 if (md->md_mflags == 0)
283 printf(" NONE");
284 else {
285 if ((md->md_mflags & G_RAID3_DEVICE_FLAG_NOAUTOSYNC) != 0)
286 printf(" NOAUTOSYNC");
287 if ((md->md_mflags & G_RAID3_DEVICE_FLAG_ROUND_ROBIN) != 0)
288 printf(" ROUND-ROBIN");
284 }
285 printf("\n");
286 printf(" dflags:");
287 if (md->md_dflags == 0)
288 printf(" NONE");
289 else {
290 if ((md->md_dflags & G_RAID3_DISK_FLAG_DIRTY) != 0)
291 printf(" DIRTY");
292 if ((md->md_dflags & G_RAID3_DISK_FLAG_SYNCHRONIZING) != 0)
293 printf(" SYNCHRONIZING");
294 if ((md->md_dflags & G_RAID3_DISK_FLAG_FORCE_SYNC) != 0)
295 printf(" FORCE_SYNC");
296 }
297 printf("\n");
298 printf("hcprovider: %s\n", md->md_provider);
299 bzero(hash, sizeof(hash));
300 for (i = 0; i < 16; i++) {
301 hash[i * 2] = hex[md->md_hash[i] >> 4];
302 hash[i * 2 + 1] = hex[md->md_hash[i] & 0x0f];
303 }
304 printf(" MD5 hash: %s\n", hash);
305}
306#endif /* !_G_RAID3_H_ */
289 }
290 printf("\n");
291 printf(" dflags:");
292 if (md->md_dflags == 0)
293 printf(" NONE");
294 else {
295 if ((md->md_dflags & G_RAID3_DISK_FLAG_DIRTY) != 0)
296 printf(" DIRTY");
297 if ((md->md_dflags & G_RAID3_DISK_FLAG_SYNCHRONIZING) != 0)
298 printf(" SYNCHRONIZING");
299 if ((md->md_dflags & G_RAID3_DISK_FLAG_FORCE_SYNC) != 0)
300 printf(" FORCE_SYNC");
301 }
302 printf("\n");
303 printf("hcprovider: %s\n", md->md_provider);
304 bzero(hash, sizeof(hash));
305 for (i = 0; i < 16; i++) {
306 hash[i * 2] = hex[md->md_hash[i] >> 4];
307 hash[i * 2 + 1] = hex[md->md_hash[i] & 0x0f];
308 }
309 printf(" MD5 hash: %s\n", hash);
310}
311#endif /* !_G_RAID3_H_ */