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