The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/vinum/vinumvar.h

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 1bd04df294eada4f7a57411e442d4131


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.