kernel: Remove two more major numbers.
[dragonfly.git] / sys / dev / raid / vinum / vinumvar.h
CommitLineData
984263bc
MD
1/*-
2 * Copyright (c) 1997, 1998, 1999
3 * Nan Yang Computer Services Limited. All rights reserved.
4 *
5 * Parts copyright (c) 1997, 1998 Cybernet Corporation, NetMAX project.
6 *
7 * Written by Greg Lehey
8 *
9 * This software is distributed under the so-called ``Berkeley
10 * License'':
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by Nan Yang Computer
23 * Services Limited.
24 * 4. Neither the name of the Company nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * This software is provided ``as is'', and any express or implied
29 * warranties, including, but not limited to, the implied warranties of
30 * merchantability and fitness for a particular purpose are disclaimed.
31 * In no event shall the company or contributors be liable for any
32 * direct, indirect, incidental, special, exemplary, or consequential
33 * damages (including, but not limited to, procurement of substitute
34 * goods or services; loss of use, data, or profits; or business
35 * interruption) however caused and on any theory of liability, whether
36 * in contract, strict liability, or tort (including negligence or
37 * otherwise) arising in any way out of the use of this software, even if
38 * advised of the possibility of such damage.
984263bc
MD
39 */
40
41#include <sys/time.h>
1f2de5d4 42#include "vinumstate.h"
984263bc 43
c2fcd54e
MD
44/*
45 * A disk block number or offset
46 */
47typedef int64_t vinum_off_t;
48
984263bc
MD
49/*
50 * Some configuration maxima. They're an enum because
51 * we can't define global constants. Sorry about that.
52 *
53 * These aren't as bad as they look: most of them are soft limits.
54 */
55
56#define VINUMROOT
57enum constants {
7c8f38d4
MD
58 VINUM_HEADER = 512, /* size of header on disk */
59 MAXCONFIGLINE = 1024, /* maximum size of one config line */
60 MINVINUMSLICE = 1048576, /* minimum size of a slice */
61
7c8f38d4
MD
62 ROUND_ROBIN_READPOL = -1, /* round robin read policy */
63
64 /*
65 * type field in minor number
66 */
67 VINUM_VOLUME_TYPE = 0,
68 VINUM_PLEX_TYPE = 1,
69 VINUM_SD_TYPE = 2,
70 VINUM_DRIVE_TYPE = 3,
71 VINUM_SUPERDEV_TYPE = 4, /* super device. */
72 VINUM_RAWPLEX_TYPE = 5, /* anonymous plex */
73 VINUM_RAWSD_TYPE = 6, /* anonymous subdisk */
74
75 /*
76 * Shifts for the individual fields in the device
77 */
78 VINUM_TYPE_SHIFT = 28,
79 VINUM_VOL_SHIFT = 0,
80 VINUM_PLEX_SHIFT = 16,
81 VINUM_SD_SHIFT = 20,
82 VINUM_VOL_WIDTH = 8,
83 VINUM_PLEX_WIDTH = 3,
84 VINUM_SD_WIDTH = 8,
85
86 /*
87 * Shifts for the second half of raw plex and
88 * subdisk numbers
89 */
90 VINUM_RAWPLEX_SHIFT = 8, /* shift the second half this much */
91 VINUM_RAWPLEX_WIDTH = 12, /* width of second half */
92
93 MAJORDEV_SHIFT = 8,
94
95 MAXPLEX = 8, /* max number of plexes in a volume */
96 MAXSD = 256, /* max number of subdisks in a plex */
97 MAXDRIVENAME = 32, /* max length of a device name */
98 MAXSDNAME = 64, /* max length of a subdisk name */
99 MAXPLEXNAME = 64, /* max length of a plex name */
100 MAXVOLNAME = 64, /* max length of a volume name */
101 MAXNAME = 64, /* max length of any name */
102
103
104 /*
105 * Define a minor device number.
106 * This is not used directly; instead, it's
107 * called by the other macros.
108 */
109#define VINUMMINOR(v,p,s,t) ( (v << VINUM_VOL_SHIFT) \
984263bc
MD
110 | (p << VINUM_PLEX_SHIFT) \
111 | (s << VINUM_SD_SHIFT) \
112 | (t << VINUM_TYPE_SHIFT) )
113
e4c9c0c8 114/* Create device minor numbers */
984263bc 115
e4c9c0c8 116#ifdef _KERNEL
984263bc 117
e4c9c0c8 118#define VINUMDEV(v,p,s,t) \
d736a600 119 VINUMMINOR (v, p, s, t)
e4c9c0c8
MD
120
121#define VINUM_PLEX(p) \
d736a600 122 ((VINUM_RAWPLEX_TYPE << VINUM_TYPE_SHIFT) \
e4c9c0c8 123 | (p & 0xff) \
d736a600 124 | ((p & ~0xff) << 8))
e4c9c0c8
MD
125
126#define VINUM_SD(s) \
d736a600 127 ((VINUM_RAWSD_TYPE << VINUM_TYPE_SHIFT) \
e4c9c0c8 128 | (s & 0xff) \
d736a600 129 | ((s & ~0xff) << 8))
e4c9c0c8
MD
130
131#endif
984263bc
MD
132
133 /* Create a bit mask for x bits */
134#define MASK(x) ((1 << (x)) - 1)
135
136 /* Create a raw block device minor number */
7c8f38d4
MD
137#define VINUMRMINOR(d,t) \
138 ( ((d & MASK(VINUM_VOL_WIDTH)) << VINUM_VOL_SHIFT) \
139 | ((d & ~MASK(VINUM_VOL_WIDTH)) << \
140 (VINUM_PLEX_SHIFT + VINUM_VOL_WIDTH)) \
141 | (t << VINUM_TYPE_SHIFT) )
984263bc 142
984263bc
MD
143 /* extract device type */
144#define DEVTYPE(x) ((minor (x) >> VINUM_TYPE_SHIFT) & 7)
145
146 /*
147 * This mess is used to catch people who compile
148 * a debug vinum(8) and non-debug kernel module,
149 * or the other way round.
150 */
151
152#ifdef VINUMDEBUG
7c8f38d4
MD
153
154/* superdevice number */
155#define VINUM_SUPERDEV VINUMMINOR(1, 0, 0, VINUM_SUPERDEV_TYPE)
156
157/* non-debug superdevice number */
158#define VINUM_WRONGSUPERDEV VINUMMINOR(2, 0, 0, VINUM_SUPERDEV_TYPE)
159
984263bc 160#else
984263bc 161
7c8f38d4
MD
162/* superdevice number */
163#define VINUM_SUPERDEV VINUMMINOR(2, 0, 0, VINUM_SUPERDEV_TYPE)
984263bc 164
7c8f38d4
MD
165/* debug superdevice number */
166#define VINUM_WRONGSUPERDEV VINUMMINOR(1, 0, 0, VINUM_SUPERDEV_TYPE)
984263bc 167
7c8f38d4
MD
168#endif
169
170/* daemon superdevice number */
171#define VINUM_DAEMON_DEV VINUMMINOR(0, 0, 0, VINUM_SUPERDEV_TYPE)
172
173 /*
174 * the number of object entries to cater for initially, and also the
175 * value by which they are incremented. It doesn't take long
176 * to extend them, so theoretically we could start with 1 of each, but
177 * it's untidy to allocate such small areas. These values are
178 * probably too small.
179 */
180
181 INITIAL_DRIVES = 4,
182 INITIAL_VOLUMES = 4,
183 INITIAL_PLEXES = 8,
184 INITIAL_SUBDISKS = 16,
185 INITIAL_SUBDISKS_IN_PLEX = 4, /* num subdisks to alloc to a plex */
186 INITIAL_SUBDISKS_IN_DRIVE = 4, /* num subdisks to alloc to a drive */
187 INITIAL_DRIVE_FREELIST = 16, /* num entries in drive freelist */
188 PLEX_REGION_TABLE_SIZE = 8, /* num entries in plex region tables */
189 PLEX_LOCKS = 256, /* num locks to alloc to a plex */
190 MAX_REVIVE_BLOCKSIZE = MAXPHYS, /* maximum revive block size */
191 DEFAULT_REVIVE_BLOCKSIZE = 65536,/* default revive block size */
192 VINUMHOSTNAMELEN = 32, /* host name field in label */
984263bc
MD
193};
194
195/* device numbers */
196
197/*
7c8f38d4
MD
198 * 31 30 28 27 20 19 18 16 15 8 7 0
199 * |---------------------------------------------------------------------|
200 * |X | Type | Subdisk number | X| Plex | Major | volno |
201 * |---------------------------------------------------------------------|
984263bc 202 *
7c8f38d4 203 * 0x2 03 1 19 06
984263bc
MD
204 *
205 * The fields in the minor number are interpreted as follows:
206 *
207 * Volume: Only type and volume number are relevant
7c8f38d4
MD
208 * Plex in volume: type, plex number in volume and volume number
209 * are relevant
984263bc
MD
210 * raw plex: type, plex number is made of bits 27-16 and 7-0
211 * raw subdisk: type, subdisk number is made of bits 27-16 and 7-0
212 */
213
7c8f38d4
MD
214#if 0
215
984263bc
MD
216/* This doesn't get used. Consider removing it. */
217struct devcode {
7c8f38d4
MD
218 /*
219 * CARE. These fields assume a big-endian word. On a
220 * little-endian system, they're the wrong way around
221 */
222 unsigned volume:8; /* up to 256 volumes */
223 unsigned major:8; /* major number fits */
224 unsigned plex:3; /* up to 8 plexes per volume */
225 unsigned unused:1; /* up for grabs */
226 unsigned sd:8; /* up to 256 subdisks per plex */
227 unsigned type:3; /* type of object */
228 /*
229 * type field
230 VINUM_VOLUME = 0,
231 VINUM_PLEX = 1,
232 VINUM_SUBDISK = 2,
233 VINUM_DRIVE = 3,
234 VINUM_SUPERDEV = 4,
235 VINUM_RAWPLEX = 5,
236 VINUM_RAWSD = 6 */
237 unsigned signbit:1; /* to make 32 bits */
984263bc
MD
238};
239
7c8f38d4
MD
240#endif
241
d736a600 242#define VINUM_BASE "vinum/"
984263bc
MD
243#define VINUM_DIR "/dev/vinum"
244
245/*
246 * These definitions help catch
247 * userland/kernel mismatches.
248 */
249#if VINUMDEBUG
7c8f38d4
MD
250
251/* normal super device */
d736a600
MD
252#define VINUM_WRONGSUPERDEV_NAME VINUM_DIR "/control"
253#define VINUM_WRONGSUPERDEV_BASE VINUM_BASE "control"
7c8f38d4
MD
254
255/* debug super device */
d736a600
MD
256#define VINUM_SUPERDEV_NAME VINUM_DIR "/Control"
257#define VINUM_SUPERDEV_BASE VINUM_BASE "Control"
7c8f38d4 258
984263bc 259#else
7c8f38d4
MD
260
261/* debug super device */
d736a600
MD
262#define VINUM_WRONGSUPERDEV_NAME VINUM_DIR "/Control"
263#define VINUM_WRONGSUPERDEV_BASE VINUM_BASE "Control"
7c8f38d4
MD
264
265/* normal super device */
d736a600
MD
266#define VINUM_SUPERDEV_NAME VINUM_DIR "/control"
267#define VINUM_SUPERDEV_BASE VINUM_BASE "control"
7c8f38d4 268
984263bc 269#endif
7c8f38d4
MD
270
271/* super device for daemon only */
d736a600
MD
272#define VINUM_DAEMON_DEV_NAME VINUM_DIR "/controld"
273#define VINUM_DAEMON_DEV_BASE VINUM_BASE "controld"
984263bc
MD
274
275/*
276 * Flags for all objects. Most of them only apply to
277 * specific objects, but we have space for all in any
278 * 32 bit flags word.
279 */
280enum objflags {
7c8f38d4
MD
281 VF_LOCKED = 1, /* locked access to this object */
282 VF_LOCKING = 2, /* we want access to this object */
283 VF_OPEN = 4, /* object has openers */
284 VF_WRITETHROUGH = 8, /* volume: write through */
285 VF_INITED = 0x10, /* unit has been initialized */
286
287 /* 0x20 unused, was: VF_WLABEL: label area is writable */
288 VF_LABELLING = 0x40, /* unit is currently being labelled */
289 VF_WANTED = 0x80, /* waiting to obtain a lock */
290 VF_RAW = 0x100, /* raw volume (no file system) */
291 VF_LOADED = 0x200, /* module is loaded */
292 VF_CONFIGURING = 0x400, /* someone is changing the config */
293 VF_WILL_CONFIGURE = 0x800, /* someone wants to change the config */
294 VF_CONFIG_INCOMPLETE = 0x1000, /* not finished changing the config */
295 VF_CONFIG_SETUPSTATE = 0x2000, /* set a vol up if all plexes empty */
296 VF_READING_CONFIG = 0x4000, /* reading config database from disk */
297 VF_FORCECONFIG = 0x8000, /* config drives even with diff names */
298 VF_NEWBORN = 0x10000, /* for objects: we've just created it */
299 VF_CONFIGURED = 0x20000, /* for drives: we read the config */
300 VF_STOPPING = 0x40000, /* for vinum_conf: stop on last close */
301
302 VF_DAEMONOPEN = 0x80000, /* the daemon has us open (only
303 * superdev) */
304
305 VF_CREATED = 0x100000, /* for vols: freshly created,
306 * more then new */
307 VF_HOTSPARE = 0x200000, /* for drives: use as hot spare */
308 VF_RETRYERRORS = 0x400000, /* don't down subdisks on I/O errors */
984263bc
MD
309};
310
311/* Global configuration information for the vinum subsystem */
312struct _vinum_conf {
7c8f38d4
MD
313 /* Pointers to vinum structures */
314 struct drive *drive;
315 struct sd *sd;
316 struct plex *plex;
317 struct volume *volume;
318
319 /* the number allocated */
320 int drives_allocated;
321 int subdisks_allocated;
322 int plexes_allocated;
323 int volumes_allocated;
324
325 /* and the number currently in use */
326 int drives_used;
327 int subdisks_used;
328 int plexes_used;
329 int volumes_used;
330
331 int flags;
332
333#define VINUM_MAXACTIVE 30000 /* max number of active requests */
334 int active; /* current number of requests outstanding */
335 int maxactive; /* max number of requests ever outstanding */
984263bc 336#if VINUMDEBUG
7c8f38d4
MD
337 struct request *lastrq;
338 struct bio *lastbio;
984263bc 339#endif
7c8f38d4 340 int physbufs;
984263bc
MD
341};
342
343/* Use these defines to simplify code */
344#define DRIVE vinum_conf.drive
345#define SD vinum_conf.sd
346#define PLEX vinum_conf.plex
347#define VOL vinum_conf.volume
348#define VFLAGS vinum_conf.flags
349
350/*
351 * Slice header
352 *
353 * Vinum drives start with this structure:
354 *
355 *\ Sector
356 * |--------------------------------------|
357 * | PDP-11 memorial boot block | 0
358 * |--------------------------------------|
359 * | Disk label, maybe | 1
360 * |--------------------------------------|
361 * | Slice definition (vinum_hdr) | 8
362 * |--------------------------------------|
363 * | |
364 * | Configuration info, first copy | 9
365 * | |
366 * |--------------------------------------|
367 * | |
368 * | Configuration info, second copy | 9 + size of config
369 * | |
370 * |--------------------------------------|
371 */
372
7c8f38d4
MD
373/*
374 * Sizes and offsets of our information
375 */
984263bc 376enum {
7c8f38d4
MD
377 VINUM_LABEL_OFFSET = 4096, /* offset of vinum label */
378 VINUMHEADERLEN = 512, /* size of vinum label */
379 VINUM_CONFIG_OFFSET = 4608, /* offset of first config copy */
380 MAXCONFIG = 65536, /* and size of config copy */
381
382 /* this is where the data starts */
383 DATASTART = (MAXCONFIG * 2 + VINUM_CONFIG_OFFSET) / DEV_BSIZE
984263bc
MD
384};
385
386/*
387 * hostname is 256 bytes long, but we don't need to shlep
388 * multiple copies in vinum. We use the host name just
389 * to identify this system, and 32 bytes should be ample
390 * for that purpose
391 */
392
393struct vinum_label {
7c8f38d4
MD
394 char sysname[VINUMHOSTNAMELEN]; /* system name at time of creation */
395 char name[MAXDRIVENAME]; /* our name of the drive */
396 struct timeval date_of_birth; /* the time it was created */
397 struct timeval last_update; /* and the time of last update */
398 /*
399 * total size in bytes of the drive. This value
400 * includes the headers.
401 */
402 off_t drive_size;
984263bc
MD
403};
404
405struct vinum_hdr {
7c8f38d4
MD
406 uint64_t magic; /* we're long on magic numbers */
407
408 /*
409 * Size in bytes of each copy of the
410 * configuration info. This must be a multiple
411 * of the sector size.
412 */
413 int config_length;
414 struct vinum_label label; /* unique label */
984263bc
MD
415};
416
7c8f38d4
MD
417/* should be this */
418#define VINUM_MAGIC 22322600044678729LL
419
420/* becomes this after obliteration */
421#define VINUM_NOMAGIC 22322600044678990LL
422
984263bc
MD
423/* Information returned from read_drive_label */
424enum drive_label_info {
7c8f38d4
MD
425 DL_CANT_OPEN, /* invalid partition */
426 DL_NOT_OURS, /* valid part, but no vinum label */
427 DL_DELETED_LABEL, /* valid part, deleted label found */
428 DL_WRONG_DRIVE, /* drive name doesn't match */
429 DL_OURS /* valid partition and label found */
984263bc
MD
430};
431
432/*** Drive definitions ***/
433/*
434 * A drive corresponds to a disk slice. We use a different term to show
435 * the difference in usage: it doesn't have to be a slice, and could
436 * theoretically be a complete, unpartitioned disk
437 */
438
439struct drive {
7c8f38d4
MD
440 char devicename[MAXDRIVENAME]; /* name of the slice it's on */
441 enum drivestate state; /* current state */
442 int flags; /* flags */
443 int subdisks_allocated; /* number of entries in sd */
444 int subdisks_used; /* and the number used */
445 int blocksize; /* size of fs blocks */
446 int pid; /* of locker */
447 u_int64_t sectors_available; /* number of sectors still available */
448 int secsperblock;
449 int lasterror; /* last error on drive */
450 int driveno; /* index of drive in vinum_conf */
451 int opencount; /* number of up subdisks */
452 u_int64_t reads; /* number of reads on this drive */
453 u_int64_t writes; /* number of writes on this drive */
454 u_int64_t bytes_read; /* number of bytes read */
455 u_int64_t bytes_written; /* number of bytes written */
456 struct vinum_label label; /* and the label information */
457#define DRIVE_MAXACTIVE 30000 /* maximum number of active requests */
458 int active; /* current number of reqs outstanding */
459 int maxactive; /* max num of reqs ever outstanding */
460 int freelist_size; /* entries alloced in free list */
461 int freelist_entries; /* entries used in free list */
462 struct drive_freelist { /* sorted list of free space on drive */
463 u_int64_t offset; /* offset of entry */
464 u_int64_t sectors; /* and length in sectors */
465 } *freelist;
466 struct partinfo partinfo; /* partition information */
467 /* XXX kludge until we get this struct cleaned up */
984263bc 468#if _KERNEL
7c8f38d4
MD
469 struct vnode *vp;
470 struct cdev *dev;
984263bc 471#else
d736a600
MD
472 void *vp_dummy;
473 void *dev_dummy;
984263bc
MD
474#endif
475#ifdef VINUMDEBUG
7c8f38d4
MD
476 char lockfilename[16]; /* locked with file */
477 int lockline; /* and the line number */
984263bc
MD
478#endif
479};
480
481/*** Subdisk definitions ***/
482
483struct sd {
7c8f38d4
MD
484 char name[MAXSDNAME]; /* name of subdisk */
485 enum sdstate state; /* state */
486 int flags;
487 int lasterror; /* last error occurred */
488 /* offsets in blocks */
489 int64_t driveoffset; /* offset on drive */
d736a600
MD
490#ifdef _KERNEL
491 cdev_t sd_dev;
492#else
493 void *sd_dev_dummy;
494#endif
7c8f38d4
MD
495
496 /*
497 * plexoffset is the offset from the beginning
498 * of the plex to the very first part of the
499 * subdisk, in sectors. For striped, RAID-4 and
500 * RAID-5 plexes, only the first stripe is
501 * located at this offset
502 */
503 int64_t plexoffset; /* offset in plex */
504 u_int64_t sectors; /* and length in sectors */
505 int plexno; /* index of plex, if it belongs */
506 int driveno; /* index of the drive */
507 int sdno; /* our index in vinum_conf */
508 int plexsdno; /* and our number in our plex */
509 /* (undefined if no plex) */
510 u_int64_t reads; /* number of reads on this subdisk */
511 u_int64_t writes; /* number of writes on this subdisk */
512 u_int64_t bytes_read; /* number of bytes read */
513 u_int64_t bytes_written; /* number of bytes written */
514 /* revive parameters */
515 u_int64_t revived; /* blkno of current revive request */
516 int revive_blocksize; /* revive block size (bytes) */
517 int revive_interval; /* and time to wait between transfers */
518 pid_t reviver; /* PID of reviving process */
519 /* init parameters */
520 u_int64_t initialized; /* blkno of current init request */
521 int init_blocksize; /* init block size (bytes) */
522 int init_interval; /* time to wait between transfers */
523 struct request *waitlist; /* list of reqs waiting on revive op */
984263bc
MD
524};
525
526/*** Plex definitions ***/
527
528/* kinds of plex organization */
529enum plexorg {
7c8f38d4
MD
530 plex_disorg, /* disorganized */
531 plex_concat, /* concatenated plex */
532 plex_striped, /* striped plex */
533 plex_raid4, /* RAID4 plex */
534 plex_raid5 /* RAID5 plex */
984263bc
MD
535};
536
537/* Recognize plex organizations */
7c8f38d4
MD
538/* RAID 1, 4 or 5 */
539#define isstriped(p) (p->organization >= plex_striped)
540
541/* RAID 4 or 5 */
542#define isparity(p) (p->organization >= plex_raid4)
984263bc
MD
543
544struct plex {
7c8f38d4
MD
545 char name[MAXPLEXNAME]; /* name of plex */
546 enum plexorg organization; /* Plex organization */
547 enum plexstate state; /* and current state */
d736a600
MD
548#ifdef _KERNEL
549 cdev_t plex_dev;
550#else
551 void *plex_dev_dummy;
552#endif
7c8f38d4
MD
553 u_int64_t length; /* total length of plex (sectors) */
554 int flags;
555 int stripesize; /* size of stripe or raid band,
556 * in sectors */
557 int subdisks; /* number of associated subdisks */
558 int subdisks_allocated; /* number of subdisks allocated
559 * space for */
560 int *sdnos; /* list of component subdisks */
561 int plexno; /* index of plex in vinum_conf */
562 int volno; /* index of volume */
563 int volplexno; /* number of plex in volume */
564 /* Statistics */
565 u_int64_t reads; /* number of reads on this plex */
566 u_int64_t writes; /* number of writes on this plex */
567 u_int64_t bytes_read; /* number of bytes read */
568 u_int64_t bytes_written; /* number of bytes written */
569 u_int64_t recovered_reads; /* number of recovered read
570 * operations */
571 u_int64_t degraded_writes; /* number of degraded writes */
572 u_int64_t parityless_writes; /* number of parityless writes */
573 u_int64_t multiblock; /* requests that needed more than
574 * one block */
575 u_int64_t multistripe; /* requests that needed more than
576 * one stripe */
577 int sddowncount; /* number of subdisks down */
578
579 /* Lock information */
580 int usedlocks; /* number currently in use */
581 int lockwaits; /* and number of waits for locks */
582 off_t checkblock; /* block number for parity op */
583 struct rangelock *lock; /* ranges of locked addresses */
984263bc
MD
584};
585
586/*** Volume definitions ***/
587
588/* Address range definitions, for locking volumes */
589struct rangelock {
c2fcd54e 590 vinum_off_t stripe; /* address + 1 of the range being locked */
7c8f38d4 591 struct buf *bp; /* user's buffer pointer */
984263bc
MD
592};
593
594struct volume {
7c8f38d4
MD
595 char name[MAXVOLNAME]; /* name of volume */
596 enum volumestate state; /* current state */
597 int plexes; /* number of plexes */
598 int preferred_plex; /* plex to read from, -1 for
599 * round-robin */
d736a600
MD
600#ifdef _KERNEL
601 cdev_t vol_dev;
602#else
603 void *vol_dev_dummy;
604#endif
605
7c8f38d4
MD
606 /*
607 * index of plex used for last read, for
608 * round-robin.
609 */
610 int last_plex_read;
611 int volno; /* volume number */
612 int flags; /* status and configuration flags */
613 int openflags; /* flags supplied to last open(2) */
614 u_int64_t size; /* size of volume */
615 int blocksize; /* logical block size */
616 int active; /* number of outstanding
617 * requests active */
618 int subops; /* and the number of suboperations */
619 /* Statistics */
620 u_int64_t bytes_read; /* number of bytes read */
621 u_int64_t bytes_written; /* number of bytes written */
622 u_int64_t reads; /* number of reads on this volume */
623 u_int64_t writes; /* number of writes on this volume */
624 u_int64_t recovered_reads; /* reads recovered from another plex */
625
626 /*
627 * Unlike subdisks in the plex, space for the
628 * plex pointers is static.
629 */
630 int plex[MAXPLEX]; /* index of plexes */
984263bc
MD
631};
632
633/*
634 * Table expansion. Expand table, which contains oldcount
635 * entries of type element, by increment entries, and change
636 * oldcount accordingly
637 */
638#define EXPAND(table, element, oldcount, increment) \
639{ \
7c8f38d4
MD
640 expand_table((void **) &table, \
641 oldcount * sizeof (element), \
642 (oldcount + increment) * sizeof (element)); \
643 oldcount += increment; \
644}
984263bc 645
7c8f38d4
MD
646/*
647 * Information on vinum's memory usage
648 */
984263bc 649struct meminfo {
7c8f38d4
MD
650 int mallocs; /* number of malloced blocks */
651 int total_malloced; /* total amount malloced */
652 int highwater; /* maximum number of mallocs */
653 struct mc *malloced; /* pointer to kernel table */
984263bc
MD
654};
655
656#define MCFILENAMELEN 16
657struct mc {
7c8f38d4
MD
658 struct timeval time;
659 int seq;
660 int size;
661 short line;
662 caddr_t address;
663 char file[MCFILENAMELEN];
984263bc
MD
664};
665
666/*
667 * These enums are used by the state transition
668 * routines. They're in bit map format:
669 *
670 * Bit 0: Other plexes in the volume are down
671 * Bit 1: Other plexes in the volume are up
672 * Bit 2: The current plex is up
673 * Maybe they should be local to
674 * state.c
675 */
676enum volplexstate {
7c8f38d4
MD
677 volplex_onlyusdown = 0, /* 0: we're the only plex,
678 * and we're down */
679 volplex_alldown, /* 1: another plex is down,
680 * and so are we */
681 volplex_otherup, /* 2: another plex is up */
682 volplex_otherupdown, /* 3: other plexes are up and down */
683 volplex_onlyus, /* 4: we're up and alone */
684 volplex_onlyusup, /* 5: only we are up, others are down */
685 volplex_allup, /* 6: all plexes are up */
686 volplex_someup /* 7: some plexes are up,
687 * including us */
984263bc
MD
688};
689
690/* state map for plex */
691enum sdstates {
7c8f38d4
MD
692 sd_emptystate = 1,
693 sd_downstate = 2, /* SD is down */
694 sd_crashedstate = 4, /* SD is crashed */
695 sd_obsoletestate = 8, /* SD is obsolete */
696 sd_stalestate = 16, /* SD is stale */
697 sd_rebornstate = 32, /* SD is reborn */
698 sd_upstate = 64, /* SD is up */
699 sd_initstate = 128, /* SD is initializing */
700 sd_initializedstate = 256, /* SD is initialized */
701 sd_otherstate = 512, /* SD is in some other state */
984263bc
MD
702};
703
704/*
705 * This is really just a parameter to pass to
706 * set_<foo>_state, but since it needs to be known
707 * in the external definitions, we need to define
708 * it here
709 */
710enum setstateflags {
7c8f38d4
MD
711 setstate_none = 0, /* no flags */
712 setstate_force = 1, /* force the state change */
713 setstate_configuring = 2, /* we're currently configuring,
714 don't save */
984263bc
MD
715};
716
717/* Operations for parityops to perform. */
718enum parityop {
7c8f38d4
MD
719 checkparity,
720 rebuildparity,
721 rebuildandcheckparity, /* rebuildparity with the -v option */
984263bc
MD
722};
723
724#ifdef VINUMDEBUG
7c8f38d4
MD
725
726/*
727 * Debugging stuff
728 */
984263bc 729enum debugflags {
7c8f38d4
MD
730 DEBUG_ADDRESSES = 1, /* show buffer information during
731 * requests */
732 DEBUG_NUMOUTPUT = 2, /* show the value of vp->v_numoutput */
733 DEBUG_RESID = 4, /* go into debugger in complete_rqe */
734 DEBUG_LASTREQS = 8, /* keep a circular buffer of
735 * last requests */
736 DEBUG_REVIVECONFLICT = 16, /* print info about revive conflicts */
737 DEBUG_EOFINFO = 32, /* print info about EOF detection */
738 DEBUG_MEMFREE = 64, /* keep info about Frees */
739 DEBUG_BIGDRIVE = 128, /* pretend our drives are 100 times
740 * the size */
741 DEBUG_REMOTEGDB = 256, /* go into remote gdb */
742 DEBUG_WARNINGS = 512, /* log various relatively
743 * harmless warnings */
984263bc
MD
744};
745
746#ifdef _KERNEL
747#ifdef __i386__
7c8f38d4 748#define longjmp LongJmp /* test our longjmps */
984263bc
MD
749#endif
750#endif
751#endif