1/*- 2 * Copyright (c) 2004, 2007 Lukas Ertl 3 * Copyright (c) 1997, 1998, 1999 4 * Nan Yang Computer Services Limited. All rights reserved. 5 * 6 * Parts copyright (c) 1997, 1998 Cybernet Corporation, NetMAX project. 7 * Parts written by Greg Lehey. 8 * 9 * This software is distributed under the so-called ``Berkeley 10 * License'': * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by Nan Yang Computer 22 * Services Limited. 23 * 4. Neither the name of the Company nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * This software is provided ``as is'', and any express or implied 28 * warranties, including, but not limited to, the implied warranties of 29 * merchantability and fitness for a particular purpose are disclaimed. 30 * In no event shall the company or contributors be liable for any * direct, indirect, incidental, special, exemplary, or consequential 31 * damages (including, but not limited to, procurement of substitute 32 * goods or services; loss of use, data, or profits; or business 33 * interruption) however caused and on any theory of liability, whether 34 * in contract, strict liability, or tort (including negligence or 35 * otherwise) arising in any way out of the use of this software, even if 36 * advised of the possibility of such damage. 37 * 38 * $FreeBSD$ 39 */ 40 41#ifndef _GEOM_VINUM_VAR_H_ 42#define _GEOM_VINUM_VAR_H_ 43 44/* 45 * Slice header 46 * 47 * Vinum drives start with this structure: 48 * 49 *\ Sector 50 * |--------------------------------------| 51 * | PDP-11 memorial boot block | 0 52 * |--------------------------------------| 53 * | Disk label, maybe | 1 54 * |--------------------------------------| 55 * | Slice definition (vinum_hdr) | 8 56 * |--------------------------------------| 57 * | | 58 * | Configuration info, first copy | 9 59 * | | 60 * |--------------------------------------| 61 * | | 62 * | Configuration info, second copy | 9 + size of config 63 * | | 64 * |--------------------------------------| 65 */ 66 67/* Sizes and offsets of our information. */ 68#define GV_HDR_OFFSET 4096 /* Offset of vinum header. */ 69#define GV_HDR_LEN 512 /* Size of vinum header. */ 70#define GV_CFG_OFFSET 4608 /* Offset of first config copy. */ 71#define GV_CFG_LEN 65536 /* Size of config copy. */ 72 73/* This is where the actual data starts. */ 74#define GV_DATA_START (GV_CFG_LEN * 2 + GV_CFG_OFFSET) 75/* #define GV_DATA_START (GV_CFG_LEN * 2 + GV_HDR_LEN) */ 76 77#define GV_MAXDRIVENAME 32 /* Maximum length of a device name. */ 78#define GV_MAXSDNAME 64 /* Maximum length of a subdisk name. */ 79#define GV_MAXPLEXNAME 64 /* Maximum length of a plex name. */ 80#define GV_MAXVOLNAME 64 /* Maximum length of a volume name. */ 81 82/* Command line flags. */ 83#define GV_FLAG_R 0x01 84#define GV_FLAG_S 0x02 85#define GV_FLAG_V 0x04 86#define GV_FLAG_VV 0x08 87#define GV_FLAG_F 0x10 88 89/* Object types. */ 90#define GV_TYPE_VOL 1 91#define GV_TYPE_PLEX 2 92#define GV_TYPE_SD 3 93#define GV_TYPE_DRIVE 4 94 95/* State changing flags. */ 96#define GV_SETSTATE_FORCE 0x1 97#define GV_SETSTATE_CONFIG 0x2 98 99/* Subdisk state bitmaps for plexes. */ 100#define GV_SD_DOWNSTATE 0x01 /* Subdisk is down. */ 101#define GV_SD_STALESTATE 0x02 /* Subdisk is stale. */ 102#define GV_SD_INITSTATE 0x04 /* Subdisk is initializing. */ 103#define GV_SD_UPSTATE 0x08 /* Subdisk is up. */ 104 105/* Synchronization/initialization request sizes. */ 106#define GV_MIN_SYNCSIZE 512 107#define GV_MAX_SYNCSIZE MAXPHYS 108#define GV_DFLT_SYNCSIZE 65536 109 110/* Flags for BIOs, as they are processed within vinum. */ 111#define GV_BIO_GROW 0x01 112#define GV_BIO_MALLOC 0x02 113#define GV_BIO_ONHOLD 0x04 114#define GV_BIO_SYNCREQ 0x08 115#define GV_BIO_INIT 0x10 116#define GV_BIO_REBUILD 0x20 117#define GV_BIO_CHECK 0x40 118#define GV_BIO_PARITY 0x80 119#define GV_BIO_INTERNAL \ 120 (GV_BIO_SYNCREQ | GV_BIO_INIT | GV_BIO_REBUILD | GV_BIO_CHECK | GV_BIO_GROW) 121 122/* Error codes to be used within gvinum. */ 123#define GV_ERR_SETSTATE (-1) /* Error setting state. */ 124#define GV_ERR_BADSIZE (-2) /* Object has wrong size. */ 125#define GV_ERR_INVTYPE (-3) /* Invalid object type. */ 126#define GV_ERR_CREATE (-4) /* Error creating gvinum object. */ 127#define GV_ERR_ISBUSY (-5) /* Object is busy. */ 128#define GV_ERR_ISATTACHED (-6) /* Object is attached to another. */ 129#define GV_ERR_INVFLAG (-7) /* Invalid flag passed. */ 130#define GV_ERR_INVSTATE (-8) /* Invalid state. */ 131#define GV_ERR_NOTFOUND (-9) /* Object not found. */ 132#define GV_ERR_NAMETAKEN (-10) /* Object name is taken. */ 133#define GV_ERR_NOSPACE (-11) /* No space left on drive/subdisk. */ 134#define GV_ERR_BADOFFSET (-12) /* Invalid offset specified. */ 135#define GV_ERR_INVNAME (-13) /* Invalid object name. */ 136#define GV_ERR_PLEXORG (-14) /* Invalid plex organization. */ 137 138/* 139 * hostname is 256 bytes long, but we don't need to shlep multiple copies in 140 * vinum. We use the host name just to identify this system, and 32 bytes 141 * should be ample for that purpose. 142 */ 143 144#define GV_HOSTNAME_LEN 32 145struct gv_label { 146 char sysname[GV_HOSTNAME_LEN]; /* System name at creation time. */ 147 char name[GV_MAXDRIVENAME]; /* Our name of the drive. */ 148 struct timeval date_of_birth; /* The time it was created ... */ 149 struct timeval last_update; /* ... and the time of last update. */ 150 off_t drive_size; /* Total size incl. headers. */ 151}; 152 153/* The 'header' of each valid vinum drive. */ 154struct gv_hdr { 155 uint64_t magic; 156#define GV_OLD_MAGIC 0x494E2056494E4F00LL 157#define GV_OLD_NOMAGIC 0x4E4F2056494E4F00LL 158#define GV_MAGIC 0x56494E554D2D3100LL 159#define GV_NOMAGIC 0x56494E554D2D2D00LL 160 161 uint64_t config_length; 162 struct gv_label label; 163}; 164 165/* A single freelist entry of a drive. */ 166struct gv_freelist { 167 off_t size; /* Size of this free slot. */ 168 off_t offset; /* Offset on the drive. */ 169 LIST_ENTRY(gv_freelist) freelist; 170}; 171 172/* 173 * Since we share structures between userland and kernel, we need this helper 174 * struct instead of struct bio_queue_head and friends. Maybe I find a proper 175 * solution some day. 176 */ 177struct gv_bioq { 178 struct bio *bp; 179 TAILQ_ENTRY(gv_bioq) queue; 180}; 181 182#define GV_EVENT_DRIVE_TASTED 1 183#define GV_EVENT_DRIVE_LOST 2 184#define GV_EVENT_THREAD_EXIT 3 185#define GV_EVENT_CREATE_DRIVE 4 186#define GV_EVENT_CREATE_VOLUME 5 187#define GV_EVENT_CREATE_PLEX 6 188#define GV_EVENT_CREATE_SD 7 189#define GV_EVENT_SAVE_CONFIG 8 190#define GV_EVENT_RM_VOLUME 9 191#define GV_EVENT_RM_PLEX 10 192#define GV_EVENT_RM_SD 11 193#define GV_EVENT_RM_DRIVE 12 194#define GV_EVENT_SET_SD_STATE 13 195#define GV_EVENT_SET_DRIVE_STATE 14 196#define GV_EVENT_SET_VOL_STATE 15 197#define GV_EVENT_SET_PLEX_STATE 16 198#define GV_EVENT_RESET_CONFIG 17 199#define GV_EVENT_PARITY_REBUILD 18 200#define GV_EVENT_PARITY_CHECK 19 201#define GV_EVENT_START_PLEX 20 202#define GV_EVENT_START_VOLUME 21 203#define GV_EVENT_ATTACH_PLEX 22 204#define GV_EVENT_ATTACH_SD 23 205#define GV_EVENT_DETACH_PLEX 24 206#define GV_EVENT_DETACH_SD 25 207#define GV_EVENT_RENAME_VOL 26 208#define GV_EVENT_RENAME_PLEX 27 209#define GV_EVENT_RENAME_SD 28 210#define GV_EVENT_RENAME_DRIVE 29 211#define GV_EVENT_MOVE_SD 30 212#define GV_EVENT_SETUP_OBJECTS 31 213 214#ifdef _KERNEL 215struct gv_event { 216 int type; 217 void *arg1; 218 void *arg2; 219 intmax_t arg3; 220 intmax_t arg4; 221 TAILQ_ENTRY(gv_event) events; 222}; 223 224/* This struct contains the main vinum config. */ 225struct gv_softc { 226 /* Linked lists of all objects in our setup. */ 227 LIST_HEAD(,gv_drive) drives; /* All drives. */ 228 LIST_HEAD(,gv_plex) plexes; /* All plexes. */ 229 LIST_HEAD(,gv_sd) subdisks; /* All subdisks. */ 230 LIST_HEAD(,gv_volume) volumes; /* All volumes. */ 231 232 TAILQ_HEAD(,gv_event) equeue; /* Event queue. */ 233 struct mtx equeue_mtx; /* Event queue lock. */ 234 struct mtx bqueue_mtx; /* BIO queue lock. */ 235 struct mtx config_mtx; /* Configuration lock. */ 236 struct bio_queue_head *bqueue_down; /* BIO queue incoming 237 requests. */ 238 struct bio_queue_head *bqueue_up; /* BIO queue for completed 239 requests. */ 240 struct g_geom *geom; /* Pointer to our VINUM geom. */ 241 struct proc *worker; /* Worker process. */ 242}; 243#endif 244 245/* softc for a drive. */ 246struct gv_drive { 247 char name[GV_MAXDRIVENAME]; /* The name of this drive. */ 248 char device[GV_MAXDRIVENAME]; /* Associated device. */ 249 int state; /* The state of this drive. */ 250#define GV_DRIVE_DOWN 0 251#define GV_DRIVE_UP 1 252 253 off_t size; /* Size of this drive. */ 254 off_t avail; /* Available space. */ 255 int sdcount; /* Number of subdisks. */ 256 257 int flags; 258#define GV_DRIVE_REFERENCED 0x01 /* The drive isn't really existing, 259 but was referenced by a subdisk 260 during taste. */ 261 262 struct gv_hdr *hdr; /* The drive header. */ 263 264 struct g_consumer *consumer; /* Consumer attached to this drive. */ 265 266 int freelist_entries; /* Count of freelist entries. */ 267 LIST_HEAD(,gv_freelist) freelist; /* List of freelist entries. */ 268 LIST_HEAD(,gv_sd) subdisks; /* Subdisks on this drive. */ 269 LIST_ENTRY(gv_drive) drive; /* Entry in the vinum config. */ 270 271 struct gv_softc *vinumconf; /* Pointer to the vinum conf. */ 272}; 273 274/* softc for a subdisk. */ 275struct gv_sd { 276 char name[GV_MAXSDNAME]; /* The name of this subdisk. */ 277 off_t size; /* The size of this subdisk. */ 278 off_t drive_offset; /* Offset in the underlying drive. */ 279 off_t plex_offset; /* Offset in the associated plex. */ 280 int state; /* The state of this subdisk. */ 281#define GV_SD_DOWN 0 282#define GV_SD_STALE 1 283#define GV_SD_INITIALIZING 2 284#define GV_SD_REVIVING 3 285#define GV_SD_UP 4 286 287 off_t initialized; /* Count of initialized bytes. */ 288 289 int init_size; /* Initialization read/write size. */ 290 int init_error; /* Flag error on initialization. */ 291 292 int flags; 293#define GV_SD_NEWBORN 0x01 /* Subdisk is created by user. */ 294#define GV_SD_TASTED 0x02 /* Subdisk is created during taste. */ 295#define GV_SD_CANGOUP 0x04 /* Subdisk can go up immediately. */ 296#define GV_SD_GROW 0x08 /* Subdisk is added to striped plex. */ 297 298 char drive[GV_MAXDRIVENAME]; /* Name of underlying drive. */ 299 char plex[GV_MAXPLEXNAME]; /* Name of associated plex. */ 300 301 struct gv_drive *drive_sc; /* Pointer to underlying drive. */ 302 struct gv_plex *plex_sc; /* Pointer to associated plex. */ 303 304 LIST_ENTRY(gv_sd) from_drive; /* Subdisk list of underlying drive. */ 305 LIST_ENTRY(gv_sd) in_plex; /* Subdisk list of associated plex. */ 306 LIST_ENTRY(gv_sd) sd; /* Entry in the vinum config. */ 307 308 struct gv_softc *vinumconf; /* Pointer to the vinum config. */ 309}; 310 311/* softc for a plex. */ 312struct gv_plex { 313 char name[GV_MAXPLEXNAME]; /* The name of the plex. */ 314 off_t size; /* The size of the plex. */ 315 int state; /* The plex state. */ 316#define GV_PLEX_DOWN 0 317#define GV_PLEX_INITIALIZING 1 318#define GV_PLEX_DEGRADED 2 319#define GV_PLEX_GROWABLE 3 320#define GV_PLEX_UP 4 321 322 int org; /* The plex organisation. */ 323#define GV_PLEX_DISORG 0 324#define GV_PLEX_CONCAT 1 325#define GV_PLEX_STRIPED 2 326#define GV_PLEX_RAID5 4 327 328 int stripesize; /* The stripe size of the plex. */ 329 330 char volume[GV_MAXVOLNAME]; /* Name of associated volume. */ 331 struct gv_volume *vol_sc; /* Pointer to associated volume. */ 332 333 int sddetached; /* Number of detached subdisks. */ 334 int sdcount; /* Number of subdisks in this plex. */ 335 int sddown; /* Number of subdisks that are down. */ 336 int flags; 337#define GV_PLEX_ADDED 0x01 /* Added to an existing volume. */ 338#define GV_PLEX_SYNCING 0x02 /* Plex is syncing from another plex. */ 339#define GV_PLEX_NEWBORN 0x20 /* The plex was just created. */ 340#define GV_PLEX_REBUILDING 0x40 /* The plex is rebuilding. */ 341#define GV_PLEX_GROWING 0x80 /* The plex is growing. */ 342 343 off_t synced; /* Count of synced bytes. */ 344 345 TAILQ_HEAD(,gv_raid5_packet) packets; /* RAID5 sub-requests. */ 346 347 LIST_HEAD(,gv_sd) subdisks; /* List of attached subdisks. */ 348 LIST_ENTRY(gv_plex) in_volume; /* Plex list of associated volume. */ 349 LIST_ENTRY(gv_plex) plex; /* Entry in the vinum config. */ 350 351#ifdef _KERNEL 352 struct bio_queue_head *bqueue; /* BIO queue. */ 353 struct bio_queue_head *wqueue; /* Waiting BIO queue. */ 354 struct bio_queue_head *rqueue; /* Rebuild waiting BIO queue. */ 355#else 356 char *bpad, *wpad, *rpad; /* Padding for userland. */ 357#endif 358 359 struct gv_softc *vinumconf; /* Pointer to the vinum config. */ 360}; 361 362/* softc for a volume. */ 363struct gv_volume { 364 char name[GV_MAXVOLNAME]; /* The name of the volume. */ 365 off_t size; /* The size of the volume. */ 366 int plexcount; /* Number of plexes. */ 367 int state; /* The state of the volume. */ 368#define GV_VOL_DOWN 0 369#define GV_VOL_UP 1 370 371 int flags; 372#define GV_VOL_NEWBORN 0x08 /* The volume was just created. */ 373 374 LIST_HEAD(,gv_plex) plexes; /* List of attached plexes. */ 375 LIST_ENTRY(gv_volume) volume; /* Entry in vinum config. */ 376 377 struct g_provider *provider; /* Provider of this volume. */ 378 379#ifdef _KERNEL 380 struct bio_queue_head *wqueue; /* BIO delayed request queue. */ 381#else 382 char *wpad; /* Padding for userland. */ 383#endif 384 385 struct gv_plex *last_read_plex; 386 struct gv_softc *vinumconf; /* Pointer to the vinum config. */ 387}; 388 389#endif /* !_GEOM_VINUM_VAR_H */ 390