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