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