10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 51623Stw21770 * Common Development and Distribution License (the "License"). 61623Stw21770 * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 221623Stw21770 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #ifndef _SYS_MD_MDDB_H 270Sstevel@tonic-gate #define _SYS_MD_MDDB_H 280Sstevel@tonic-gate 290Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 300Sstevel@tonic-gate 310Sstevel@tonic-gate #include <sys/types.h> 320Sstevel@tonic-gate #include <sys/buf.h> 330Sstevel@tonic-gate 340Sstevel@tonic-gate #ifdef __cplusplus 350Sstevel@tonic-gate extern "C" { 360Sstevel@tonic-gate #endif 370Sstevel@tonic-gate 380Sstevel@tonic-gate #if 0 /* DRP FOR DEBUGGING */ 390Sstevel@tonic-gate #define MDDB_FAKE 400Sstevel@tonic-gate #endif 410Sstevel@tonic-gate 420Sstevel@tonic-gate /* Private flags */ 430Sstevel@tonic-gate #define MD_PRV_GOTIT 0x0001 /* Been snarfed */ 440Sstevel@tonic-gate #define MD_PRV_DELETE 0x0002 /* Record pending to be deleted */ 450Sstevel@tonic-gate #define MD_PRV_COMMIT 0x0004 /* Record pending to be commited */ 460Sstevel@tonic-gate #define MD_PRV_CLEANUP 0x0008 /* Record pending to be cleaned up */ 470Sstevel@tonic-gate #define MD_PRV_CONVD 0x0010 /* Record has been converted (32->64) */ 480Sstevel@tonic-gate #define MD_PRV_PENDDEL (MD_PRV_GOTIT | MD_PRV_DELETE) 490Sstevel@tonic-gate #define MD_PRV_PENDCOM (MD_PRV_GOTIT | MD_PRV_COMMIT) 500Sstevel@tonic-gate #define MD_PRV_PENDCLEAN (MD_PRV_GOTIT | MD_PRV_CLEANUP) 510Sstevel@tonic-gate 520Sstevel@tonic-gate 530Sstevel@tonic-gate #define MDDB_E_INVALID (-1) /* an invalid argument was passed */ 540Sstevel@tonic-gate #define MDDB_E_EXISTS (-2) /* doing an operation a 2nd time which can */ 550Sstevel@tonic-gate /* only be done once */ 560Sstevel@tonic-gate #define MDDB_E_MASTER (-3) /* problem occurred accessing mastor block */ 570Sstevel@tonic-gate /* returned from NEW_DEV */ 580Sstevel@tonic-gate #define MDDB_E_TOOSMALL (-4) /* device is not large enough */ 590Sstevel@tonic-gate #define MDDB_E_NORECORD (-5) /* record does not exits */ 600Sstevel@tonic-gate /* 610Sstevel@tonic-gate * returned from: mddb_getnextrec 620Sstevel@tonic-gate * mddb_getrecsize 630Sstevel@tonic-gate * mddb_commitrec 640Sstevel@tonic-gate * mddb_commitrecs 650Sstevel@tonic-gate * mddb_deleterec 660Sstevel@tonic-gate */ 670Sstevel@tonic-gate #define MDDB_E_NOSPACE (-6) /* no space to create record */ 680Sstevel@tonic-gate #define MDDB_E_NOTNOW (-7) /* do not presently have enough resources */ 690Sstevel@tonic-gate /* to perform requested operation */ 700Sstevel@tonic-gate #define MDDB_E_NODB (-8) /* no database exist */ 710Sstevel@tonic-gate #define MDDB_E_NOTOWNER (-9) /* have not been told to grab this set */ 720Sstevel@tonic-gate #define MDDB_E_STALE (-10) /* database is stale */ 730Sstevel@tonic-gate #define MDDB_E_TOOFEW (-11) /* not enough replicas available */ 740Sstevel@tonic-gate #define MDDB_E_TAGDATA (-12) /* tagged data detected */ 750Sstevel@tonic-gate #define MDDB_E_ACCOK (-13) /* 50/50 mode */ 760Sstevel@tonic-gate #define MDDB_E_NTAGDATA (-14) /* tagop try, no tag data */ 770Sstevel@tonic-gate #define MDDB_E_ACCNOTOK (-15) /* accop try, no accept possible */ 780Sstevel@tonic-gate #define MDDB_E_NOLOCBLK (-16) /* No valid locators found */ 790Sstevel@tonic-gate #define MDDB_E_NOLOCNMS (-17) /* No valid locator name information */ 800Sstevel@tonic-gate #define MDDB_E_NODIRBLK (-18) /* No directory blocks found */ 810Sstevel@tonic-gate #define MDDB_E_NOTAGREC (-19) /* No tag record blocks found */ 820Sstevel@tonic-gate #define MDDB_E_NOTAG (-20) /* No matching tag record found */ 830Sstevel@tonic-gate #define MDDB_E_NODEVID (-21) /* No device id found */ 840Sstevel@tonic-gate 850Sstevel@tonic-gate #define MDDB_MINBLKS 16 /* enough for a few metadevices */ 860Sstevel@tonic-gate #define MDDB_MAXBLKS 8192 /* size of free bit map (must be / 8) */ 870Sstevel@tonic-gate #define MDDB_MN_MINBLKS 32768 /* Multinode metadb minimum size */ 880Sstevel@tonic-gate /* 16MB */ 890Sstevel@tonic-gate #define MDDB_MN_MAXBLKS 524288 /* size of free bit map (must be / 8) */ 900Sstevel@tonic-gate /* 256MB */ 910Sstevel@tonic-gate 920Sstevel@tonic-gate #define MDDB_C_STALE 0x0001 930Sstevel@tonic-gate #define MDDB_C_TOOFEW 0x0002 940Sstevel@tonic-gate #define MDDB_C_NOTOWNER 0x0004 950Sstevel@tonic-gate #define MDDB_C_SET_MN_STALE 0x0008 /* Set MN set to stale */ 960Sstevel@tonic-gate #define MDDB_C_IMPORT 0x0010 970Sstevel@tonic-gate 980Sstevel@tonic-gate /* 990Sstevel@tonic-gate * Defines used to set/reset new master flag in set structure. 1000Sstevel@tonic-gate * Used during reconfig cycle to determine quickly if there is 1010Sstevel@tonic-gate * new master for the set. 1020Sstevel@tonic-gate */ 1030Sstevel@tonic-gate #define MDDB_NM_SET 0x0001 1040Sstevel@tonic-gate #define MDDB_NM_RESET 0x0002 1050Sstevel@tonic-gate #define MDDB_NM_GET 0x0004 1060Sstevel@tonic-gate 1070Sstevel@tonic-gate /* Definitions of flag in Locator Block Device ID data area - mddb_did_info */ 1080Sstevel@tonic-gate #define MDDB_DID_EXISTS 0x0001 /* Device ID exists */ 1090Sstevel@tonic-gate #define MDDB_DID_VALID 0x0002 /* Device ID valid on current system */ 1100Sstevel@tonic-gate #define MDDB_DID_UPDATED 0x0004 /* locator/sidelocator info updated */ 1110Sstevel@tonic-gate 1120Sstevel@tonic-gate /* Definitions of flag in Locator Block - mddb_lb */ 1130Sstevel@tonic-gate #define MDDB_DEVID_STYLE 0x0001 /* Locator Block in Device ID format */ 1140Sstevel@tonic-gate #define MDDB_MNSET 0x0002 /* MDDB is for a multi-node set */ 1150Sstevel@tonic-gate 1160Sstevel@tonic-gate 1170Sstevel@tonic-gate #define MDDB_MAX_PATCH 25 /* number of locations that */ 1180Sstevel@tonic-gate /* can be patched in etc/system */ 1190Sstevel@tonic-gate 1200Sstevel@tonic-gate /* 1210Sstevel@tonic-gate * Set struct used by all parts of the driver, to store anchor pointers. 1221623Stw21770 * 1231623Stw21770 * Lock associated with field in this structure: 1241623Stw21770 * 1251623Stw21770 * Some of fields are accessible by both the single threaded ioctl thread 1261623Stw21770 * and internal threads such as resync, hotsparing...etc. In this case 1271623Stw21770 * additional protection is needed. For example, s_db is protected by 1281623Stw21770 * s_dbmx additionally and s_un, s_ui are protected by md_unit_array_rw.lock 1291623Stw21770 * s_nm, s_nmid, s_did_nm and s_did_nmid and s_dtp are protected by nm_lock 1301623Stw21770 * Rest of other fileds are protected by md_mx. Two fields s_un_next and 1311623Stw21770 * s_un_avail are introduced by the friendly name project and are ONLY 1321623Stw21770 * accessible via a single threaded ioctl thread which already is protected 1331623Stw21770 * by the ioctl lock and there is no need to add extra protection to them. 1341623Stw21770 * However, in the future if they become accessible by other internal threads 1351623Stw21770 * then an additional protection such as md_mx lock is highly recommended. 1361623Stw21770 * 1370Sstevel@tonic-gate */ 1380Sstevel@tonic-gate typedef struct md_set { 1390Sstevel@tonic-gate uint_t s_status; /* set status */ 1400Sstevel@tonic-gate void **s_ui; /* set unit incore anchor */ 1410Sstevel@tonic-gate void **s_un; /* set unit anchor */ 1420Sstevel@tonic-gate void *s_hsp; /* set Hot Spare Pool anchor */ 1430Sstevel@tonic-gate void *s_hs; /* set Hot Spare anchor */ 1440Sstevel@tonic-gate void *s_db; /* set MDDB anchor */ 1450Sstevel@tonic-gate kmutex_t s_dbmx; /* set MDDB mutex */ 1460Sstevel@tonic-gate void *s_nm; /* set namespace anchor */ 1470Sstevel@tonic-gate mddb_recid_t s_nmid; /* set namespace anchor record */ 1480Sstevel@tonic-gate void *s_did_nm; /* set device id namespace anchor */ 1490Sstevel@tonic-gate mddb_recid_t s_did_nmid; /* set device id namespace anchor rec */ 1500Sstevel@tonic-gate void *s_dtp; /* set data tag rec */ 1510Sstevel@tonic-gate int s_am_i_master; /* incore master flag for this node */ 1520Sstevel@tonic-gate md_mn_nodeid_t s_nodeid; /* nodeid of this node - for MN sets */ 1530Sstevel@tonic-gate uint_t s_rcnt; /* incore resync count for set */ 1541623Stw21770 unit_t s_un_next; /* s_un scan starts here */ 1551623Stw21770 unit_t s_un_avail; /* number of avail slots */ 1560Sstevel@tonic-gate } md_set_t; 1570Sstevel@tonic-gate 1580Sstevel@tonic-gate 1590Sstevel@tonic-gate #define MDDB_MAGIC_MB 0x6d646d62 /* magic number for master blocks */ 1600Sstevel@tonic-gate #define MDDB_MAGIC_DB 0x6d646462 /* magic number for directory blocks */ 1610Sstevel@tonic-gate #define MDDB_MAGIC_RB 0x6d647262 /* magic number for record blocks */ 1620Sstevel@tonic-gate #define MDDB_MAGIC_LB 0x6d646c62 /* magic number for locator blocks */ 1630Sstevel@tonic-gate #define MDDB_MAGIC_LN 0x6d646c6e /* magic number for locator names */ 1640Sstevel@tonic-gate #define MDDB_MAGIC_DT 0x6d646474 /* magic number for data tag */ 1650Sstevel@tonic-gate #define MDDB_MAGIC_DI 0x6d646469 /* magic number for device ID block */ 1660Sstevel@tonic-gate #define MDDB_MAGIC_DU 0x6d646475 /* magic num for dummy mb */ 1670Sstevel@tonic-gate #define MDDB_MAGIC_DE 0x6d646465 /* magic num for mb devid */ 1680Sstevel@tonic-gate 1690Sstevel@tonic-gate #define MDDB_GLOBAL_XOR 1234567890 1700Sstevel@tonic-gate 1710Sstevel@tonic-gate #define MDDB_REV_MAJOR (uint_t)0xff00 1720Sstevel@tonic-gate #define MDDB_REV_MINOR (uint_t)0x00ff 1730Sstevel@tonic-gate 1740Sstevel@tonic-gate /* 1750Sstevel@tonic-gate * MDDB_REV_MNMB: 1760Sstevel@tonic-gate * If a MN diskset, master block revision is set to MDDB_REV_MNMB. 1770Sstevel@tonic-gate * Even though the master block structure is no different 1780Sstevel@tonic-gate * for a MN set, setting the revision field to a different 1790Sstevel@tonic-gate * number keeps any pre-MN_diskset code from accessing 1800Sstevel@tonic-gate * this diskset. It also allows for an early determination 1810Sstevel@tonic-gate * of a MN diskset when reading in from disk so that the 1820Sstevel@tonic-gate * proper size locator block and locator names structure 1830Sstevel@tonic-gate * can be read in thus saving time on diskset startup. 1840Sstevel@tonic-gate * Since no change in master block structure, the MDDB_REV_MINOR 1850Sstevel@tonic-gate * portion of the revision was incremented. 1860Sstevel@tonic-gate * 1870Sstevel@tonic-gate * MDDB_REV_MNLB: 1880Sstevel@tonic-gate * If a MN diskset, the locator block structure is a different size in 1890Sstevel@tonic-gate * order to accomodate up to MD_MNMAXSIDES nodes in a diskset 1900Sstevel@tonic-gate * with any nodeid (sideno) allowed. 1910Sstevel@tonic-gate * The revision is set to MDDB_REV_MNLB which is a change of the 1920Sstevel@tonic-gate * MDDB_REV_MAJOR portion of the revision. 1930Sstevel@tonic-gate * 1940Sstevel@tonic-gate * MDDB_REV_MNLN: 1950Sstevel@tonic-gate * If a MN diskset, the locator names is a different size in 1960Sstevel@tonic-gate * order to accomodate up to MD_MNMAXSIDES nodes in a diskset 1970Sstevel@tonic-gate * with any nodeid (sideno) allowed. 1980Sstevel@tonic-gate * The revision is set to MDDB_REV_MNLN which is a change of the 1990Sstevel@tonic-gate * MDDB_REV_MAJOR portion of the revision. 2001623Stw21770 * 2011623Stw21770 * The record blocks have two binary properties. A record block can 2021623Stw21770 * represent either a 32 or 64 bit unit. A record block can also represent 2031623Stw21770 * a traditionally named unit or a friendly named unit. Thus, there are 2041623Stw21770 * minor revisions of record block. 2051623Stw21770 * 2061623Stw21770 * Traditional Friendly 2071623Stw21770 * Name Name 2081623Stw21770 * ----------- -------- 2091623Stw21770 * 32 bit MDDB_REV_RB MDDB_REV_RBFN 2101623Stw21770 * 64 bit MDDB_REV_RB64 MDDB_REV_RB64FN 2110Sstevel@tonic-gate */ 2120Sstevel@tonic-gate 2130Sstevel@tonic-gate #define MDDB_REV_MB (uint_t)0x0201 2140Sstevel@tonic-gate #define MDDB_REV_MNMB (uint_t)0x0202 2150Sstevel@tonic-gate #define MDDB_REV_DB (uint_t)0x0201 2160Sstevel@tonic-gate #define MDDB_REV_LB (uint_t)0x0500 2170Sstevel@tonic-gate #define MDDB_REV_MNLB (uint_t)0x0600 2180Sstevel@tonic-gate #define MDDB_REV_LN (uint_t)0x0100 2190Sstevel@tonic-gate #define MDDB_REV_MNLN (uint_t)0x0300 2200Sstevel@tonic-gate #define MDDB_REV_RB (uint_t)0x0200 2210Sstevel@tonic-gate #define MDDB_REV_RB64 (uint_t)0x0201 2221623Stw21770 #define MDDB_REV_RBFN (uint_t)0x0202 2231623Stw21770 #define MDDB_REV_RB64FN (uint_t)0x0203 2240Sstevel@tonic-gate #define MDDB_REV_DT (uint_t)0x0100 2250Sstevel@tonic-gate #define MDDB_REV_DI (uint_t)0x0100 2260Sstevel@tonic-gate 2271623Stw21770 /* 2281623Stw21770 * Transfer record block friendly name status to unit/hs structure. 2291623Stw21770 */ 230*2077Stw21770 #define MDDB_NOTE_FN(rbv, unv) switch (rbv) { \ 2311623Stw21770 case MDDB_REV_RB: \ 2321623Stw21770 case MDDB_REV_RB64: \ 2331623Stw21770 unv &= ~MD_FN_META_DEV; \ 2341623Stw21770 break; \ 2351623Stw21770 case MDDB_REV_RBFN: \ 2361623Stw21770 case MDDB_REV_RB64FN: \ 2371623Stw21770 unv |= MD_FN_META_DEV; \ 2381623Stw21770 break; \ 2391623Stw21770 } 2401623Stw21770 2410Sstevel@tonic-gate #define MDDB_BSIZE (uint_t)DEV_BSIZE 2420Sstevel@tonic-gate #define MDDB_PREFIXCNT 10 2430Sstevel@tonic-gate #define MDDB_DRVNMCNT 10 2440Sstevel@tonic-gate 2450Sstevel@tonic-gate typedef int mddb_block_t; 2460Sstevel@tonic-gate 2470Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 2480Sstevel@tonic-gate #pragma pack(4) 2490Sstevel@tonic-gate #endif 2500Sstevel@tonic-gate typedef struct md_mnname_suffix { 2510Sstevel@tonic-gate md_name_suffix mn_ln_suffix; 2520Sstevel@tonic-gate uint_t mn_ln_sideno; 2530Sstevel@tonic-gate } md_mnname_suffix_t; 2540Sstevel@tonic-gate 2550Sstevel@tonic-gate typedef struct mddb_ln { 2560Sstevel@tonic-gate int ln_magic; 2570Sstevel@tonic-gate uint_t ln_revision; 2580Sstevel@tonic-gate uint_t ln_checksum; 2590Sstevel@tonic-gate struct timeval32 ln_timestamp; 2600Sstevel@tonic-gate md_name_prefix ln_prefixes[MDDB_PREFIXCNT]; 2610Sstevel@tonic-gate /* Don't change array sizes without changing RNDUP_BLKCNT */ 2620Sstevel@tonic-gate md_name_suffix ln_suffixes[MD_MAXSIDES][MDDB_NLB]; 2630Sstevel@tonic-gate } mddb_ln_t; 2640Sstevel@tonic-gate 2650Sstevel@tonic-gate /* 2660Sstevel@tonic-gate * Locator name structure for MN diskset. Same as for traditional 2670Sstevel@tonic-gate * and local diskset except that more sides are supported and the 2680Sstevel@tonic-gate * side number can be any number since the side number is stored 2690Sstevel@tonic-gate * in the ln_mnsuffixes structure instead of being used as an index 2700Sstevel@tonic-gate * into that array. This means that the whole array may need to be 2710Sstevel@tonic-gate * searched in order to find the correct information given a side number. 2720Sstevel@tonic-gate */ 2730Sstevel@tonic-gate typedef struct mddb_mnln { 2740Sstevel@tonic-gate int ln_magic; 2750Sstevel@tonic-gate uint_t ln_revision; 2760Sstevel@tonic-gate uint_t ln_checksum; 2770Sstevel@tonic-gate struct timeval32 ln_timestamp; 2780Sstevel@tonic-gate md_name_prefix ln_prefixes[MDDB_PREFIXCNT]; 2790Sstevel@tonic-gate /* Don't change array sizes without changing MDDB_MNLNCNT */ 2800Sstevel@tonic-gate md_mnname_suffix_t ln_mnsuffixes[MD_MNMAXSIDES][MDDB_NLB]; 2810Sstevel@tonic-gate } mddb_mnln_t; 2820Sstevel@tonic-gate 2830Sstevel@tonic-gate #define RNDUP_BLKCNT(sz, delta) (((sz) - \ 2840Sstevel@tonic-gate ((delta) * \ 2850Sstevel@tonic-gate ((MD_MAXSIDES - 1) * MDDB_NLB)) + \ 2860Sstevel@tonic-gate MDDB_BSIZE - 1) / MDDB_BSIZE) 2870Sstevel@tonic-gate #define MDDB_LNCNT RNDUP_BLKCNT(sizeof (mddb_ln_t), 0) 2880Sstevel@tonic-gate #define MDDB_LOCAL_LNCNT RNDUP_BLKCNT(sizeof (mddb_ln_t), \ 2890Sstevel@tonic-gate sizeof (md_name_suffix)) 2900Sstevel@tonic-gate 2910Sstevel@tonic-gate #define MDDB_MNLNCNT ((sizeof (mddb_mnln_t) + (MDDB_BSIZE - 1)) \ 2920Sstevel@tonic-gate / MDDB_BSIZE) 2930Sstevel@tonic-gate 2940Sstevel@tonic-gate typedef struct mddb_dt { 2950Sstevel@tonic-gate uint_t dt_mag; 2960Sstevel@tonic-gate uint_t dt_rev; 2970Sstevel@tonic-gate uint_t dt_cks; 2980Sstevel@tonic-gate mddb_dtag_t dt_dtag; 2990Sstevel@tonic-gate } mddb_dt_t; 3000Sstevel@tonic-gate 3010Sstevel@tonic-gate #define MDDB_DT_BYTES (roundup(sizeof (mddb_dt_t), MDDB_BSIZE)) 3020Sstevel@tonic-gate #define MDDB_DT_BLOCKS (btodb(MDDB_DT_BYTES)) 3030Sstevel@tonic-gate 3040Sstevel@tonic-gate typedef union identifier { 3050Sstevel@tonic-gate char serial[MDDB_SN_LEN]; 3060Sstevel@tonic-gate struct timeval32 createtime; 3070Sstevel@tonic-gate } identifier_t; 3080Sstevel@tonic-gate 3090Sstevel@tonic-gate typedef struct mddb_locator { 3100Sstevel@tonic-gate dev32_t l_dev; 3110Sstevel@tonic-gate daddr32_t l_blkno; 3120Sstevel@tonic-gate int l_flags; 3130Sstevel@tonic-gate } mddb_locator_t; 3140Sstevel@tonic-gate 3150Sstevel@tonic-gate typedef struct mddb_sidelocator { 3160Sstevel@tonic-gate uchar_t l_drvnm_index; 3170Sstevel@tonic-gate minor_t l_mnum; 3180Sstevel@tonic-gate } mddb_sidelocator_t; 3190Sstevel@tonic-gate 3200Sstevel@tonic-gate typedef struct mddb_mnsidelocator { 3210Sstevel@tonic-gate uchar_t mnl_drvnm_index; 3220Sstevel@tonic-gate minor_t mnl_mnum; 3230Sstevel@tonic-gate uint_t mnl_sideno; 3240Sstevel@tonic-gate } mddb_mnsidelocator_t; 3250Sstevel@tonic-gate 3260Sstevel@tonic-gate typedef struct mddb_drvnm { 3270Sstevel@tonic-gate uchar_t dn_len; 3280Sstevel@tonic-gate char dn_data[MD_MAXDRVNM]; 3290Sstevel@tonic-gate } mddb_drvnm_t; 3300Sstevel@tonic-gate 3310Sstevel@tonic-gate /* 3320Sstevel@tonic-gate * Locator Block Device ID Information 3330Sstevel@tonic-gate * Several device id's may share one disk block in an effort to 3340Sstevel@tonic-gate * conserve used replica space. 3350Sstevel@tonic-gate */ 3360Sstevel@tonic-gate typedef struct mddb_did_info { 3370Sstevel@tonic-gate uint_t info_flags; /* MDDB Device ID flags */ 3380Sstevel@tonic-gate uint_t info_firstblk; /* Device ID Start Block */ 3390Sstevel@tonic-gate uint_t info_blkcnt; /* Device ID Block Count */ 3400Sstevel@tonic-gate uint_t info_offset; /* Device ID offset w/i Block */ 3410Sstevel@tonic-gate uint_t info_length; /* Device ID Length */ 3420Sstevel@tonic-gate uint_t info_checksum; /* Device ID Checksum */ 3430Sstevel@tonic-gate char info_minor_name[32]; /* Minor name of lb dev */ 3440Sstevel@tonic-gate } mddb_did_info_t; 3450Sstevel@tonic-gate 3460Sstevel@tonic-gate typedef struct mddb_did_blk { 3470Sstevel@tonic-gate int blk_magic; /* used for verification */ 3480Sstevel@tonic-gate uint_t blk_revision; /* used for verification */ 3490Sstevel@tonic-gate int blk_checksum; /* used for verification */ 3500Sstevel@tonic-gate uint_t blk_commitcnt; /* matches LB's commitcnt */ 3510Sstevel@tonic-gate mddb_did_info_t blk_info[MDDB_NLB]; 3520Sstevel@tonic-gate } mddb_did_blk_t; 3530Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 3540Sstevel@tonic-gate #pragma pack() 3550Sstevel@tonic-gate #endif 3560Sstevel@tonic-gate 3570Sstevel@tonic-gate #define MDDB_DID_BYTES (roundup(sizeof (mddb_did_blk_t), MDDB_BSIZE)) 3580Sstevel@tonic-gate #define MDDB_DID_BLOCKS (btodb(MDDB_DID_BYTES)) 3590Sstevel@tonic-gate 3600Sstevel@tonic-gate /* 3610Sstevel@tonic-gate * Device ID Disk Blocks. 3620Sstevel@tonic-gate * Incore linked list of disk blocks containing device IDs. 3630Sstevel@tonic-gate * The list is built when reading in the mddb_did_blk structure and 3640Sstevel@tonic-gate * when reading in the actual disk blocks containing device ids. 3650Sstevel@tonic-gate * This list is used to easily write out all disk blocks containing 3660Sstevel@tonic-gate * device ids. 3670Sstevel@tonic-gate */ 3680Sstevel@tonic-gate typedef struct mddb_did_db { 3690Sstevel@tonic-gate uint_t db_firstblk; /* Disk Block's logical addr */ 3700Sstevel@tonic-gate uint_t db_blkcnt; /* Contig Disk Block Count */ 3710Sstevel@tonic-gate caddr_t db_ptr; /* Ptr to incore Block(s) */ 3720Sstevel@tonic-gate struct mddb_did_db *db_next; /* Ptr to next in list */ 3730Sstevel@tonic-gate } mddb_did_db_t; 3740Sstevel@tonic-gate 3750Sstevel@tonic-gate /* 3760Sstevel@tonic-gate * Device ID Free List. 3770Sstevel@tonic-gate * Incore linked list of free space in disk blocks containing device IDs. 3780Sstevel@tonic-gate * Used to manage placement of device IDs in disk blocks. 3790Sstevel@tonic-gate * All disk blocks on free list are also in linked list of disk block 3800Sstevel@tonic-gate * containing device IDs (mddb_did_db_t). 3810Sstevel@tonic-gate */ 3820Sstevel@tonic-gate typedef struct mddb_did_free { 3830Sstevel@tonic-gate uint_t free_blk; /* Disk Block's logical addr */ 3840Sstevel@tonic-gate uint_t free_offset; /* offset of free space */ 3850Sstevel@tonic-gate uint_t free_length; /* length of free space */ 3860Sstevel@tonic-gate struct mddb_did_free *free_next; /* Ptr to next in list */ 3870Sstevel@tonic-gate } mddb_did_free_t; 3880Sstevel@tonic-gate 3890Sstevel@tonic-gate /* 3900Sstevel@tonic-gate * Device ID Incore Area 3910Sstevel@tonic-gate * Contains pointer to Device ID Disk Block list and 3920Sstevel@tonic-gate * Device ID Free List. 3930Sstevel@tonic-gate * Also contains incore array of pointers to device IDs. Pointers 3940Sstevel@tonic-gate * point into the device ID Disk Block list and are used as a 3950Sstevel@tonic-gate * shortcut to find incore device IDs. 3960Sstevel@tonic-gate */ 3970Sstevel@tonic-gate typedef struct mddb_did_ic { 3980Sstevel@tonic-gate mddb_did_blk_t *did_ic_blkp; 3990Sstevel@tonic-gate mddb_did_db_t *did_ic_dbp; 4000Sstevel@tonic-gate mddb_did_free_t *did_ic_freep; 4010Sstevel@tonic-gate ddi_devid_t did_ic_devid[MDDB_NLB]; /* Ptr to device IDs */ 4020Sstevel@tonic-gate } mddb_did_ic_t; 4030Sstevel@tonic-gate 4040Sstevel@tonic-gate /* 4050Sstevel@tonic-gate * Locator Block (LB): 4060Sstevel@tonic-gate * - Are fixed size, but the size is different 4070Sstevel@tonic-gate * for local/shared set db replicas. 4080Sstevel@tonic-gate * - All LB's start at logical block 0. 4090Sstevel@tonic-gate * - After a replica quorum is found, there is 4100Sstevel@tonic-gate * is only one incore copy of the LB. 4110Sstevel@tonic-gate * - LB's are only written when replicas are added, deleted, or errored. 4120Sstevel@tonic-gate * - LB's provide information about other replica's and their state. 4130Sstevel@tonic-gate */ 4140Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 4150Sstevel@tonic-gate #pragma pack(4) 4160Sstevel@tonic-gate #endif 4170Sstevel@tonic-gate typedef struct mddb_lb { 4180Sstevel@tonic-gate int lb_magic; /* used for verification */ 4190Sstevel@tonic-gate uint_t lb_revision; /* used for verification */ 4200Sstevel@tonic-gate int lb_checksum; /* used for verification */ 4210Sstevel@tonic-gate uint_t lb_commitcnt; /* IMPORTANT */ 4220Sstevel@tonic-gate struct timeval32 lb_timestamp; /* informative only */ 4230Sstevel@tonic-gate int lb_loccnt; /* used for verification */ 4240Sstevel@tonic-gate identifier_t lb_ident; /* used for verification */ 4250Sstevel@tonic-gate uint_t lb_flags; /* flags describing LB */ 4260Sstevel@tonic-gate uint_t lb_spare[8]; /* Spare/Pad */ 4270Sstevel@tonic-gate mddb_block_t lb_didfirstblk; /* Devid Array Start Block */ 4280Sstevel@tonic-gate mddb_block_t lb_didblkcnt; /* Devid Array Number Blocks */ 4290Sstevel@tonic-gate mddb_block_t lb_dtfirstblk; /* Data Tag Start Block */ 4300Sstevel@tonic-gate mddb_block_t lb_dtblkcnt; /* Data Tag Number Block(s) */ 4310Sstevel@tonic-gate struct timeval32 lb_inittime; /* creation of database */ 4320Sstevel@tonic-gate set_t lb_setno; /* used for verification */ 4330Sstevel@tonic-gate mddb_block_t lb_blkcnt; /* used for verification */ 4340Sstevel@tonic-gate mddb_block_t lb_lnfirstblk; 4350Sstevel@tonic-gate mddb_block_t lb_lnblkcnt; 4360Sstevel@tonic-gate mddb_block_t lb_dbfirstblk; 4370Sstevel@tonic-gate mddb_drvnm_t lb_drvnm[MDDB_DRVNMCNT]; 4380Sstevel@tonic-gate mddb_locator_t lb_locators[MDDB_NLB]; 4390Sstevel@tonic-gate /* Don't change array sizes without changing RNDUP_BLKCNT */ 4400Sstevel@tonic-gate mddb_sidelocator_t lb_sidelocators[MD_MAXSIDES][MDDB_NLB]; 4410Sstevel@tonic-gate } mddb_lb_t; 4420Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 4430Sstevel@tonic-gate #pragma pack() 4440Sstevel@tonic-gate #endif 4450Sstevel@tonic-gate 4460Sstevel@tonic-gate /* 4470Sstevel@tonic-gate * Locator block structure for MN diskset. Same as for traditional 4480Sstevel@tonic-gate * and local diskset except that more sides are supported and the 4490Sstevel@tonic-gate * side number can be any number since the side number is stored 4500Sstevel@tonic-gate * in the lb_mnsidelocators structure instead of being used as an index 4510Sstevel@tonic-gate * into that array. This means that the whole array may need to be 4520Sstevel@tonic-gate * searched in order to find the correct information given a side number. 4530Sstevel@tonic-gate */ 4540Sstevel@tonic-gate typedef struct mddb_mnlb { 4550Sstevel@tonic-gate int lb_magic; /* used for verification */ 4560Sstevel@tonic-gate uint_t lb_revision; /* used for verification */ 4570Sstevel@tonic-gate int lb_checksum; /* used for verification */ 4580Sstevel@tonic-gate uint_t lb_commitcnt; /* IMPORTANT */ 4590Sstevel@tonic-gate struct timeval32 lb_timestamp; /* informative only */ 4600Sstevel@tonic-gate int lb_loccnt; /* used for verification */ 4610Sstevel@tonic-gate identifier_t lb_ident; /* used for verification */ 4620Sstevel@tonic-gate uint_t lb_flags; /* flags describing LB */ 4630Sstevel@tonic-gate uint_t lb_spare[8]; /* Spare/Pad */ 4640Sstevel@tonic-gate mddb_block_t lb_didfirstblk; /* Devid Array Start Block */ 4650Sstevel@tonic-gate mddb_block_t lb_didblkcnt; /* Devid Array Number Blocks */ 4660Sstevel@tonic-gate mddb_block_t lb_dtfirstblk; /* Data Tag Start Block */ 4670Sstevel@tonic-gate mddb_block_t lb_dtblkcnt; /* Data Tag Number Block(s) */ 4680Sstevel@tonic-gate struct timeval32 lb_inittime; /* creation of database */ 4690Sstevel@tonic-gate set_t lb_setno; /* used for verification */ 4700Sstevel@tonic-gate mddb_block_t lb_blkcnt; /* used for verification */ 4710Sstevel@tonic-gate mddb_block_t lb_lnfirstblk; 4720Sstevel@tonic-gate mddb_block_t lb_lnblkcnt; 4730Sstevel@tonic-gate mddb_block_t lb_dbfirstblk; 4740Sstevel@tonic-gate mddb_drvnm_t lb_drvnm[MDDB_DRVNMCNT]; 4750Sstevel@tonic-gate mddb_locator_t lb_locators[MDDB_NLB]; 4760Sstevel@tonic-gate /* Don't change array sizes without changing MDDB_MNLBCNT */ 4770Sstevel@tonic-gate mddb_mnsidelocator_t lb_mnsidelocators[MD_MNMAXSIDES][MDDB_NLB]; 4780Sstevel@tonic-gate } mddb_mnlb_t; 4790Sstevel@tonic-gate 4800Sstevel@tonic-gate 4810Sstevel@tonic-gate #define MDDB_LBCNT RNDUP_BLKCNT(sizeof (mddb_lb_t), 0) 4820Sstevel@tonic-gate #define MDDB_LOCAL_LBCNT RNDUP_BLKCNT(sizeof (mddb_lb_t), \ 4830Sstevel@tonic-gate sizeof (mddb_sidelocator_t)) 4840Sstevel@tonic-gate 4850Sstevel@tonic-gate #define MDDB_MNLBCNT ((sizeof (mddb_mnlb_t) + (MDDB_BSIZE - 1)) \ 4860Sstevel@tonic-gate / MDDB_BSIZE) 4870Sstevel@tonic-gate 4880Sstevel@tonic-gate typedef struct mddb_map { 4890Sstevel@tonic-gate daddr32_t m_consecutive; 4900Sstevel@tonic-gate daddr32_t m_firstblk; 4910Sstevel@tonic-gate } mddb_map_t; 4920Sstevel@tonic-gate 4930Sstevel@tonic-gate /* 4940Sstevel@tonic-gate * Master block(s) (MB) 4950Sstevel@tonic-gate * - Are written by userland; Never by the driver! 4960Sstevel@tonic-gate * - Each replica has there own master blocks, 4970Sstevel@tonic-gate * the master block(s) are not shared. 4980Sstevel@tonic-gate * - MB's are not in the logical block address space of the database. 4990Sstevel@tonic-gate * - MB's are a fixed size record (MDDB_BSIZE) 5000Sstevel@tonic-gate * - MB's provide the logical to physical block translation, 5010Sstevel@tonic-gate * for their replica. 5020Sstevel@tonic-gate */ 5030Sstevel@tonic-gate typedef struct mddb_mb { 5040Sstevel@tonic-gate int mb_magic; /* used for verification */ 5050Sstevel@tonic-gate uint_t mb_revision; /* used for verification */ 5060Sstevel@tonic-gate uint_t mb_checksum; /* used for verification */ 5070Sstevel@tonic-gate #ifdef _LP64 5080Sstevel@tonic-gate uint32_t mb_next; /* incore to next mb */ 5090Sstevel@tonic-gate #else 5100Sstevel@tonic-gate struct mddb_mb *mb_next; /* incore to next mb */ 5110Sstevel@tonic-gate #endif /* _LP64 */ 5120Sstevel@tonic-gate daddr32_t mb_nextblk; /* block # for next mb */ 5130Sstevel@tonic-gate md_timeval32_t mb_timestamp; /* timestamp */ 5140Sstevel@tonic-gate daddr32_t mb_blkcnt; /* size of blkmap */ 5150Sstevel@tonic-gate daddr32_t mb_blkno; /* physical loc. for this MB */ 5160Sstevel@tonic-gate set_t mb_setno; /* used for verification */ 5170Sstevel@tonic-gate struct timeval32 mb_setcreatetime; /* set creation timestamp */ 5180Sstevel@tonic-gate int spares[7]; 5190Sstevel@tonic-gate mddb_map_t mb_blkmap; /* logical->physical blk map */ 5200Sstevel@tonic-gate int mb_devid_magic; /* verify devid in mb */ 5210Sstevel@tonic-gate short mb_devid_len; /* len of following devid */ 5220Sstevel@tonic-gate char mb_devid[1]; /* devid byte array */ 5230Sstevel@tonic-gate } mddb_mb_t; 5240Sstevel@tonic-gate 5250Sstevel@tonic-gate /* 5260Sstevel@tonic-gate * In-core version of mddb_mb. It is known that the mddb_mb is 512 bytes on 5270Sstevel@tonic-gate * disk, really, and so this structure is 512 + sizeof(struct mddb_mb_ic *) 5280Sstevel@tonic-gate */ 5290Sstevel@tonic-gate #define MDDB_IC_BSIZE (MDDB_BSIZE + sizeof (struct mddb_mb_ic *)) 5300Sstevel@tonic-gate typedef struct mddb_mb_ic { 5310Sstevel@tonic-gate struct mddb_mb_ic *mbi_next; 5320Sstevel@tonic-gate struct mddb_mb mbi_mddb_mb; 5330Sstevel@tonic-gate } mddb_mb_ic_t; 5340Sstevel@tonic-gate 5350Sstevel@tonic-gate 5360Sstevel@tonic-gate /* 5370Sstevel@tonic-gate * there can be no address in record block. The checksum must 5380Sstevel@tonic-gate * stay the same where ever the record is in memory. Many 5390Sstevel@tonic-gate * things depend on this. Also the timestamp is the time the the 5400Sstevel@tonic-gate * record was committed not the time it was written to a particular 5410Sstevel@tonic-gate * device. 5420Sstevel@tonic-gate * 5430Sstevel@tonic-gate * Old definition of mddb_rb, for 32-bit apps and libraries 5440Sstevel@tonic-gate */ 5450Sstevel@tonic-gate typedef struct mddb_rb { 5460Sstevel@tonic-gate uint_t rb_magic; 5470Sstevel@tonic-gate uint_t rb_revision; 5480Sstevel@tonic-gate uint_t rb_checksum; 5490Sstevel@tonic-gate uint_t rb_checksum_fiddle; 5500Sstevel@tonic-gate uint_t rb_private; 5510Sstevel@tonic-gate void *rb_userdata; 5520Sstevel@tonic-gate uint_t rb_commitcnt; 5530Sstevel@tonic-gate uint_t rb_spare[1]; 5540Sstevel@tonic-gate struct timeval32 rb_timestamp; 5550Sstevel@tonic-gate int rb_data[1]; 5560Sstevel@tonic-gate } mddb_rb_t; 5570Sstevel@tonic-gate 5580Sstevel@tonic-gate /* This is, and always will be, the on-disk version of mddb_rb */ 5590Sstevel@tonic-gate typedef struct mddb_rb32 { 5600Sstevel@tonic-gate uint_t rb_magic; 5610Sstevel@tonic-gate uint_t rb_revision; 5620Sstevel@tonic-gate uint_t rb_checksum; 5630Sstevel@tonic-gate uint_t rb_checksum_fiddle; 5640Sstevel@tonic-gate uint_t rb_private; 5650Sstevel@tonic-gate uint32_t rb_userdata; 5660Sstevel@tonic-gate uint_t rb_commitcnt; 5670Sstevel@tonic-gate uint_t rb_spare[1]; 5680Sstevel@tonic-gate struct timeval32 rb_timestamp; 5690Sstevel@tonic-gate int rb_data[1]; 5700Sstevel@tonic-gate } mddb_rb32_t; 5710Sstevel@tonic-gate 5720Sstevel@tonic-gate /* 5730Sstevel@tonic-gate * directory entries 5740Sstevel@tonic-gate */ 5750Sstevel@tonic-gate typedef struct mddb_optinfo { 5760Sstevel@tonic-gate int o_li; 5770Sstevel@tonic-gate int o_flags; 5780Sstevel@tonic-gate } mddb_optinfo_t; 5790Sstevel@tonic-gate 5800Sstevel@tonic-gate /* Old definition of mddb_de, for 32-bit apps and libraries */ 5810Sstevel@tonic-gate typedef struct mddb_de { 5820Sstevel@tonic-gate struct mddb_de *de_next; 5830Sstevel@tonic-gate mddb_rb_t *de_rb; 5840Sstevel@tonic-gate mddb_recid_t de_recid; 5850Sstevel@tonic-gate mddb_type_t de_type1; 5860Sstevel@tonic-gate uint_t de_type2; 5870Sstevel@tonic-gate uint_t de_reqsize; 5880Sstevel@tonic-gate uint_t de_recsize; 5890Sstevel@tonic-gate mddb_block_t de_blkcount; 5900Sstevel@tonic-gate uint_t de_flags; 5910Sstevel@tonic-gate mddb_optinfo_t de_optinfo[2]; 5920Sstevel@tonic-gate mddb_block_t de_blks[1]; 5930Sstevel@tonic-gate } mddb_de_t; 5940Sstevel@tonic-gate 5950Sstevel@tonic-gate /* 5960Sstevel@tonic-gate * In core version of mddb_de, includes pointer for mddb_rb32_t user data 5970Sstevel@tonic-gate * mddb_rb32_t is used incore 5980Sstevel@tonic-gate */ 5990Sstevel@tonic-gate typedef struct mddb_de_ic { 6000Sstevel@tonic-gate void *de_rb_userdata; 6010Sstevel@tonic-gate void *de_rb_userdata_ic; 6020Sstevel@tonic-gate uint_t de_owner_nodeid; 6030Sstevel@tonic-gate struct mddb_de_ic *de_next; 6040Sstevel@tonic-gate mddb_rb32_t *de_rb; 6050Sstevel@tonic-gate mddb_recid_t de_recid; 6060Sstevel@tonic-gate mddb_type_t de_type1; 6070Sstevel@tonic-gate uint_t de_type2; 6080Sstevel@tonic-gate size_t de_reqsize; 6090Sstevel@tonic-gate size_t de_icreqsize; 6100Sstevel@tonic-gate size_t de_recsize; 6110Sstevel@tonic-gate uint_t de_blkcount; 6120Sstevel@tonic-gate uint_t de_flags; 6130Sstevel@tonic-gate mddb_optinfo_t de_optinfo[2]; 6140Sstevel@tonic-gate mddb_block_t de_blks[1]; 6150Sstevel@tonic-gate } mddb_de_ic_t; 6160Sstevel@tonic-gate 6170Sstevel@tonic-gate typedef struct mddb_db { 6180Sstevel@tonic-gate uint_t db_magic; 6190Sstevel@tonic-gate uint_t db_revision; 6200Sstevel@tonic-gate uint_t db_checksum; 6210Sstevel@tonic-gate mddb_block_t db_blknum; 6220Sstevel@tonic-gate struct mddb_db *db_next; 6230Sstevel@tonic-gate mddb_block_t db_nextblk; 6240Sstevel@tonic-gate struct timeval32 db_timestamp; 6250Sstevel@tonic-gate uint_t db_recsum; 6260Sstevel@tonic-gate #ifdef _KERNEL 6270Sstevel@tonic-gate mddb_de_ic_t *db_firstentry; 6280Sstevel@tonic-gate #else 6290Sstevel@tonic-gate mddb_de_t *db_firstentry; 6300Sstevel@tonic-gate #endif 6310Sstevel@tonic-gate } mddb_db_t; 6320Sstevel@tonic-gate 6330Sstevel@tonic-gate /* 6340Sstevel@tonic-gate * This is, and always will be, the on-disk version of mddb_de 6350Sstevel@tonic-gate * When mddb_de32 is read in it is converted into mddb_de_ic 6360Sstevel@tonic-gate */ 6370Sstevel@tonic-gate typedef struct mddb_de32 { 6380Sstevel@tonic-gate uint32_t de32_next; 6390Sstevel@tonic-gate uint32_t de32_rb; 6400Sstevel@tonic-gate mddb_recid_t de32_recid; 6410Sstevel@tonic-gate mddb_type_t de32_type1; 6420Sstevel@tonic-gate uint_t de32_type2; 6430Sstevel@tonic-gate uint_t de32_reqsize; 6440Sstevel@tonic-gate uint_t de32_recsize; 6450Sstevel@tonic-gate mddb_block_t de32_blkcount; 6460Sstevel@tonic-gate uint_t de32_flags; 6470Sstevel@tonic-gate mddb_optinfo_t de32_optinfo[2]; 6480Sstevel@tonic-gate mddb_block_t de32_blks[1]; 6490Sstevel@tonic-gate } mddb_de32_t; 6500Sstevel@tonic-gate 6510Sstevel@tonic-gate /* 6520Sstevel@tonic-gate * This is, and always will be, the on-disk version of mddb_db 6530Sstevel@tonic-gate * When mddb_db32 is read in it is converted into mddb_db 6540Sstevel@tonic-gate * To minimize impact on mddb format mddb_db fileds remain intact 6550Sstevel@tonic-gate */ 6560Sstevel@tonic-gate typedef struct mddb_db32 { 6570Sstevel@tonic-gate uint_t db32_magic; 6580Sstevel@tonic-gate uint_t db32_revision; 6590Sstevel@tonic-gate uint_t db32_checksum; 6600Sstevel@tonic-gate mddb_block_t db32_blknum; 6610Sstevel@tonic-gate uint32_t db32_next; 6620Sstevel@tonic-gate mddb_block_t db32_nextblk; 6630Sstevel@tonic-gate struct timeval32 db32_timestamp; 6640Sstevel@tonic-gate uint_t db32_recsum; 6650Sstevel@tonic-gate uint32_t db32_firstentry; 6660Sstevel@tonic-gate } mddb_db32_t; 6670Sstevel@tonic-gate 6680Sstevel@tonic-gate #define de32tode(from, to) \ 6690Sstevel@tonic-gate { \ 6700Sstevel@tonic-gate int i; \ 6710Sstevel@tonic-gate to->de_rb_userdata = NULL; \ 6720Sstevel@tonic-gate to->de_owner_nodeid = MD_MN_INVALID_NID; \ 6730Sstevel@tonic-gate to->de_next = (struct mddb_de_ic *)(uintptr_t)from->de32_next; \ 6740Sstevel@tonic-gate to->de_rb = (mddb_rb32_t *)(uintptr_t)from->de32_rb; \ 6750Sstevel@tonic-gate to->de_recid = from->de32_recid; \ 6760Sstevel@tonic-gate to->de_type1 = from->de32_type1; \ 6770Sstevel@tonic-gate to->de_type2 = from->de32_type2; \ 6780Sstevel@tonic-gate to->de_reqsize = from->de32_reqsize; \ 6790Sstevel@tonic-gate to->de_recsize = from->de32_recsize; \ 6800Sstevel@tonic-gate to->de_blkcount = from->de32_blkcount; \ 6810Sstevel@tonic-gate to->de_flags = from->de32_flags; \ 6820Sstevel@tonic-gate to->de_optinfo[0] = from->de32_optinfo[0]; \ 6830Sstevel@tonic-gate to->de_optinfo[1] = from->de32_optinfo[1]; \ 6840Sstevel@tonic-gate for (i = 0; i < from->de32_blkcount; i++) \ 6850Sstevel@tonic-gate to->de_blks[i] = from->de32_blks[i]; \ 6860Sstevel@tonic-gate } 6870Sstevel@tonic-gate 6880Sstevel@tonic-gate #define detode32(from, to) \ 6890Sstevel@tonic-gate { \ 6900Sstevel@tonic-gate int i; \ 6910Sstevel@tonic-gate to->de32_next = (uint32_t)(uintptr_t)from->de_next; \ 6920Sstevel@tonic-gate to->de32_rb = (uint32_t)(uintptr_t)from->de_rb; \ 6930Sstevel@tonic-gate to->de32_recid = from->de_recid; \ 6940Sstevel@tonic-gate to->de32_type1 = from->de_type1; \ 6950Sstevel@tonic-gate to->de32_type2 = from->de_type2; \ 6960Sstevel@tonic-gate to->de32_reqsize = from->de_reqsize; \ 6970Sstevel@tonic-gate to->de32_recsize = from->de_recsize; \ 6980Sstevel@tonic-gate to->de32_blkcount = from->de_blkcount; \ 6990Sstevel@tonic-gate to->de32_flags = from->de_flags; \ 7000Sstevel@tonic-gate to->de32_optinfo[0] = from->de_optinfo[0]; \ 7010Sstevel@tonic-gate to->de32_optinfo[1] = from->de_optinfo[1]; \ 7020Sstevel@tonic-gate for (i = 0; i < from->de_blkcount; i++) \ 7030Sstevel@tonic-gate to->de32_blks[i] = from->de_blks[i]; \ 7040Sstevel@tonic-gate } 7050Sstevel@tonic-gate 7060Sstevel@tonic-gate #define db32todb(from, to) \ 7070Sstevel@tonic-gate to->db_magic = from->db32_magic; \ 7080Sstevel@tonic-gate to->db_revision = from->db32_revision; \ 7090Sstevel@tonic-gate to->db_checksum = from->db32_checksum; \ 7100Sstevel@tonic-gate to->db_blknum = from->db32_blknum; \ 7110Sstevel@tonic-gate to->db_next = (struct mddb_db *)(uintptr_t)from->db32_next; \ 7120Sstevel@tonic-gate to->db_nextblk = from->db32_nextblk; \ 7130Sstevel@tonic-gate to->db_timestamp = from->db32_timestamp; \ 7140Sstevel@tonic-gate to->db_recsum = from->db32_recsum; \ 7150Sstevel@tonic-gate to->db_firstentry = (mddb_de_ic_t *)(uintptr_t)from->db32_firstentry; 7160Sstevel@tonic-gate 7170Sstevel@tonic-gate #define dbtodb32(from, to) \ 7180Sstevel@tonic-gate to->db32_magic = from->db_magic; \ 7190Sstevel@tonic-gate to->db32_revision = from->db_revision; \ 7200Sstevel@tonic-gate to->db32_checksum = from->db_checksum; \ 7210Sstevel@tonic-gate to->db32_blknum = from->db_blknum; \ 7220Sstevel@tonic-gate to->db32_next = (uint32_t)(uintptr_t)from->db_next; \ 7230Sstevel@tonic-gate to->db32_nextblk = from->db_nextblk; \ 7240Sstevel@tonic-gate to->db32_timestamp = from->db_timestamp; \ 7250Sstevel@tonic-gate to->db32_recsum = from->db_recsum; \ 7260Sstevel@tonic-gate to->db32_firstentry = (uint32_t)(uintptr_t)from->db_firstentry; 7270Sstevel@tonic-gate 7280Sstevel@tonic-gate /* 7290Sstevel@tonic-gate * information about a replica of the data base 7300Sstevel@tonic-gate */ 7310Sstevel@tonic-gate typedef struct mddb_ri { 7320Sstevel@tonic-gate struct mddb_ri *ri_next; 7330Sstevel@tonic-gate uint_t ri_flags; 7340Sstevel@tonic-gate uint_t ri_commitcnt; 7350Sstevel@tonic-gate int ri_transplant; 7360Sstevel@tonic-gate md_dev64_t ri_dev; 7370Sstevel@tonic-gate daddr32_t ri_blkno; 7380Sstevel@tonic-gate char ri_driver[16]; 7390Sstevel@tonic-gate mddb_mb_ic_t *ri_mbip; 7400Sstevel@tonic-gate mddb_lb_t *ri_lbp; 7410Sstevel@tonic-gate mddb_dt_t *ri_dtp; 7420Sstevel@tonic-gate mddb_did_ic_t *ri_did_icp; 7430Sstevel@tonic-gate ddi_devid_t ri_devid; 7440Sstevel@tonic-gate ddi_devid_t ri_old_devid; 7450Sstevel@tonic-gate char ri_minor_name[MDDB_MINOR_NAME_MAX]; 7460Sstevel@tonic-gate char ri_devname[MAXPATHLEN]; 7470Sstevel@tonic-gate } mddb_ri_t; 7480Sstevel@tonic-gate 7490Sstevel@tonic-gate typedef struct mddb_bf { 7500Sstevel@tonic-gate struct mddb_bf *bf_next; 7510Sstevel@tonic-gate mddb_locator_t *bf_locator; 7520Sstevel@tonic-gate buf_t bf_buf; 7530Sstevel@tonic-gate } mddb_bf_t; 7540Sstevel@tonic-gate 7550Sstevel@tonic-gate /* 7560Sstevel@tonic-gate * Information for sets of databases (which include replicas) 7570Sstevel@tonic-gate */ 7580Sstevel@tonic-gate #define MDDB_BITSRECID 31 7590Sstevel@tonic-gate #define MDDB_SETSHIFT (MDDB_BITSRECID - MD_BITSSET) 7600Sstevel@tonic-gate #define MDDB_SETMASK (MD_SETMASK << MDDB_SETSHIFT) 7610Sstevel@tonic-gate #define MDDB_RECIDMASK ((1 << MDDB_SETSHIFT) - 1) 7620Sstevel@tonic-gate 7630Sstevel@tonic-gate #define DBSET(id) (((id) & MDDB_SETMASK) >> MDDB_SETSHIFT) 7640Sstevel@tonic-gate #define DBID(id) ((id) & MDDB_RECIDMASK) 7650Sstevel@tonic-gate #define MAKERECID(s, i) ((((s) << MDDB_SETSHIFT) & MDDB_SETMASK) | \ 7660Sstevel@tonic-gate ((i) & MDDB_RECIDMASK)) 7670Sstevel@tonic-gate 7680Sstevel@tonic-gate #define MDDB_PARSE_LOCBLK 0x00000001 7690Sstevel@tonic-gate #define MDDB_PARSE_LOCNM 0x00000002 7700Sstevel@tonic-gate #define MDDB_PARSE_OPTRECS 0x00000004 7710Sstevel@tonic-gate #define MDDB_PARSE_MASK 0x0000000F 7720Sstevel@tonic-gate 7730Sstevel@tonic-gate 7740Sstevel@tonic-gate #define MDDB_BLOCK_PARSE 0x00000001 /* Block sending parse msgs */ 7750Sstevel@tonic-gate #define MDDB_UNBLOCK_PARSE 0x00000002 /* Unblock sending parse msgs */ 7760Sstevel@tonic-gate 7770Sstevel@tonic-gate /* 7780Sstevel@tonic-gate * We need to keep s_ident and s_inittime 32 bit. They are used in mddb_lb 7790Sstevel@tonic-gate */ 7800Sstevel@tonic-gate typedef struct mddb_set { 7810Sstevel@tonic-gate uint_t s_setno; /* set number */ 7820Sstevel@tonic-gate uint_t s_sideno; /* side number */ 7830Sstevel@tonic-gate identifier_t s_ident; /* set identifier */ 7840Sstevel@tonic-gate char *s_setname; /* set name */ 7850Sstevel@tonic-gate mddb_mb_ic_t **s_mbiarray; /* master blocks array */ 7860Sstevel@tonic-gate mddb_db_t *s_dbp; /* directory block */ 7870Sstevel@tonic-gate mddb_lb_t *s_lbp; /* locator block */ 7880Sstevel@tonic-gate /* May be cast to mddb_mnlb_t */ 7890Sstevel@tonic-gate /* if accessing sidenames in */ 7900Sstevel@tonic-gate /* MN diskset */ 7910Sstevel@tonic-gate mddb_ln_t *s_lnp; /* locator names block */ 7920Sstevel@tonic-gate /* May be cast to mddb_mnln_t */ 7930Sstevel@tonic-gate /* if accessing sidenames in */ 7940Sstevel@tonic-gate /* MN diskset */ 7950Sstevel@tonic-gate mddb_dtag_lst_t *s_dtlp; /* List of data tags found */ 7960Sstevel@tonic-gate mddb_did_ic_t *s_did_icp; /* Device ID incore area */ 7970Sstevel@tonic-gate mddb_ri_t *s_rip; /* replicas incore list */ 7980Sstevel@tonic-gate int s_freeblkcnt; /* visable for test code */ 7990Sstevel@tonic-gate int s_totalblkcnt; /* visable for test code */ 8000Sstevel@tonic-gate int s_mn_parseflags; /* mddb parse flags for MNset */ 8010Sstevel@tonic-gate int s_mn_parseflags_sending; /* parse flgs sent to slaves */ 8020Sstevel@tonic-gate uchar_t *s_freebitmap; /* free blocks bitmap */ 8030Sstevel@tonic-gate uint_t s_freebitmapsize; /* size of bitmap */ 8040Sstevel@tonic-gate struct timeval32 s_inittime; /* timestamp set created */ 8050Sstevel@tonic-gate mddb_recid_t s_zombie; /* zombie record - createrec */ 8060Sstevel@tonic-gate int s_staledeletes; /* number of stale deleterec */ 8070Sstevel@tonic-gate int s_optcmtcnt; /* Following are opt. record */ 8080Sstevel@tonic-gate int s_opthavelck; /* bookkeeping records ... */ 8090Sstevel@tonic-gate int s_optwantlck; 8100Sstevel@tonic-gate kcondvar_t s_optwantlck_cv; 8110Sstevel@tonic-gate int s_optwaiterr; 8120Sstevel@tonic-gate int s_opthungerr; 8130Sstevel@tonic-gate kcondvar_t s_opthungerr_cv; 8140Sstevel@tonic-gate int s_opthavequeuinglck; 8150Sstevel@tonic-gate int s_optwantqueuinglck; 8160Sstevel@tonic-gate kcondvar_t s_optqueuing_cv; 8170Sstevel@tonic-gate ulong_t s_bufmisses; 8180Sstevel@tonic-gate mddb_bf_t *s_freebufhead; 8190Sstevel@tonic-gate int s_bufwakeup; 8200Sstevel@tonic-gate kcondvar_t s_buf_cv; 8210Sstevel@tonic-gate size_t s_databuffer_size; 8220Sstevel@tonic-gate void *s_databuffer; 8230Sstevel@tonic-gate int s_singlelockgotten; 8240Sstevel@tonic-gate int s_singlelockwanted; 8250Sstevel@tonic-gate kcondvar_t s_single_thread_cv; 8260Sstevel@tonic-gate md_hi_arr_t s_med; 8270Sstevel@tonic-gate } mddb_set_t; 8280Sstevel@tonic-gate 8290Sstevel@tonic-gate #ifndef MDDB_FAKE 8300Sstevel@tonic-gate #ifdef _KERNEL 8310Sstevel@tonic-gate /* md_mddb.c */ 8320Sstevel@tonic-gate extern uint_t mddb_lb_did_convert(mddb_set_t *, 8330Sstevel@tonic-gate uint_t, uint_t *); 8340Sstevel@tonic-gate extern void mddb_locatorblock2splitname(mddb_ln_t *, 8350Sstevel@tonic-gate int, side_t, md_splitname *); 8360Sstevel@tonic-gate extern int mddb_configure(mddb_cfgcmd_t, 8370Sstevel@tonic-gate struct mddb_config *); 8380Sstevel@tonic-gate extern mddb_recid_t mddb_getnextrec(mddb_recid_t, 8390Sstevel@tonic-gate mddb_type_t, uint_t); 8400Sstevel@tonic-gate extern int mddb_getoptloc(mddb_optloc_t *); 8410Sstevel@tonic-gate extern void *mddb_getrecaddr(mddb_recid_t); 8420Sstevel@tonic-gate extern void *mddb_getrecaddr_resize(mddb_recid_t, size_t, 8430Sstevel@tonic-gate off_t); 8440Sstevel@tonic-gate extern int mddb_getrecprivate(mddb_recid_t); 8450Sstevel@tonic-gate extern void mddb_setrecprivate(mddb_recid_t, uint_t); 8460Sstevel@tonic-gate extern mddb_de_ic_t *mddb_getrecdep(mddb_recid_t); 8470Sstevel@tonic-gate extern mddb_type_t mddb_getrectype1(mddb_recid_t); 8480Sstevel@tonic-gate extern int mddb_getrectype2(mddb_recid_t); 8490Sstevel@tonic-gate extern int mddb_getrecsize(mddb_recid_t); 8500Sstevel@tonic-gate extern int mddb_commitrec(mddb_recid_t); 8510Sstevel@tonic-gate extern int mddb_commitrecs(mddb_recid_t *); 8520Sstevel@tonic-gate extern int mddb_deleterec(mddb_recid_t); 8530Sstevel@tonic-gate extern mddb_recstatus_t mddb_getrecstatus(mddb_recid_t); 8540Sstevel@tonic-gate extern mddb_recid_t mddb_createrec(size_t usersize, 8550Sstevel@tonic-gate mddb_type_t type, uint_t type2, 8560Sstevel@tonic-gate md_create_rec_option_t option, set_t setno); 8570Sstevel@tonic-gate extern void mddb_init(void); 8580Sstevel@tonic-gate extern void mddb_unload(void); 8590Sstevel@tonic-gate extern void mddb_unload_set(set_t setno); 8600Sstevel@tonic-gate extern mddb_recid_t mddb_makerecid(set_t setno, mddb_recid_t id); 8610Sstevel@tonic-gate extern set_t mddb_getsetnum(mddb_recid_t id); 8620Sstevel@tonic-gate extern char *mddb_getsetname(set_t setno); 8630Sstevel@tonic-gate extern side_t mddb_getsidenum(set_t setno); 8640Sstevel@tonic-gate extern int mddb_ownset(set_t setno); 8650Sstevel@tonic-gate extern int getmed_ioctl(mddb_med_parm_t *medpp, int mode); 8660Sstevel@tonic-gate extern int setmed_ioctl(mddb_med_parm_t *medpp, int mode); 8670Sstevel@tonic-gate extern int updmed_ioctl(mddb_med_upd_parm_t *medpp, 8680Sstevel@tonic-gate int mode); 8690Sstevel@tonic-gate extern int take_set(mddb_config_t *cp, int mode); 8700Sstevel@tonic-gate extern int release_set(mddb_config_t *cp, int mode); 8710Sstevel@tonic-gate extern int gettag_ioctl(mddb_dtag_get_parm_t *dtgpp, 8720Sstevel@tonic-gate int mode); 8730Sstevel@tonic-gate extern int usetag_ioctl(mddb_dtag_use_parm_t *dtupp, 8740Sstevel@tonic-gate int mode); 8750Sstevel@tonic-gate extern int accept_ioctl(mddb_accept_parm_t *medpp, 8760Sstevel@tonic-gate int mode); 8770Sstevel@tonic-gate extern int md_update_locator_namespace(set_t setno, 8780Sstevel@tonic-gate side_t side, char *dname, char *pname, 8790Sstevel@tonic-gate md_dev64_t devt); 8800Sstevel@tonic-gate extern int mddb_validate_lb(set_t setno, int *rmaxsz); 8810Sstevel@tonic-gate extern int mddb_getinvlb_devid(set_t setno, int count, 8820Sstevel@tonic-gate int size, char **ctdptr); 8830Sstevel@tonic-gate extern int md_update_minor(set_t, side_t, mdkey_t); 8841945Sjeanm extern int md_update_nm_rr_did_ioctl(mddb_config_t *cp); 8851623Stw21770 extern int md_update_top_device_minor(set_t, side_t, 8861623Stw21770 md_dev64_t); 8870Sstevel@tonic-gate #ifdef DEBUG 8880Sstevel@tonic-gate extern void mddb_check(void); 8890Sstevel@tonic-gate #endif /* DEBUG */ 8900Sstevel@tonic-gate #endif /* _KERNEL */ 8910Sstevel@tonic-gate 8920Sstevel@tonic-gate #else 8930Sstevel@tonic-gate 8940Sstevel@tonic-gate caddr_t mddb_fakeit; 8950Sstevel@tonic-gate 8960Sstevel@tonic-gate #define md_lb_did_convert(a, b, c) (0) 8970Sstevel@tonic-gate #define mddb_configure(a, b) (0) 8980Sstevel@tonic-gate #define mddb_getnextrec(a, b, c) ((mddb_recid_t)0) 8990Sstevel@tonic-gate #define mddb_getrecaddr(a) (mddb_fakeit) 9000Sstevel@tonic-gate #define mddb_getrecprivate(a) (0) 9010Sstevel@tonic-gate #define mddb_setrecprivate(a, b) (0) 9020Sstevel@tonic-gate #define mddb_getrectype1(a) (0) 9030Sstevel@tonic-gate #define mddb_getrectype2(a) (0) 9040Sstevel@tonic-gate #define mddb_getrecsize(a) (0) 9050Sstevel@tonic-gate #define mddb_commitrec(a) (0) 9060Sstevel@tonic-gate #define mddb_commitrecs(a) (0) 9070Sstevel@tonic-gate #define mddb_deleterec(a) (0) 9080Sstevel@tonic-gate #define mddb_getrecstatus(a) (MDDB_OK) 9090Sstevel@tonic-gate #define mddb_createrec(s, a, b) (0xffff & (int)(mddb_fakeit = \ 9100Sstevel@tonic-gate (caddr_t)kmem_zalloc(s, KM_SLEEP))) 9110Sstevel@tonic-gate #define mddb_unload() (0) 9120Sstevel@tonic-gate 9130Sstevel@tonic-gate #endif 9140Sstevel@tonic-gate 9150Sstevel@tonic-gate #define MDDB_NOSLEEP 1 9160Sstevel@tonic-gate #define MDDB_SLEEPOK 0 9170Sstevel@tonic-gate 9180Sstevel@tonic-gate #define MDDB_NOOLDOK 0x1 9190Sstevel@tonic-gate #define MDDB_MUSTEXIST 0x2 9200Sstevel@tonic-gate #define MDDB_NOINIT 0x4 9210Sstevel@tonic-gate #define MDDB_MULTINODE 0x8 9220Sstevel@tonic-gate #define MDDB_MN_STALE 0x10 /* MN set is stale */ 9230Sstevel@tonic-gate 9240Sstevel@tonic-gate /* Flags passed to selectreplicas - not a bit mask */ 9250Sstevel@tonic-gate #define MDDB_SCANALL 1 9260Sstevel@tonic-gate #define MDDB_RETRYSCAN 0 9270Sstevel@tonic-gate #define MDDB_SCANALLSYNC 2 /* During reconfig, sync up incore */ 9280Sstevel@tonic-gate /* and ondisk mddb by writing incore */ 9290Sstevel@tonic-gate /* values to disk. Don't write */ 9300Sstevel@tonic-gate /* change log records. */ 9310Sstevel@tonic-gate 9320Sstevel@tonic-gate /* Flags passed to writestart and writecopy */ 9330Sstevel@tonic-gate #define MDDB_WRITECOPY_ALL 1 /* Write all incore mddb to disk */ 9340Sstevel@tonic-gate #define MDDB_WRITECOPY_SYNC 2 /* Write incore mddb to disk except */ 9350Sstevel@tonic-gate /* - change log records */ 9360Sstevel@tonic-gate /* - optimized resync records */ 9370Sstevel@tonic-gate 9380Sstevel@tonic-gate 9390Sstevel@tonic-gate #define MDDB_PROBE 1 9400Sstevel@tonic-gate #define MDDB_NOPROBE 0 9410Sstevel@tonic-gate 9420Sstevel@tonic-gate 9430Sstevel@tonic-gate /* 9440Sstevel@tonic-gate * MN diskset definitions used to determine if a slave can write 9450Sstevel@tonic-gate * directly to the mddb. ONLY_MASTER only allows the master node 9460Sstevel@tonic-gate * to write to the mddb. ANY_NODE allows any node to write 9470Sstevel@tonic-gate * to the mddb. 9480Sstevel@tonic-gate */ 9490Sstevel@tonic-gate #define MDDB_WR_ONLY_MASTER 0 9500Sstevel@tonic-gate #define MDDB_WR_ANY_NODE 1 9510Sstevel@tonic-gate 9520Sstevel@tonic-gate #define MDDB_L_LOCKED 0x0001 /* this record is locked */ 9530Sstevel@tonic-gate #define MDDB_L_WANTED 0x0002 9540Sstevel@tonic-gate 9550Sstevel@tonic-gate #ifdef __cplusplus 9560Sstevel@tonic-gate } 9570Sstevel@tonic-gate #endif 9580Sstevel@tonic-gate 9590Sstevel@tonic-gate #endif /* _SYS_MD_MDDB_H */ 960