File:  [DragonFly] / src / sys / dev / raid / vinum / vinumvar.h
Revision 1.4: download - view: text, annotated - select for diffs
Thu Aug 7 21:17:10 2003 UTC (11 years, 2 months ago) by dillon
Branches: MAIN
CVS tags: HEAD
kernel tree reorganization stage 1: Major cvs repository work (not logged as
commits) plus a major reworking of the #include's to accomodate the
relocations.

    * CVS repository files manually moved.  Old directories left intact
      and empty (temporary).

    * Reorganize all filesystems into vfs/, most devices into dev/,
      sub-divide devices by function.

    * Begin to move device-specific architecture files to the device
      subdirs rather then throwing them all into, e.g. i386/include

    * Reorganize files related to system busses, placing the related code
      in a new bus/ directory.  Also move cam to bus/cam though this may
      not have been the best idea in retrospect.

    * Reorganize emulation code and place it in a new emulation/ directory.

    * Remove the -I- compiler option in order to allow #include file
      localization, rename all config generated X.h files to use_X.h to
      clean up the conflicts.

    * Remove /usr/src/include (or /usr/include) dependancies during the
      kernel build, beyond what is normally needed to compile helper
      programs.

    * Make config create 'machine' softlinks for architecture specific
      directories outside of the standard <arch>/include.

    * Bump the config rev.

    WARNING! after this commit /usr/include and /usr/src/sys/compile/*
    should be regenerated from scratch.

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