1139778Simp/*- 2190507Slulf * Copyright (c) 2004, 2007 Lukas Ertl 3130389Sle * Copyright (c) 1997, 1998, 1999 4130389Sle * Nan Yang Computer Services Limited. All rights reserved. 5130389Sle * 6130389Sle * Parts copyright (c) 1997, 1998 Cybernet Corporation, NetMAX project. 7130389Sle * Parts written by Greg Lehey. 8130389Sle * 9130389Sle * This software is distributed under the so-called ``Berkeley 10130389Sle * License'': * 11130389Sle * Redistribution and use in source and binary forms, with or without 12130389Sle * modification, are permitted provided that the following conditions 13130389Sle * are met: 14130389Sle * 1. Redistributions of source code must retain the above copyright 15130389Sle * notice, this list of conditions and the following disclaimer. 16130389Sle * 2. Redistributions in binary form must reproduce the above copyright 17130389Sle * notice, this list of conditions and the following disclaimer in the 18130389Sle * documentation and/or other materials provided with the distribution. 19130389Sle * 3. All advertising materials mentioning features or use of this software 20130389Sle * must display the following acknowledgement: 21130389Sle * This product includes software developed by Nan Yang Computer 22130389Sle * Services Limited. 23130389Sle * 4. Neither the name of the Company nor the names of its contributors 24130389Sle * may be used to endorse or promote products derived from this software 25130389Sle * without specific prior written permission. 26130389Sle * 27130389Sle * This software is provided ``as is'', and any express or implied 28130389Sle * warranties, including, but not limited to, the implied warranties of 29130389Sle * merchantability and fitness for a particular purpose are disclaimed. 30130389Sle * In no event shall the company or contributors be liable for any * direct, indirect, incidental, special, exemplary, or consequential 31130389Sle * damages (including, but not limited to, procurement of substitute 32130389Sle * goods or services; loss of use, data, or profits; or business 33130389Sle * interruption) however caused and on any theory of liability, whether 34130389Sle * in contract, strict liability, or tort (including negligence or 35130389Sle * otherwise) arising in any way out of the use of this software, even if 36130389Sle * advised of the possibility of such damage. 37130389Sle * 38130389Sle * $FreeBSD: releng/11.0/sys/geom/vinum/geom_vinum_var.h 207878 2010-05-10 19:12:23Z jh $ 39130389Sle */ 40130389Sle 41130389Sle#ifndef _GEOM_VINUM_VAR_H_ 42130389Sle#define _GEOM_VINUM_VAR_H_ 43130389Sle 44130389Sle/* 45130389Sle * Slice header 46130389Sle * 47130389Sle * Vinum drives start with this structure: 48130389Sle * 49130389Sle *\ Sector 50130389Sle * |--------------------------------------| 51130389Sle * | PDP-11 memorial boot block | 0 52130389Sle * |--------------------------------------| 53130389Sle * | Disk label, maybe | 1 54130389Sle * |--------------------------------------| 55130389Sle * | Slice definition (vinum_hdr) | 8 56130389Sle * |--------------------------------------| 57130389Sle * | | 58130389Sle * | Configuration info, first copy | 9 59130389Sle * | | 60130389Sle * |--------------------------------------| 61130389Sle * | | 62130389Sle * | Configuration info, second copy | 9 + size of config 63130389Sle * | | 64130389Sle * |--------------------------------------| 65130389Sle */ 66130389Sle 67130389Sle/* Sizes and offsets of our information. */ 68130389Sle#define GV_HDR_OFFSET 4096 /* Offset of vinum header. */ 69130389Sle#define GV_HDR_LEN 512 /* Size of vinum header. */ 70130389Sle#define GV_CFG_OFFSET 4608 /* Offset of first config copy. */ 71130389Sle#define GV_CFG_LEN 65536 /* Size of config copy. */ 72130389Sle 73130389Sle/* This is where the actual data starts. */ 74130389Sle#define GV_DATA_START (GV_CFG_LEN * 2 + GV_CFG_OFFSET) 75130389Sle/* #define GV_DATA_START (GV_CFG_LEN * 2 + GV_HDR_LEN) */ 76130389Sle 77130389Sle#define GV_MAXDRIVENAME 32 /* Maximum length of a device name. */ 78130389Sle#define GV_MAXSDNAME 64 /* Maximum length of a subdisk name. */ 79130389Sle#define GV_MAXPLEXNAME 64 /* Maximum length of a plex name. */ 80130389Sle#define GV_MAXVOLNAME 64 /* Maximum length of a volume name. */ 81130389Sle 82130389Sle/* Command line flags. */ 83130389Sle#define GV_FLAG_R 0x01 84130389Sle#define GV_FLAG_S 0x02 85130389Sle#define GV_FLAG_V 0x04 86130389Sle#define GV_FLAG_VV 0x08 87130389Sle#define GV_FLAG_F 0x10 88130389Sle 89130389Sle/* Object types. */ 90130389Sle#define GV_TYPE_VOL 1 91130389Sle#define GV_TYPE_PLEX 2 92130389Sle#define GV_TYPE_SD 3 93130389Sle#define GV_TYPE_DRIVE 4 94130389Sle 95130389Sle/* State changing flags. */ 96130389Sle#define GV_SETSTATE_FORCE 0x1 97130389Sle#define GV_SETSTATE_CONFIG 0x2 98130389Sle 99130389Sle/* Subdisk state bitmaps for plexes. */ 100130389Sle#define GV_SD_DOWNSTATE 0x01 /* Subdisk is down. */ 101130389Sle#define GV_SD_STALESTATE 0x02 /* Subdisk is stale. */ 102130389Sle#define GV_SD_INITSTATE 0x04 /* Subdisk is initializing. */ 103130389Sle#define GV_SD_UPSTATE 0x08 /* Subdisk is up. */ 104130389Sle 105130389Sle/* Synchronization/initialization request sizes. */ 106130389Sle#define GV_MIN_SYNCSIZE 512 107130389Sle#define GV_MAX_SYNCSIZE MAXPHYS 108130389Sle#define GV_DFLT_SYNCSIZE 65536 109130389Sle 110135173Sle/* Flags for BIOs, as they are processed within vinum. */ 111191856Slulf#define GV_BIO_GROW 0x01 112135173Sle#define GV_BIO_MALLOC 0x02 113135173Sle#define GV_BIO_ONHOLD 0x04 114135426Sle#define GV_BIO_SYNCREQ 0x08 115190507Slulf#define GV_BIO_INIT 0x10 116135966Sle#define GV_BIO_REBUILD 0x20 117138110Sle#define GV_BIO_CHECK 0x40 118138110Sle#define GV_BIO_PARITY 0x80 119190507Slulf#define GV_BIO_INTERNAL \ 120191856Slulf (GV_BIO_SYNCREQ | GV_BIO_INIT | GV_BIO_REBUILD | GV_BIO_CHECK | GV_BIO_GROW) 121135173Sle 122190507Slulf/* Error codes to be used within gvinum. */ 123190507Slulf#define GV_ERR_SETSTATE (-1) /* Error setting state. */ 124190507Slulf#define GV_ERR_BADSIZE (-2) /* Object has wrong size. */ 125190507Slulf#define GV_ERR_INVTYPE (-3) /* Invalid object type. */ 126190507Slulf#define GV_ERR_CREATE (-4) /* Error creating gvinum object. */ 127190507Slulf#define GV_ERR_ISBUSY (-5) /* Object is busy. */ 128190507Slulf#define GV_ERR_ISATTACHED (-6) /* Object is attached to another. */ 129190507Slulf#define GV_ERR_INVFLAG (-7) /* Invalid flag passed. */ 130190507Slulf#define GV_ERR_INVSTATE (-8) /* Invalid state. */ 131190507Slulf#define GV_ERR_NOTFOUND (-9) /* Object not found. */ 132190507Slulf#define GV_ERR_NAMETAKEN (-10) /* Object name is taken. */ 133190507Slulf#define GV_ERR_NOSPACE (-11) /* No space left on drive/subdisk. */ 134190507Slulf#define GV_ERR_BADOFFSET (-12) /* Invalid offset specified. */ 135190507Slulf#define GV_ERR_INVNAME (-13) /* Invalid object name. */ 136190507Slulf#define GV_ERR_PLEXORG (-14) /* Invalid plex organization. */ 137190507Slulf 138130389Sle/* 139130389Sle * hostname is 256 bytes long, but we don't need to shlep multiple copies in 140130389Sle * vinum. We use the host name just to identify this system, and 32 bytes 141130389Sle * should be ample for that purpose. 142130389Sle */ 143130389Sle 144130389Sle#define GV_HOSTNAME_LEN 32 145130389Slestruct gv_label { 146130389Sle char sysname[GV_HOSTNAME_LEN]; /* System name at creation time. */ 147130389Sle char name[GV_MAXDRIVENAME]; /* Our name of the drive. */ 148130389Sle struct timeval date_of_birth; /* The time it was created ... */ 149130389Sle struct timeval last_update; /* ... and the time of last update. */ 150130389Sle off_t drive_size; /* Total size incl. headers. */ 151130389Sle}; 152130389Sle 153130389Sle/* The 'header' of each valid vinum drive. */ 154130389Slestruct gv_hdr { 155130389Sle uint64_t magic; 156183514Slulf#define GV_OLD_MAGIC 0x494E2056494E4F00LL 157183514Slulf#define GV_OLD_NOMAGIC 0x4E4F2056494E4F00LL 158183514Slulf#define GV_MAGIC 0x56494E554D2D3100LL 159183514Slulf#define GV_NOMAGIC 0x56494E554D2D2D00LL 160130389Sle 161183514Slulf uint64_t config_length; 162130389Sle struct gv_label label; 163130389Sle}; 164130389Sle 165130389Sle/* A single freelist entry of a drive. */ 166130389Slestruct gv_freelist { 167130389Sle off_t size; /* Size of this free slot. */ 168130389Sle off_t offset; /* Offset on the drive. */ 169130389Sle LIST_ENTRY(gv_freelist) freelist; 170130389Sle}; 171130389Sle 172135173Sle/* 173135173Sle * Since we share structures between userland and kernel, we need this helper 174135173Sle * struct instead of struct bio_queue_head and friends. Maybe I find a proper 175135173Sle * solution some day. 176135173Sle */ 177135173Slestruct gv_bioq { 178135173Sle struct bio *bp; 179135173Sle TAILQ_ENTRY(gv_bioq) queue; 180135173Sle}; 181135173Sle 182190507Slulf#define GV_EVENT_DRIVE_TASTED 1 183190507Slulf#define GV_EVENT_DRIVE_LOST 2 184190507Slulf#define GV_EVENT_THREAD_EXIT 3 185190507Slulf#define GV_EVENT_CREATE_DRIVE 4 186190507Slulf#define GV_EVENT_CREATE_VOLUME 5 187190507Slulf#define GV_EVENT_CREATE_PLEX 6 188190507Slulf#define GV_EVENT_CREATE_SD 7 189190507Slulf#define GV_EVENT_SAVE_CONFIG 8 190190507Slulf#define GV_EVENT_RM_VOLUME 9 191190507Slulf#define GV_EVENT_RM_PLEX 10 192190507Slulf#define GV_EVENT_RM_SD 11 193190507Slulf#define GV_EVENT_RM_DRIVE 12 194190507Slulf#define GV_EVENT_SET_SD_STATE 13 195190507Slulf#define GV_EVENT_SET_DRIVE_STATE 14 196190507Slulf#define GV_EVENT_SET_VOL_STATE 15 197190507Slulf#define GV_EVENT_SET_PLEX_STATE 16 198190507Slulf#define GV_EVENT_RESET_CONFIG 17 199190507Slulf#define GV_EVENT_PARITY_REBUILD 18 200190507Slulf#define GV_EVENT_PARITY_CHECK 19 201190507Slulf#define GV_EVENT_START_PLEX 20 202190507Slulf#define GV_EVENT_START_VOLUME 21 203190507Slulf#define GV_EVENT_ATTACH_PLEX 22 204190507Slulf#define GV_EVENT_ATTACH_SD 23 205190507Slulf#define GV_EVENT_DETACH_PLEX 24 206190507Slulf#define GV_EVENT_DETACH_SD 25 207190507Slulf#define GV_EVENT_RENAME_VOL 26 208190507Slulf#define GV_EVENT_RENAME_PLEX 27 209190507Slulf#define GV_EVENT_RENAME_SD 28 210190507Slulf#define GV_EVENT_RENAME_DRIVE 29 211190507Slulf#define GV_EVENT_MOVE_SD 30 212190507Slulf#define GV_EVENT_SETUP_OBJECTS 31 213190507Slulf 214190507Slulf#ifdef _KERNEL 215190507Slulfstruct gv_event { 216190507Slulf int type; 217190507Slulf void *arg1; 218190507Slulf void *arg2; 219190507Slulf intmax_t arg3; 220190507Slulf intmax_t arg4; 221190507Slulf TAILQ_ENTRY(gv_event) events; 222190507Slulf}; 223190507Slulf 224130389Sle/* This struct contains the main vinum config. */ 225130389Slestruct gv_softc { 226130389Sle /* Linked lists of all objects in our setup. */ 227130389Sle LIST_HEAD(,gv_drive) drives; /* All drives. */ 228130389Sle LIST_HEAD(,gv_plex) plexes; /* All plexes. */ 229130389Sle LIST_HEAD(,gv_sd) subdisks; /* All subdisks. */ 230130389Sle LIST_HEAD(,gv_volume) volumes; /* All volumes. */ 231130389Sle 232190507Slulf TAILQ_HEAD(,gv_event) equeue; /* Event queue. */ 233191849Slulf struct mtx equeue_mtx; /* Event queue lock. */ 234191849Slulf struct mtx bqueue_mtx; /* BIO queue lock. */ 235190507Slulf struct mtx config_mtx; /* Configuration lock. */ 236191856Slulf struct bio_queue_head *bqueue_down; /* BIO queue incoming 237191856Slulf requests. */ 238191856Slulf struct bio_queue_head *bqueue_up; /* BIO queue for completed 239191856Slulf requests. */ 240130389Sle struct g_geom *geom; /* Pointer to our VINUM geom. */ 241207878Sjh struct proc *worker; /* Worker process. */ 242130389Sle}; 243191787Slulf#endif 244130389Sle 245130389Sle/* softc for a drive. */ 246130389Slestruct gv_drive { 247130389Sle char name[GV_MAXDRIVENAME]; /* The name of this drive. */ 248130389Sle char device[GV_MAXDRIVENAME]; /* Associated device. */ 249130389Sle int state; /* The state of this drive. */ 250130389Sle#define GV_DRIVE_DOWN 0 251130389Sle#define GV_DRIVE_UP 1 252130389Sle 253130389Sle off_t size; /* Size of this drive. */ 254130389Sle off_t avail; /* Available space. */ 255130389Sle int sdcount; /* Number of subdisks. */ 256130389Sle 257135173Sle int flags; 258190507Slulf#define GV_DRIVE_REFERENCED 0x01 /* The drive isn't really existing, 259190507Slulf but was referenced by a subdisk 260190507Slulf during taste. */ 261135173Sle 262190507Slulf struct gv_hdr *hdr; /* The drive header. */ 263130389Sle 264190507Slulf struct g_consumer *consumer; /* Consumer attached to this drive. */ 265190507Slulf 266130389Sle int freelist_entries; /* Count of freelist entries. */ 267130389Sle LIST_HEAD(,gv_freelist) freelist; /* List of freelist entries. */ 268130389Sle LIST_HEAD(,gv_sd) subdisks; /* Subdisks on this drive. */ 269130389Sle LIST_ENTRY(gv_drive) drive; /* Entry in the vinum config. */ 270130389Sle 271130389Sle struct gv_softc *vinumconf; /* Pointer to the vinum conf. */ 272130389Sle}; 273130389Sle 274130389Sle/* softc for a subdisk. */ 275130389Slestruct gv_sd { 276130389Sle char name[GV_MAXSDNAME]; /* The name of this subdisk. */ 277130389Sle off_t size; /* The size of this subdisk. */ 278130389Sle off_t drive_offset; /* Offset in the underlying drive. */ 279130389Sle off_t plex_offset; /* Offset in the associated plex. */ 280130389Sle int state; /* The state of this subdisk. */ 281130389Sle#define GV_SD_DOWN 0 282130389Sle#define GV_SD_STALE 1 283130389Sle#define GV_SD_INITIALIZING 2 284130389Sle#define GV_SD_REVIVING 3 285130389Sle#define GV_SD_UP 4 286130389Sle 287130389Sle off_t initialized; /* Count of initialized bytes. */ 288130389Sle 289130389Sle int init_size; /* Initialization read/write size. */ 290130389Sle int init_error; /* Flag error on initialization. */ 291130389Sle 292130389Sle int flags; 293190507Slulf#define GV_SD_NEWBORN 0x01 /* Subdisk is created by user. */ 294190507Slulf#define GV_SD_TASTED 0x02 /* Subdisk is created during taste. */ 295190507Slulf#define GV_SD_CANGOUP 0x04 /* Subdisk can go up immediately. */ 296190507Slulf#define GV_SD_GROW 0x08 /* Subdisk is added to striped plex. */ 297130389Sle 298130389Sle char drive[GV_MAXDRIVENAME]; /* Name of underlying drive. */ 299130389Sle char plex[GV_MAXPLEXNAME]; /* Name of associated plex. */ 300130389Sle 301130389Sle struct gv_drive *drive_sc; /* Pointer to underlying drive. */ 302130389Sle struct gv_plex *plex_sc; /* Pointer to associated plex. */ 303130389Sle 304130389Sle LIST_ENTRY(gv_sd) from_drive; /* Subdisk list of underlying drive. */ 305130389Sle LIST_ENTRY(gv_sd) in_plex; /* Subdisk list of associated plex. */ 306130389Sle LIST_ENTRY(gv_sd) sd; /* Entry in the vinum config. */ 307130389Sle 308130389Sle struct gv_softc *vinumconf; /* Pointer to the vinum config. */ 309130389Sle}; 310130389Sle 311130389Sle/* softc for a plex. */ 312130389Slestruct gv_plex { 313130389Sle char name[GV_MAXPLEXNAME]; /* The name of the plex. */ 314130389Sle off_t size; /* The size of the plex. */ 315130389Sle int state; /* The plex state. */ 316130389Sle#define GV_PLEX_DOWN 0 317130389Sle#define GV_PLEX_INITIALIZING 1 318130389Sle#define GV_PLEX_DEGRADED 2 319190507Slulf#define GV_PLEX_GROWABLE 3 320190507Slulf#define GV_PLEX_UP 4 321130389Sle 322130389Sle int org; /* The plex organisation. */ 323130389Sle#define GV_PLEX_DISORG 0 324130389Sle#define GV_PLEX_CONCAT 1 325130389Sle#define GV_PLEX_STRIPED 2 326130389Sle#define GV_PLEX_RAID5 4 327130389Sle 328130389Sle int stripesize; /* The stripe size of the plex. */ 329130389Sle 330130389Sle char volume[GV_MAXVOLNAME]; /* Name of associated volume. */ 331130389Sle struct gv_volume *vol_sc; /* Pointer to associated volume. */ 332130389Sle 333190507Slulf int sddetached; /* Number of detached subdisks. */ 334130389Sle int sdcount; /* Number of subdisks in this plex. */ 335130389Sle int sddown; /* Number of subdisks that are down. */ 336130389Sle int flags; 337130389Sle#define GV_PLEX_ADDED 0x01 /* Added to an existing volume. */ 338130389Sle#define GV_PLEX_SYNCING 0x02 /* Plex is syncing from another plex. */ 339130389Sle#define GV_PLEX_NEWBORN 0x20 /* The plex was just created. */ 340190507Slulf#define GV_PLEX_REBUILDING 0x40 /* The plex is rebuilding. */ 341190507Slulf#define GV_PLEX_GROWING 0x80 /* The plex is growing. */ 342130389Sle 343130389Sle off_t synced; /* Count of synced bytes. */ 344130389Sle 345135426Sle TAILQ_HEAD(,gv_raid5_packet) packets; /* RAID5 sub-requests. */ 346130389Sle 347130389Sle LIST_HEAD(,gv_sd) subdisks; /* List of attached subdisks. */ 348130389Sle LIST_ENTRY(gv_plex) in_volume; /* Plex list of associated volume. */ 349130389Sle LIST_ENTRY(gv_plex) plex; /* Entry in the vinum config. */ 350130389Sle 351190507Slulf#ifdef _KERNEL 352190507Slulf struct bio_queue_head *bqueue; /* BIO queue. */ 353190507Slulf struct bio_queue_head *wqueue; /* Waiting BIO queue. */ 354190507Slulf struct bio_queue_head *rqueue; /* Rebuild waiting BIO queue. */ 355190507Slulf#else 356190507Slulf char *bpad, *wpad, *rpad; /* Padding for userland. */ 357190507Slulf#endif 358130389Sle 359130389Sle struct gv_softc *vinumconf; /* Pointer to the vinum config. */ 360130389Sle}; 361130389Sle 362130389Sle/* softc for a volume. */ 363130389Slestruct gv_volume { 364130389Sle char name[GV_MAXVOLNAME]; /* The name of the volume. */ 365130389Sle off_t size; /* The size of the volume. */ 366130389Sle int plexcount; /* Number of plexes. */ 367130389Sle int state; /* The state of the volume. */ 368130389Sle#define GV_VOL_DOWN 0 369130389Sle#define GV_VOL_UP 1 370130389Sle 371135426Sle int flags; 372190507Slulf#define GV_VOL_NEWBORN 0x08 /* The volume was just created. */ 373135426Sle 374190507Slulf LIST_HEAD(,gv_plex) plexes; /* List of attached plexes. */ 375190507Slulf LIST_ENTRY(gv_volume) volume; /* Entry in vinum config. */ 376190507Slulf 377190507Slulf struct g_provider *provider; /* Provider of this volume. */ 378190507Slulf 379190507Slulf#ifdef _KERNEL 380190507Slulf struct bio_queue_head *wqueue; /* BIO delayed request queue. */ 381154075Sle#else 382190507Slulf char *wpad; /* Padding for userland. */ 383154075Sle#endif 384135426Sle 385148048Sle struct gv_plex *last_read_plex; 386130389Sle struct gv_softc *vinumconf; /* Pointer to the vinum config. */ 387130389Sle}; 388130389Sle 389130389Sle#endif /* !_GEOM_VINUM_VAR_H */ 390