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

Cache object: dcc3b1d1dfef2198f82bc1a19d5ae7cd


[ 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.