1 /*-
2 * SPDX-License-Identifier: BSD-4-Clause
3 *
4 * Copyright (c) 2004, 2007 Lukas Ertl
5 * Copyright (c) 1997, 1998, 1999
6 * Nan Yang Computer Services Limited. All rights reserved.
7 *
8 * Parts copyright (c) 1997, 1998 Cybernet Corporation, NetMAX project.
9 * Parts written by Greg Lehey.
10 *
11 * This software is distributed under the so-called ``Berkeley
12 * License'': *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 * 3. All advertising materials mentioning features or use of this software
22 * must display the following acknowledgement:
23 * This product includes software developed by Nan Yang Computer
24 * Services Limited.
25 * 4. Neither the name of the Company nor the names of its contributors
26 * may be used to endorse or promote products derived from this software
27 * without specific prior written permission.
28 *
29 * This software is provided ``as is'', and any express or implied
30 * warranties, including, but not limited to, the implied warranties of
31 * merchantability and fitness for a particular purpose are disclaimed.
32 * In no event shall the company or contributors be liable for any
33 * direct, indirect, incidental, special, exemplary, or consequential
34 * damages (including, but not limited to, procurement of substitute
35 * goods or services; loss of use, data, or profits; or business
36 * interruption) however caused and on any theory of liability, whether
37 * in contract, strict liability, or tort (including negligence or
38 * otherwise) arising in any way out of the use of this software, even if
39 * advised of the possibility of such damage.
40 *
41 * $FreeBSD$
42 */
43
44 #ifndef _GEOM_VINUM_VAR_H_
45 #define _GEOM_VINUM_VAR_H_
46
47 /*
48 * Slice header
49 *
50 * Vinum drives start with this structure:
51 *
52 *\ Sector
53 * |--------------------------------------|
54 * | PDP-11 memorial boot block | 0
55 * |--------------------------------------|
56 * | Disk label, maybe | 1
57 * |--------------------------------------|
58 * | Slice definition (vinum_hdr) | 8
59 * |--------------------------------------|
60 * | |
61 * | Configuration info, first copy | 9
62 * | |
63 * |--------------------------------------|
64 * | |
65 * | Configuration info, second copy | 9 + size of config
66 * | |
67 * |--------------------------------------|
68 */
69
70 /* Sizes and offsets of our information. */
71 #define GV_HDR_OFFSET 4096 /* Offset of vinum header. */
72 #define GV_HDR_LEN 512 /* Size of vinum header. */
73 #define GV_CFG_OFFSET 4608 /* Offset of first config copy. */
74 #define GV_CFG_LEN 65536 /* Size of config copy. */
75
76 /* This is where the actual data starts. */
77 #define GV_DATA_START (GV_CFG_LEN * 2 + GV_CFG_OFFSET)
78 /* #define GV_DATA_START (GV_CFG_LEN * 2 + GV_HDR_LEN) */
79
80 #define GV_MAXDRIVENAME 32 /* Maximum length of a device name. */
81 #define GV_MAXSDNAME 64 /* Maximum length of a subdisk name. */
82 #define GV_MAXPLEXNAME 64 /* Maximum length of a plex name. */
83 #define GV_MAXVOLNAME 64 /* Maximum length of a volume name. */
84
85 /* Command line flags. */
86 #define GV_FLAG_R 0x01
87 #define GV_FLAG_S 0x02
88 #define GV_FLAG_V 0x04
89 #define GV_FLAG_VV 0x08
90 #define GV_FLAG_F 0x10
91
92 /* Object types. */
93 #define GV_TYPE_VOL 1
94 #define GV_TYPE_PLEX 2
95 #define GV_TYPE_SD 3
96 #define GV_TYPE_DRIVE 4
97
98 /* State changing flags. */
99 #define GV_SETSTATE_FORCE 0x1
100 #define GV_SETSTATE_CONFIG 0x2
101
102 /* Subdisk state bitmaps for plexes. */
103 #define GV_SD_DOWNSTATE 0x01 /* Subdisk is down. */
104 #define GV_SD_STALESTATE 0x02 /* Subdisk is stale. */
105 #define GV_SD_INITSTATE 0x04 /* Subdisk is initializing. */
106 #define GV_SD_UPSTATE 0x08 /* Subdisk is up. */
107
108 /* Synchronization/initialization request sizes. */
109 #define GV_MIN_SYNCSIZE 512
110 #define GV_MAX_SYNCSIZE maxphys
111 #define GV_DFLT_SYNCSIZE 65536
112
113 /* Flags for BIOs, as they are processed within vinum. */
114 #define GV_BIO_GROW 0x01
115 #define GV_BIO_MALLOC 0x02
116 #define GV_BIO_ONHOLD 0x04
117 #define GV_BIO_SYNCREQ 0x08
118 #define GV_BIO_INIT 0x10
119 #define GV_BIO_REBUILD 0x20
120 #define GV_BIO_CHECK 0x40
121 #define GV_BIO_PARITY 0x80
122 #define GV_BIO_INTERNAL \
123 (GV_BIO_SYNCREQ | GV_BIO_INIT | GV_BIO_REBUILD | GV_BIO_CHECK | GV_BIO_GROW)
124
125 /* Error codes to be used within gvinum. */
126 #define GV_ERR_SETSTATE (-1) /* Error setting state. */
127 #define GV_ERR_BADSIZE (-2) /* Object has wrong size. */
128 #define GV_ERR_INVTYPE (-3) /* Invalid object type. */
129 #define GV_ERR_CREATE (-4) /* Error creating gvinum object. */
130 #define GV_ERR_ISBUSY (-5) /* Object is busy. */
131 #define GV_ERR_ISATTACHED (-6) /* Object is attached to another. */
132 #define GV_ERR_INVFLAG (-7) /* Invalid flag passed. */
133 #define GV_ERR_INVSTATE (-8) /* Invalid state. */
134 #define GV_ERR_NOTFOUND (-9) /* Object not found. */
135 #define GV_ERR_NAMETAKEN (-10) /* Object name is taken. */
136 #define GV_ERR_NOSPACE (-11) /* No space left on drive/subdisk. */
137 #define GV_ERR_BADOFFSET (-12) /* Invalid offset specified. */
138 #define GV_ERR_INVNAME (-13) /* Invalid object name. */
139 #define GV_ERR_PLEXORG (-14) /* Invalid plex organization. */
140
141 /*
142 * hostname is 256 bytes long, but we don't need to shlep multiple copies in
143 * vinum. We use the host name just to identify this system, and 32 bytes
144 * should be ample for that purpose.
145 */
146
147 #define GV_HOSTNAME_LEN 32
148 struct gv_label {
149 char sysname[GV_HOSTNAME_LEN]; /* System name at creation time. */
150 char name[GV_MAXDRIVENAME]; /* Our name of the drive. */
151 struct timeval date_of_birth; /* The time it was created ... */
152 struct timeval last_update; /* ... and the time of last update. */
153 off_t drive_size; /* Total size incl. headers. */
154 };
155
156 /* The 'header' of each valid vinum drive. */
157 struct gv_hdr {
158 uint64_t magic;
159 #define GV_OLD_MAGIC 0x494E2056494E4F00LL
160 #define GV_OLD_NOMAGIC 0x4E4F2056494E4F00LL
161 #define GV_MAGIC 0x56494E554D2D3100LL
162 #define GV_NOMAGIC 0x56494E554D2D2D00LL
163
164 uint64_t config_length;
165 struct gv_label label;
166 };
167
168 /* A single freelist entry of a drive. */
169 struct gv_freelist {
170 off_t size; /* Size of this free slot. */
171 off_t offset; /* Offset on the drive. */
172 LIST_ENTRY(gv_freelist) freelist;
173 };
174
175 /*
176 * Since we share structures between userland and kernel, we need this helper
177 * struct instead of struct bio_queue_head and friends. Maybe I find a proper
178 * solution some day.
179 */
180 struct gv_bioq {
181 struct bio *bp;
182 TAILQ_ENTRY(gv_bioq) queue;
183 };
184
185 #define GV_EVENT_DRIVE_TASTED 1
186 #define GV_EVENT_DRIVE_LOST 2
187 #define GV_EVENT_THREAD_EXIT 3
188 #define GV_EVENT_CREATE_DRIVE 4
189 #define GV_EVENT_CREATE_VOLUME 5
190 #define GV_EVENT_CREATE_PLEX 6
191 #define GV_EVENT_CREATE_SD 7
192 #define GV_EVENT_SAVE_CONFIG 8
193 #define GV_EVENT_RM_VOLUME 9
194 #define GV_EVENT_RM_PLEX 10
195 #define GV_EVENT_RM_SD 11
196 #define GV_EVENT_RM_DRIVE 12
197 #define GV_EVENT_SET_SD_STATE 13
198 #define GV_EVENT_SET_DRIVE_STATE 14
199 #define GV_EVENT_SET_VOL_STATE 15
200 #define GV_EVENT_SET_PLEX_STATE 16
201 #define GV_EVENT_RESET_CONFIG 17
202 #define GV_EVENT_PARITY_REBUILD 18
203 #define GV_EVENT_PARITY_CHECK 19
204 #define GV_EVENT_START_PLEX 20
205 #define GV_EVENT_START_VOLUME 21
206 #define GV_EVENT_ATTACH_PLEX 22
207 #define GV_EVENT_ATTACH_SD 23
208 #define GV_EVENT_DETACH_PLEX 24
209 #define GV_EVENT_DETACH_SD 25
210 #define GV_EVENT_RENAME_VOL 26
211 #define GV_EVENT_RENAME_PLEX 27
212 #define GV_EVENT_RENAME_SD 28
213 #define GV_EVENT_RENAME_DRIVE 29
214 #define GV_EVENT_MOVE_SD 30
215 #define GV_EVENT_SETUP_OBJECTS 31
216
217 #ifdef _KERNEL
218 struct gv_event {
219 int type;
220 void *arg1;
221 void *arg2;
222 intmax_t arg3;
223 intmax_t arg4;
224 TAILQ_ENTRY(gv_event) events;
225 };
226
227 /* This struct contains the main vinum config. */
228 struct gv_softc {
229 /* Linked lists of all objects in our setup. */
230 LIST_HEAD(,gv_drive) drives; /* All drives. */
231 LIST_HEAD(,gv_plex) plexes; /* All plexes. */
232 LIST_HEAD(,gv_sd) subdisks; /* All subdisks. */
233 LIST_HEAD(,gv_volume) volumes; /* All volumes. */
234
235 TAILQ_HEAD(,gv_event) equeue; /* Event queue. */
236 struct mtx equeue_mtx; /* Event queue lock. */
237 struct mtx bqueue_mtx; /* BIO queue lock. */
238 struct mtx config_mtx; /* Configuration lock. */
239 struct bio_queue_head *bqueue_down; /* BIO queue incoming
240 requests. */
241 struct bio_queue_head *bqueue_up; /* BIO queue for completed
242 requests. */
243 struct g_geom *geom; /* Pointer to our VINUM geom. */
244 struct proc *worker; /* Worker process. */
245 };
246 #endif
247
248 /* softc for a drive. */
249 struct gv_drive {
250 char name[GV_MAXDRIVENAME]; /* The name of this drive. */
251 char device[GV_MAXDRIVENAME]; /* Associated device. */
252 int state; /* The state of this drive. */
253 #define GV_DRIVE_DOWN 0
254 #define GV_DRIVE_UP 1
255
256 off_t size; /* Size of this drive. */
257 off_t avail; /* Available space. */
258 int sdcount; /* Number of subdisks. */
259
260 int flags;
261 #define GV_DRIVE_REFERENCED 0x01 /* The drive isn't really existing,
262 but was referenced by a subdisk
263 during taste. */
264 #define GV_DRIVE_ORPHANED 0x02 /* The drive was orphaned. */
265
266 struct gv_hdr *hdr; /* The drive header. */
267
268 struct g_consumer *consumer; /* Consumer attached to this drive. */
269 int active; /* Number of active requests. */
270
271 int freelist_entries; /* Count of freelist entries. */
272 LIST_HEAD(,gv_freelist) freelist; /* List of freelist entries. */
273 LIST_HEAD(,gv_sd) subdisks; /* Subdisks on this drive. */
274 LIST_ENTRY(gv_drive) drive; /* Entry in the vinum config. */
275
276 struct gv_softc *vinumconf; /* Pointer to the vinum conf. */
277 };
278
279 /* softc for a subdisk. */
280 struct gv_sd {
281 char name[GV_MAXSDNAME]; /* The name of this subdisk. */
282 off_t size; /* The size of this subdisk. */
283 off_t drive_offset; /* Offset in the underlying drive. */
284 off_t plex_offset; /* Offset in the associated plex. */
285 int state; /* The state of this subdisk. */
286 #define GV_SD_DOWN 0
287 #define GV_SD_STALE 1
288 #define GV_SD_INITIALIZING 2
289 #define GV_SD_REVIVING 3
290 #define GV_SD_UP 4
291
292 off_t initialized; /* Count of initialized bytes. */
293
294 int init_size; /* Initialization read/write size. */
295 int init_error; /* Flag error on initialization. */
296
297 int flags;
298 #define GV_SD_NEWBORN 0x01 /* Subdisk is created by user. */
299 #define GV_SD_TASTED 0x02 /* Subdisk is created during taste. */
300 #define GV_SD_CANGOUP 0x04 /* Subdisk can go up immediately. */
301 #define GV_SD_GROW 0x08 /* Subdisk is added to striped plex. */
302
303 char drive[GV_MAXDRIVENAME]; /* Name of underlying drive. */
304 char plex[GV_MAXPLEXNAME]; /* Name of associated plex. */
305
306 struct gv_drive *drive_sc; /* Pointer to underlying drive. */
307 struct gv_plex *plex_sc; /* Pointer to associated plex. */
308
309 LIST_ENTRY(gv_sd) from_drive; /* Subdisk list of underlying drive. */
310 LIST_ENTRY(gv_sd) in_plex; /* Subdisk list of associated plex. */
311 LIST_ENTRY(gv_sd) sd; /* Entry in the vinum config. */
312
313 struct gv_softc *vinumconf; /* Pointer to the vinum config. */
314 };
315
316 /* softc for a plex. */
317 struct gv_plex {
318 char name[GV_MAXPLEXNAME]; /* The name of the plex. */
319 off_t size; /* The size of the plex. */
320 int state; /* The plex state. */
321 #define GV_PLEX_DOWN 0
322 #define GV_PLEX_INITIALIZING 1
323 #define GV_PLEX_DEGRADED 2
324 #define GV_PLEX_GROWABLE 3
325 #define GV_PLEX_UP 4
326
327 int org; /* The plex organisation. */
328 #define GV_PLEX_DISORG 0
329 #define GV_PLEX_CONCAT 1
330 #define GV_PLEX_STRIPED 2
331 #define GV_PLEX_RAID5 4
332
333 int stripesize; /* The stripe size of the plex. */
334
335 char volume[GV_MAXVOLNAME]; /* Name of associated volume. */
336 struct gv_volume *vol_sc; /* Pointer to associated volume. */
337
338 int sddetached; /* Number of detached subdisks. */
339 int sdcount; /* Number of subdisks in this plex. */
340 int sddown; /* Number of subdisks that are down. */
341 int flags;
342 #define GV_PLEX_ADDED 0x01 /* Added to an existing volume. */
343 #define GV_PLEX_SYNCING 0x02 /* Plex is syncing from another plex. */
344 #define GV_PLEX_NEWBORN 0x20 /* The plex was just created. */
345 #define GV_PLEX_REBUILDING 0x40 /* The plex is rebuilding. */
346 #define GV_PLEX_GROWING 0x80 /* The plex is growing. */
347
348 off_t synced; /* Count of synced bytes. */
349
350 TAILQ_HEAD(,gv_raid5_packet) packets; /* RAID5 sub-requests. */
351
352 LIST_HEAD(,gv_sd) subdisks; /* List of attached subdisks. */
353 LIST_ENTRY(gv_plex) in_volume; /* Plex list of associated volume. */
354 LIST_ENTRY(gv_plex) plex; /* Entry in the vinum config. */
355
356 #ifdef _KERNEL
357 struct bio_queue_head *bqueue; /* BIO queue. */
358 struct bio_queue_head *wqueue; /* Waiting BIO queue. */
359 struct bio_queue_head *rqueue; /* Rebuild waiting BIO queue. */
360 #else
361 char *bpad, *wpad, *rpad; /* Padding for userland. */
362 #endif
363
364 struct gv_softc *vinumconf; /* Pointer to the vinum config. */
365 };
366
367 /* softc for a volume. */
368 struct gv_volume {
369 char name[GV_MAXVOLNAME]; /* The name of the volume. */
370 off_t size; /* The size of the volume. */
371 int plexcount; /* Number of plexes. */
372 int state; /* The state of the volume. */
373 #define GV_VOL_DOWN 0
374 #define GV_VOL_UP 1
375
376 int flags;
377 #define GV_VOL_NEWBORN 0x08 /* The volume was just created. */
378
379 LIST_HEAD(,gv_plex) plexes; /* List of attached plexes. */
380 LIST_ENTRY(gv_volume) volume; /* Entry in vinum config. */
381
382 struct g_provider *provider; /* Provider of this volume. */
383
384 #ifdef _KERNEL
385 struct bio_queue_head *wqueue; /* BIO delayed request queue. */
386 #else
387 char *wpad; /* Padding for userland. */
388 #endif
389
390 struct gv_plex *last_read_plex;
391 struct gv_softc *vinumconf; /* Pointer to the vinum config. */
392 };
393
394 #endif /* !_GEOM_VINUM_VAR_H */
Cache object: 06612bdf1b2599b4f9ee35760bae29ca
|