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 5*1623Stw21770 * Common Development and Distribution License (the "License"). 6*1623Stw21770 * 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 /* 22*1623Stw21770 * 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_RAID_H 270Sstevel@tonic-gate #define _SYS_MD_RAID_H 280Sstevel@tonic-gate 290Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 300Sstevel@tonic-gate 310Sstevel@tonic-gate #include <sys/lvm/mdvar.h> 320Sstevel@tonic-gate #include <sys/lvm/md_rename.h> 330Sstevel@tonic-gate 340Sstevel@tonic-gate #ifdef __cplusplus 350Sstevel@tonic-gate extern "C" { 360Sstevel@tonic-gate #endif 370Sstevel@tonic-gate 380Sstevel@tonic-gate 390Sstevel@tonic-gate /* 400Sstevel@tonic-gate * following bits are used in status word in the common section 410Sstevel@tonic-gate * of unit structure: un_status 420Sstevel@tonic-gate */ 430Sstevel@tonic-gate #define RAID_UNMAGIC 0xBADBABE0 440Sstevel@tonic-gate #define RAID_PSMAGIC 0xBADBABE1 450Sstevel@tonic-gate #define RAID_CSMAGIC 0xBADBABE2 460Sstevel@tonic-gate #define RAID_PWMAGIC 0xBADBABE3 470Sstevel@tonic-gate #define RAID_BUFMAGIC 0xBADBABE4 480Sstevel@tonic-gate /* 490Sstevel@tonic-gate * These are the major constants for the definition of a raid device 500Sstevel@tonic-gate */ 510Sstevel@tonic-gate #define PWCNT_MIN 10 /* mininum # prewrites */ 520Sstevel@tonic-gate #define PWCNT_MAX 100 /* maximum # prewrites */ 530Sstevel@tonic-gate #define RAID_MIN_INTERLACE (DEV_BSIZE * 2) 540Sstevel@tonic-gate 550Sstevel@tonic-gate #define UNIT_STATE(un) ((un)->un_state) 560Sstevel@tonic-gate #define COLUMN_STATE(un, column) ((un)->un_column[(column)].un_devstate) 570Sstevel@tonic-gate 580Sstevel@tonic-gate #define COLUMN_STATE_ONLY(un, column) (\ 590Sstevel@tonic-gate ((un)->un_column[(column)].un_devstate == RCS_INIT) || \ 600Sstevel@tonic-gate ((un)->un_column[(column)].un_devstate == RCS_OKAY) || \ 610Sstevel@tonic-gate ((un)->un_column[(column)].un_devstate == RCS_ERRED) || \ 620Sstevel@tonic-gate ((un)->un_column[(column)].un_devstate == RCS_RESYNC) || \ 630Sstevel@tonic-gate ((un)->un_column[(column)].un_devstate == RCS_LAST_ERRED) || \ 640Sstevel@tonic-gate ((un)->un_column[(column)].un_devstate == RCS_REGEN))) 650Sstevel@tonic-gate 660Sstevel@tonic-gate #define COLUMN_ISUP(un, column) (\ 670Sstevel@tonic-gate ((un)->un_column[(column)].un_devstate == RCS_OKAY) || \ 680Sstevel@tonic-gate ((un)->un_column[(column)].un_devstate == RCS_RESYNC) || \ 690Sstevel@tonic-gate ((un)->un_column[(column)].un_devstate == RCS_LAST_ERRED)) 700Sstevel@tonic-gate 710Sstevel@tonic-gate #define COLUMN_ISOKAY(un, column) (\ 720Sstevel@tonic-gate ((un)->un_column[(column)].un_devstate == RCS_OKAY)) 730Sstevel@tonic-gate 740Sstevel@tonic-gate #define COLUMN_ISLASTERR(un, column) (\ 750Sstevel@tonic-gate ((un)->un_column[(column)].un_devstate == RCS_LAST_ERRED)) 760Sstevel@tonic-gate 770Sstevel@tonic-gate #define WRITE_ALT(un, column) ( \ 780Sstevel@tonic-gate ((un)->un_column[(column)].un_alt_dev != NODEV64) && \ 790Sstevel@tonic-gate (((un)->un_column[(column)].un_devflags & MD_RAID_WRITE_ALT))) 800Sstevel@tonic-gate 810Sstevel@tonic-gate #define HOTSPARED(un, column) ( \ 820Sstevel@tonic-gate ((un)->un_column[(column)].un_hs_id != 0)) 830Sstevel@tonic-gate 840Sstevel@tonic-gate #define OVERLAPED(blk1, lblk1, blk2, lblk2) ( \ 850Sstevel@tonic-gate (((blk1 > lblk2) ? 1 : 0) || \ 860Sstevel@tonic-gate ((lblk1 < blk2) ? 1 : 0))) 870Sstevel@tonic-gate 880Sstevel@tonic-gate 890Sstevel@tonic-gate /* 900Sstevel@tonic-gate * Note: magic is needed only to set rpw_magic, not rpw_magic_ext! 910Sstevel@tonic-gate */ 920Sstevel@tonic-gate #define RAID_FILLIN_RPW(buf, un, sum, colnum, \ 930Sstevel@tonic-gate blkno, blkcnt, id, \ 940Sstevel@tonic-gate colcount, col, magic) { \ 95*1623Stw21770 if ((un)->c.un_revision & MD_64BIT_META_DEV) { \ 960Sstevel@tonic-gate raid_pwhdr_t *rpw64 = (raid_pwhdr_t *)(void *)(buf);\ 970Sstevel@tonic-gate rpw64->rpw_magic = magic; \ 980Sstevel@tonic-gate rpw64->rpw_sum = sum; \ 990Sstevel@tonic-gate rpw64->rpw_columnnum = colnum; \ 1000Sstevel@tonic-gate rpw64->rpw_blkno = (diskaddr_t)blkno; \ 1010Sstevel@tonic-gate rpw64->rpw_blkcnt = blkcnt; \ 1020Sstevel@tonic-gate rpw64->rpw_id = id; \ 1030Sstevel@tonic-gate rpw64->rpw_colcount = colcount; \ 1040Sstevel@tonic-gate rpw64->rpw_column = col; \ 1050Sstevel@tonic-gate rpw64->rpw_unit = MD_SID(un); \ 1060Sstevel@tonic-gate rpw64->rpw_magic_ext = RAID_PWMAGIC; \ 1070Sstevel@tonic-gate rpw64->rpw_origcolumncnt = (un)->un_origcolumncnt; \ 1080Sstevel@tonic-gate rpw64->rpw_totalcolumncnt = (un)->un_totalcolumncnt; \ 1090Sstevel@tonic-gate rpw64->rpw_segsize = (un)->un_segsize; \ 1100Sstevel@tonic-gate rpw64->rpw_segsincolumn = (diskaddr_t)((un)->un_segsincolumn);\ 1110Sstevel@tonic-gate rpw64->rpw_pwcnt = (un)->un_pwcnt; \ 1120Sstevel@tonic-gate rpw64->rpw_pwsize = (un)->un_pwsize; \ 1130Sstevel@tonic-gate rpw64->rpw_devstart = \ 1140Sstevel@tonic-gate (diskaddr_t)((un)->un_column[col].un_orig_devstart);\ 1150Sstevel@tonic-gate rpw64->rpw_pwstart = \ 1160Sstevel@tonic-gate (diskaddr_t)((un)->un_column[col].un_orig_pwstart);\ 1170Sstevel@tonic-gate } else { \ 1180Sstevel@tonic-gate raid_pwhdr32_od_t *rpw32 = \ 1190Sstevel@tonic-gate (raid_pwhdr32_od_t *)(void *)(buf); \ 1200Sstevel@tonic-gate rpw32->rpw_magic = magic; \ 1210Sstevel@tonic-gate rpw32->rpw_sum = sum; \ 1220Sstevel@tonic-gate rpw32->rpw_columnnum = colnum; \ 1230Sstevel@tonic-gate rpw32->rpw_blkno = (daddr_t)blkno; \ 1240Sstevel@tonic-gate rpw32->rpw_blkcnt = blkcnt; \ 1250Sstevel@tonic-gate rpw32->rpw_id = id; \ 1260Sstevel@tonic-gate rpw32->rpw_colcount = colcount; \ 1270Sstevel@tonic-gate rpw32->rpw_column = col; \ 1280Sstevel@tonic-gate rpw32->rpw_unit = MD_SID(un); \ 1290Sstevel@tonic-gate rpw32->rpw_magic_ext = RAID_PWMAGIC; \ 1300Sstevel@tonic-gate rpw32->rpw_origcolumncnt = (un)->un_origcolumncnt; \ 1310Sstevel@tonic-gate rpw32->rpw_totalcolumncnt = (un)->un_totalcolumncnt; \ 1320Sstevel@tonic-gate rpw32->rpw_segsize = (daddr_t)((un)->un_segsize); \ 1330Sstevel@tonic-gate rpw32->rpw_segsincolumn = (daddr_t)((un)->un_segsincolumn);\ 1340Sstevel@tonic-gate rpw32->rpw_pwcnt = (un)->un_pwcnt; \ 1350Sstevel@tonic-gate rpw32->rpw_pwsize = (un)->un_pwsize; \ 1360Sstevel@tonic-gate rpw32->rpw_devstart = \ 1370Sstevel@tonic-gate (daddr_t)((un)->un_column[col].un_orig_devstart);\ 1380Sstevel@tonic-gate rpw32->rpw_pwstart = \ 1390Sstevel@tonic-gate (daddr_t)((un)->un_column[col].un_orig_pwstart);\ 1400Sstevel@tonic-gate } \ 1410Sstevel@tonic-gate } 1420Sstevel@tonic-gate 1430Sstevel@tonic-gate #define RAID_CONVERT_RPW(rpw32, rpw64) { \ 1440Sstevel@tonic-gate (rpw64)->rpw_magic = (rpw32)->rpw_magic; \ 1450Sstevel@tonic-gate (rpw64)->rpw_sum = (rpw32)->rpw_sum; \ 1460Sstevel@tonic-gate (rpw64)->rpw_columnnum = (rpw32)->rpw_columnnum; \ 1470Sstevel@tonic-gate (rpw64)->rpw_blkno = (rpw32)->rpw_blkno; \ 1480Sstevel@tonic-gate (rpw64)->rpw_blkcnt = (rpw32)->rpw_blkcnt; \ 1490Sstevel@tonic-gate (rpw64)->rpw_id = (rpw32)->rpw_id; \ 1500Sstevel@tonic-gate (rpw64)->rpw_colcount = (rpw32)->rpw_colcount; \ 1510Sstevel@tonic-gate (rpw64)->rpw_column = (rpw32)->rpw_column; \ 1520Sstevel@tonic-gate (rpw64)->rpw_unit = (rpw32)->rpw_unit; \ 1530Sstevel@tonic-gate (rpw64)->rpw_magic_ext = (rpw32)->rpw_magic_ext; \ 1540Sstevel@tonic-gate (rpw64)->rpw_origcolumncnt = (rpw32)->rpw_origcolumncnt; \ 1550Sstevel@tonic-gate (rpw64)->rpw_totalcolumncnt = (rpw32)->rpw_totalcolumncnt; \ 1560Sstevel@tonic-gate (rpw64)->rpw_segsize = (rpw32)->rpw_segsize; \ 1570Sstevel@tonic-gate (rpw64)->rpw_segsincolumn = (rpw32)->rpw_segsincolumn; \ 1580Sstevel@tonic-gate (rpw64)->rpw_pwcnt = (rpw32)->rpw_pwcnt; \ 1590Sstevel@tonic-gate (rpw64)->rpw_pwsize = (rpw32)->rpw_pwsize; \ 1600Sstevel@tonic-gate (rpw64)->rpw_devstart = (rpw32)->rpw_devstart; \ 1610Sstevel@tonic-gate (rpw64)->rpw_pwstart = (rpw32)->rpw_pwstart; \ 1620Sstevel@tonic-gate } 1630Sstevel@tonic-gate 1640Sstevel@tonic-gate typedef struct mr_scoreboard { 1650Sstevel@tonic-gate int sb_column; 1660Sstevel@tonic-gate int sb_flags; 1670Sstevel@tonic-gate diskaddr_t sb_start_blk; 1680Sstevel@tonic-gate diskaddr_t sb_last_blk; 1690Sstevel@tonic-gate void *sb_cs; 1700Sstevel@tonic-gate } mr_scoreboard_t; 1710Sstevel@tonic-gate 1720Sstevel@tonic-gate #define SB_AVAIL (0x00000001) /* useable and valid blocks */ 1730Sstevel@tonic-gate #define SB_INUSE (0x00000002) /* being used */ 1740Sstevel@tonic-gate #define SB_UNUSED (0x00000004) /* useable and no valid blocks */ 1750Sstevel@tonic-gate #define SB_INVAL_PEND (0x00000008) /* being invalidated */ 1760Sstevel@tonic-gate 1770Sstevel@tonic-gate typedef struct mr_pw_reserve { 1780Sstevel@tonic-gate uint_t pw_magic; 1790Sstevel@tonic-gate int pw_column; 1800Sstevel@tonic-gate int pw_free; 1810Sstevel@tonic-gate mr_scoreboard_t pw_sb[1]; 1820Sstevel@tonic-gate } mr_pw_reserve_t; 1830Sstevel@tonic-gate 1840Sstevel@tonic-gate 1850Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 1860Sstevel@tonic-gate #pragma pack(4) 1870Sstevel@tonic-gate #endif 1880Sstevel@tonic-gate typedef struct mr_column { 1890Sstevel@tonic-gate rcs_state_t un_devstate; 1900Sstevel@tonic-gate rcs_flags_t un_devflags; 1910Sstevel@tonic-gate md_timeval32_t un_devtimestamp; /* time of last state change, 32 bit */ 1920Sstevel@tonic-gate 1930Sstevel@tonic-gate mddb_recid_t un_hs_id; 1940Sstevel@tonic-gate diskaddr_t un_hs_pwstart; 1950Sstevel@tonic-gate diskaddr_t un_hs_devstart; 1960Sstevel@tonic-gate mdkey_t un_hs_key; 1970Sstevel@tonic-gate 1980Sstevel@tonic-gate 1990Sstevel@tonic-gate md_dev64_t un_orig_dev; /* original device, 64 bit */ 2000Sstevel@tonic-gate mdkey_t un_orig_key; 2010Sstevel@tonic-gate diskaddr_t un_orig_pwstart; 2020Sstevel@tonic-gate diskaddr_t un_orig_devstart; 2030Sstevel@tonic-gate 2040Sstevel@tonic-gate md_dev64_t un_dev; /* current read/write dev */ 2050Sstevel@tonic-gate diskaddr_t un_pwstart; 2060Sstevel@tonic-gate diskaddr_t un_devstart; 2070Sstevel@tonic-gate 2080Sstevel@tonic-gate md_dev64_t un_alt_dev; /* write to if resync */ 2090Sstevel@tonic-gate diskaddr_t un_alt_pwstart; 2100Sstevel@tonic-gate diskaddr_t un_alt_devstart; 2110Sstevel@tonic-gate } mr_column_t; 2120Sstevel@tonic-gate 2130Sstevel@tonic-gate /* 2140Sstevel@tonic-gate * mr_column32_od is for old 32 bit format only 2150Sstevel@tonic-gate */ 2160Sstevel@tonic-gate typedef struct mr_column32_od { 2170Sstevel@tonic-gate rcs_state_t un_devstate; 2180Sstevel@tonic-gate rcs_flags_t un_devflags; 2190Sstevel@tonic-gate struct timeval32 un_devtimestamp; /* time of last state change */ 2200Sstevel@tonic-gate caddr32_t xx_un_pw_reserve; 2210Sstevel@tonic-gate 2220Sstevel@tonic-gate mddb_recid_t un_hs_id; 2230Sstevel@tonic-gate daddr32_t un_hs_pwstart; 2240Sstevel@tonic-gate daddr32_t un_hs_devstart; 2250Sstevel@tonic-gate mdkey_t un_hs_key; 2260Sstevel@tonic-gate 2270Sstevel@tonic-gate dev32_t un_orig_dev; /* original device */ 2280Sstevel@tonic-gate mdkey_t un_orig_key; 2290Sstevel@tonic-gate daddr32_t un_orig_pwstart; 2300Sstevel@tonic-gate daddr32_t un_orig_devstart; 2310Sstevel@tonic-gate 2320Sstevel@tonic-gate dev32_t un_dev; /* current read/write dev */ 2330Sstevel@tonic-gate daddr32_t un_pwstart; 2340Sstevel@tonic-gate daddr32_t un_devstart; 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate dev32_t un_alt_dev; /* write to if resync */ 2370Sstevel@tonic-gate daddr32_t un_alt_pwstart; 2380Sstevel@tonic-gate daddr32_t un_alt_devstart; 2390Sstevel@tonic-gate } mr_column32_od_t; 2400Sstevel@tonic-gate 2410Sstevel@tonic-gate 2420Sstevel@tonic-gate /* 2430Sstevel@tonic-gate * Incore only elements structures 2440Sstevel@tonic-gate */ 2450Sstevel@tonic-gate typedef struct mr_column_ic { 2460Sstevel@tonic-gate mr_pw_reserve_t *un_pw_reserve; 2470Sstevel@tonic-gate } mr_column_ic_t; 2480Sstevel@tonic-gate 2490Sstevel@tonic-gate typedef struct mr_unit_ic { 2500Sstevel@tonic-gate caddr_t _t_un_pbuffer; 2510Sstevel@tonic-gate caddr_t _t_un_dbuffer; 2520Sstevel@tonic-gate struct md_raidcs *_t_un_linlck_chn; 2530Sstevel@tonic-gate kmutex_t _t_un_linlck_mx; 2540Sstevel@tonic-gate kcondvar_t _t_un_linlck_cv; 2550Sstevel@tonic-gate kmutex_t _t_un_mx; 2560Sstevel@tonic-gate kcondvar_t _t_un_cv; 2570Sstevel@tonic-gate mr_column_ic_t *_t_un_column_ic; 2580Sstevel@tonic-gate } mr_unit_ic_t; 2590Sstevel@tonic-gate 2600Sstevel@tonic-gate typedef struct mr_unit { 2610Sstevel@tonic-gate mdc_unit_t c; 2620Sstevel@tonic-gate int un_raid_res; 2630Sstevel@tonic-gate uint_t un_magic; 2640Sstevel@tonic-gate rus_state_t un_state; 2650Sstevel@tonic-gate md_timeval32_t un_timestamp; /* 32 bit fixed size */ 2660Sstevel@tonic-gate uint_t un_origcolumncnt; 2670Sstevel@tonic-gate uint_t un_totalcolumncnt; 2680Sstevel@tonic-gate uint_t un_rflags; 2690Sstevel@tonic-gate uint_t un_segsize; 2700Sstevel@tonic-gate diskaddr_t un_segsincolumn; 2710Sstevel@tonic-gate uint_t un_maxio; /* in blks */ 2720Sstevel@tonic-gate uint_t un_iosize; /* in blks */ 2730Sstevel@tonic-gate uint_t un_linlck_flg; 2740Sstevel@tonic-gate uint_t un_pwcnt; 2750Sstevel@tonic-gate uint_t un_pwsize; 2760Sstevel@tonic-gate long long un_pwid; 2770Sstevel@tonic-gate uint_t un_percent_done; 2780Sstevel@tonic-gate uint_t un_resync_copysize; /* in blks */ 2790Sstevel@tonic-gate hsp_t un_hsp_id; 2800Sstevel@tonic-gate /* 2810Sstevel@tonic-gate * This union has to begin at an 8 byte aligned address. 2820Sstevel@tonic-gate * If not, this structure has different sizes in 32 / 64 bit 2830Sstevel@tonic-gate * environments, since in a 64 bit environment the compiler 2840Sstevel@tonic-gate * adds paddings before a long long, if it doesn't start at an 8byte 2850Sstevel@tonic-gate * aligned address. 2860Sstevel@tonic-gate * Be careful if you add or remove structure elements before it! 2870Sstevel@tonic-gate */ 2880Sstevel@tonic-gate 2890Sstevel@tonic-gate union { 2900Sstevel@tonic-gate struct { 2910Sstevel@tonic-gate diskaddr_t _t_un_resync_line_index; 2920Sstevel@tonic-gate uint_t _t_un_resync_segment; 2930Sstevel@tonic-gate int _t_un_resync_index; 2940Sstevel@tonic-gate } _resync; 2950Sstevel@tonic-gate struct { 2960Sstevel@tonic-gate diskaddr_t _t_un_grow_tb; 2970Sstevel@tonic-gate uint_t _t_un_init_colcnt; 2980Sstevel@tonic-gate u_longlong_t _t_un_init_iocnt; 2990Sstevel@tonic-gate } _init; 3000Sstevel@tonic-gate } _t_un; 3010Sstevel@tonic-gate 3020Sstevel@tonic-gate /* 3030Sstevel@tonic-gate * This union has to begin at an 8 byte aligned address. 3040Sstevel@tonic-gate * Be careful if you add or remove structure elements before it! 3050Sstevel@tonic-gate */ 3060Sstevel@tonic-gate union { 3070Sstevel@tonic-gate mr_unit_ic_t *_mr_ic; 3080Sstevel@tonic-gate uint_t _mr_ic_pad[2]; 3090Sstevel@tonic-gate } un_mr_ic; 3100Sstevel@tonic-gate 3110Sstevel@tonic-gate mr_column_t un_column[1]; 3120Sstevel@tonic-gate } mr_unit_t; 3130Sstevel@tonic-gate 3140Sstevel@tonic-gate #define mr_ic un_mr_ic._mr_ic 3150Sstevel@tonic-gate #define un_pbuffer mr_ic->_t_un_pbuffer 3160Sstevel@tonic-gate #define un_dbuffer mr_ic->_t_un_dbuffer 3170Sstevel@tonic-gate #define un_linlck_chn mr_ic->_t_un_linlck_chn 3180Sstevel@tonic-gate #define un_linlck_mx mr_ic->_t_un_linlck_mx 3190Sstevel@tonic-gate #define un_linlck_cv mr_ic->_t_un_linlck_cv 3200Sstevel@tonic-gate #define un_mx mr_ic->_t_un_mx 3210Sstevel@tonic-gate #define un_cv mr_ic->_t_un_cv 3220Sstevel@tonic-gate #define un_column_ic mr_ic->_t_un_column_ic 3230Sstevel@tonic-gate 3240Sstevel@tonic-gate /* 3250Sstevel@tonic-gate * For old 32 bit format use only 3260Sstevel@tonic-gate */ 3270Sstevel@tonic-gate typedef struct mr_unit32_od { 3280Sstevel@tonic-gate mdc_unit32_od_t c; 3290Sstevel@tonic-gate caddr32_t xx_un_raid_res; 3300Sstevel@tonic-gate uint_t un_magic; 3310Sstevel@tonic-gate rus_state_t un_state; 3320Sstevel@tonic-gate struct timeval32 un_timestamp; 3330Sstevel@tonic-gate uint_t un_origcolumncnt; 3340Sstevel@tonic-gate uint_t un_totalcolumncnt; 3350Sstevel@tonic-gate uint_t un_rflags; 3360Sstevel@tonic-gate uint_t un_segsize; 3370Sstevel@tonic-gate uint_t un_segsincolumn; 3380Sstevel@tonic-gate uint_t un_maxio; 3390Sstevel@tonic-gate uint_t un_iosize; 3400Sstevel@tonic-gate caddr32_t xx_un_pbuffer; 3410Sstevel@tonic-gate caddr32_t xx_un_dbuffer; 3420Sstevel@tonic-gate uint_t un_linlck_flg; 3430Sstevel@tonic-gate caddr32_t xx_un_linlck_chn; 3440Sstevel@tonic-gate uint_t un_pwcnt; 3450Sstevel@tonic-gate uint_t un_pwsize; 3460Sstevel@tonic-gate long long un_pwid; 3470Sstevel@tonic-gate uint_t un_rebuild_size; 3480Sstevel@tonic-gate uint_t un_percent_done; 3490Sstevel@tonic-gate union { 3500Sstevel@tonic-gate struct { 3510Sstevel@tonic-gate uint_t _t_un_resync_segment; 3520Sstevel@tonic-gate int _t_un_resync_index; 3530Sstevel@tonic-gate uint_t _t_un_resync_line_index; 3540Sstevel@tonic-gate } _resync; 3550Sstevel@tonic-gate struct { 3560Sstevel@tonic-gate daddr32_t _t_un_grow_tb; 3570Sstevel@tonic-gate uint_t _t_un_init_colcnt; 3580Sstevel@tonic-gate uint_t _t_un_init_iocnt; 3590Sstevel@tonic-gate } _init; 3600Sstevel@tonic-gate } _t_un; 3610Sstevel@tonic-gate uint_t un_resync_copysize; 3620Sstevel@tonic-gate 3630Sstevel@tonic-gate /* 3640Sstevel@tonic-gate * This spot is 8 byte aligned!!! 3650Sstevel@tonic-gate * Don't change this arrangement. 3660Sstevel@tonic-gate */ 3670Sstevel@tonic-gate union { 3680Sstevel@tonic-gate struct { 3690Sstevel@tonic-gate mr_unit_ic_t *_t_mr_ic; 3700Sstevel@tonic-gate } _mric; 3710Sstevel@tonic-gate struct { 3720Sstevel@tonic-gate uint_t xx_un_linlck_mx[2]; 3730Sstevel@tonic-gate } _lckmx; 3740Sstevel@tonic-gate } _unic; 3750Sstevel@tonic-gate 3760Sstevel@tonic-gate short xx_un_linlck_cv; 3770Sstevel@tonic-gate int xx_un_mx[2]; 3780Sstevel@tonic-gate short xx_un_cv; 3790Sstevel@tonic-gate hsp_t un_hsp_id; 3800Sstevel@tonic-gate mr_column32_od_t un_column[1]; 3810Sstevel@tonic-gate } mr_unit32_od_t; 3820Sstevel@tonic-gate 3830Sstevel@tonic-gate typedef struct raid_pwhdr { 3840Sstevel@tonic-gate uint_t rpw_magic; 3850Sstevel@tonic-gate uint_t rpw_sum; 3860Sstevel@tonic-gate int rpw_columnnum; 3870Sstevel@tonic-gate diskaddr_t rpw_blkno; 3880Sstevel@tonic-gate uint_t rpw_blkcnt; 3890Sstevel@tonic-gate long long rpw_id; 3900Sstevel@tonic-gate uint_t rpw_colcount; 3910Sstevel@tonic-gate uint_t rpw_column; 3920Sstevel@tonic-gate uint_t rpw_unit; 3930Sstevel@tonic-gate uint_t rpw_magic_ext; 3940Sstevel@tonic-gate uint_t rpw_origcolumncnt; 3950Sstevel@tonic-gate uint_t rpw_totalcolumncnt; 3960Sstevel@tonic-gate uint_t rpw_segsize; 3970Sstevel@tonic-gate diskaddr_t rpw_segsincolumn; 3980Sstevel@tonic-gate uint_t rpw_pwcnt; 3990Sstevel@tonic-gate uint_t rpw_pwsize; 4000Sstevel@tonic-gate diskaddr_t rpw_devstart; 4010Sstevel@tonic-gate diskaddr_t rpw_pwstart; 4020Sstevel@tonic-gate char rpw_filler[12]; 4030Sstevel@tonic-gate } raid_pwhdr_t; 4040Sstevel@tonic-gate 4050Sstevel@tonic-gate /* 4060Sstevel@tonic-gate * For old 32 bit pre-write area 4070Sstevel@tonic-gate */ 4080Sstevel@tonic-gate typedef struct raid_pwhdr32_od { 4090Sstevel@tonic-gate uint_t rpw_magic; 4100Sstevel@tonic-gate uint_t rpw_sum; 4110Sstevel@tonic-gate int rpw_columnnum; 4120Sstevel@tonic-gate daddr32_t rpw_blkno; 4130Sstevel@tonic-gate daddr32_t rpw_blkcnt; 4140Sstevel@tonic-gate long long rpw_id; 4150Sstevel@tonic-gate uint_t rpw_colcount; 4160Sstevel@tonic-gate uint_t rpw_column; 4170Sstevel@tonic-gate uint_t rpw_unit; 4180Sstevel@tonic-gate uint_t rpw_magic_ext; 4190Sstevel@tonic-gate uint_t rpw_origcolumncnt; 4200Sstevel@tonic-gate uint_t rpw_totalcolumncnt; 4210Sstevel@tonic-gate uint_t rpw_segsize; 4220Sstevel@tonic-gate uint_t rpw_segsincolumn; 4230Sstevel@tonic-gate uint_t rpw_pwcnt; 4240Sstevel@tonic-gate uint_t rpw_pwsize; 4250Sstevel@tonic-gate uint_t rpw_devstart; 4260Sstevel@tonic-gate uint_t rpw_pwstart; 4270Sstevel@tonic-gate rus_state_t rpw_unit_state; 4280Sstevel@tonic-gate rcs_state_t rpw_next_column_state; 4290Sstevel@tonic-gate rcs_state_t rpw_prev_column_state; 4300Sstevel@tonic-gate } raid_pwhdr32_od_t; 4310Sstevel@tonic-gate #if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4 4320Sstevel@tonic-gate #pragma pack() 4330Sstevel@tonic-gate #endif 4340Sstevel@tonic-gate 4350Sstevel@tonic-gate #ifdef _KERNEL 4360Sstevel@tonic-gate 4370Sstevel@tonic-gate /* 4380Sstevel@tonic-gate * the buffer header is only bp_mapin if it is needed. It is needed on 4390Sstevel@tonic-gate * all writes and on some reads. ps_mapin is non zero if the buffer is 4400Sstevel@tonic-gate * maped in. ps_mapin_mx protect ps_mapin. The protocol for usage is 4410Sstevel@tonic-gate * 4420Sstevel@tonic-gate * 1) check for non-zero and continue if non-zero 4430Sstevel@tonic-gate * 2) aquire the ps_mapin_mx 4440Sstevel@tonic-gate * 3) recheck for non-zero and continue if non-zero 4450Sstevel@tonic-gate * 4) bp_mapin 4460Sstevel@tonic-gate * 5) set ps_mapin to non-zero 4470Sstevel@tonic-gate * 6) drop ps_mapin_mx 4480Sstevel@tonic-gate * 4490Sstevel@tonic-gate * the reason for this is to avoid the mutex when possible. 4500Sstevel@tonic-gate */ 4510Sstevel@tonic-gate typedef struct md_raidps { /* raid parent save */ 4520Sstevel@tonic-gate DAEMON_QUEUE 4530Sstevel@tonic-gate uint_t ps_magic; 4540Sstevel@tonic-gate mr_unit_t *ps_un; 4550Sstevel@tonic-gate mdi_unit_t *ps_ui; 4560Sstevel@tonic-gate buf_t *ps_bp; 4570Sstevel@tonic-gate caddr_t ps_addr; 4580Sstevel@tonic-gate int ps_flags; 4590Sstevel@tonic-gate int ps_error; 4600Sstevel@tonic-gate int ps_frags; 4610Sstevel@tonic-gate int ps_pwfrags; 4620Sstevel@tonic-gate int ps_mapin; /* buffer maped in if non zero */ 4630Sstevel@tonic-gate kmutex_t ps_mx; 4640Sstevel@tonic-gate kmutex_t ps_mapin_mx; /* protects ps_mapin */ 4650Sstevel@tonic-gate } md_raidps_t; 4660Sstevel@tonic-gate 4670Sstevel@tonic-gate /* flags for parent save area */ 4680Sstevel@tonic-gate 4690Sstevel@tonic-gate #define MD_RPS_ERROR 0x0001 4700Sstevel@tonic-gate #define MD_RPS_READ 0x0020 4710Sstevel@tonic-gate #define MD_RPS_WRITE 0x0040 4720Sstevel@tonic-gate #define MD_RPS_DONE 0x0080 4730Sstevel@tonic-gate #define MD_RPS_INUSE 0x0100 4740Sstevel@tonic-gate #define MD_RPS_IODONE 0x0200 4750Sstevel@tonic-gate #define MD_RPS_HSREQ 0x0400 4760Sstevel@tonic-gate 4770Sstevel@tonic-gate /* 4780Sstevel@tonic-gate * used in cs_state to describe the type of io operation in progress 4790Sstevel@tonic-gate */ 4800Sstevel@tonic-gate enum raid_io_stage { 4810Sstevel@tonic-gate RAID_NONE = 0x0, 4820Sstevel@tonic-gate RAID_READ_DONE = 0x1, 4830Sstevel@tonic-gate RAID_WRITE_DONE = 0x2, 4840Sstevel@tonic-gate RAID_PREWRITE_DONE = 0x4, 4850Sstevel@tonic-gate RAID_WRITE_PONLY_DONE = 0x8, 4860Sstevel@tonic-gate RAID_WRITE_DONLY_DONE = 0x10, 4870Sstevel@tonic-gate RAID_LINE_PWDONE = 0x20 4880Sstevel@tonic-gate }; 4890Sstevel@tonic-gate 4900Sstevel@tonic-gate typedef struct md_raidcbuf { 4910Sstevel@tonic-gate DAEMON_QUEUE 4920Sstevel@tonic-gate uint_t cbuf_magic; 4930Sstevel@tonic-gate struct md_raidcbuf *cbuf_next; /* 0x10 */ 4940Sstevel@tonic-gate mr_unit_t *cbuf_un; 4950Sstevel@tonic-gate md_raidps_t *cbuf_ps; 4960Sstevel@tonic-gate int cbuf_column; 4970Sstevel@tonic-gate size_t cbuf_bcount; /* 0x20 */ 4980Sstevel@tonic-gate caddr_t cbuf_buffer; 4990Sstevel@tonic-gate int cbuf_sum; 5000Sstevel@tonic-gate int cbuf_pwslot; 5010Sstevel@tonic-gate int cbuf_pwcnt; /* 0x30 */ 5020Sstevel@tonic-gate int cbuf_flags; 5030Sstevel@tonic-gate buf_t cbuf_bp; 5040Sstevel@tonic-gate uint_t cbuf_pad[4]; 5050Sstevel@tonic-gate } md_raidcbuf_t; 5060Sstevel@tonic-gate #define CBUF_PW_INVALIDATE (0x00000001) 5070Sstevel@tonic-gate #define CBUF_WRITE (0x00000002) 5080Sstevel@tonic-gate 5090Sstevel@tonic-gate typedef struct md_raidcs { 5100Sstevel@tonic-gate DAEMON_QUEUE 5110Sstevel@tonic-gate uint_t cs_magic; 5120Sstevel@tonic-gate minor_t cs_mdunit; 5130Sstevel@tonic-gate mr_unit_t *cs_un; 5140Sstevel@tonic-gate int cs_flags; 5150Sstevel@tonic-gate md_raidps_t *cs_ps; 5160Sstevel@tonic-gate diskaddr_t cs_line; 5170Sstevel@tonic-gate void (*cs_call)(); 5180Sstevel@tonic-gate void (*cs_error_call)(); 5190Sstevel@tonic-gate void (*cs_retry_call)(); 5200Sstevel@tonic-gate struct md_raidcs *cs_linlck_next; 5210Sstevel@tonic-gate struct md_raidcs *cs_linlck_prev; 5220Sstevel@tonic-gate long long cs_pwid; 5230Sstevel@tonic-gate int cs_dcolumn; 5240Sstevel@tonic-gate int cs_dpwslot; 5250Sstevel@tonic-gate uint_t cs_dflags; 5260Sstevel@tonic-gate int cs_pcolumn; 5270Sstevel@tonic-gate int cs_ppwslot; 5280Sstevel@tonic-gate uint_t cs_pflags; 5290Sstevel@tonic-gate size_t cs_bcount; 5300Sstevel@tonic-gate uint_t cs_blkcnt; 5310Sstevel@tonic-gate diskaddr_t cs_blkno; 5320Sstevel@tonic-gate diskaddr_t cs_lastblk; 5330Sstevel@tonic-gate int cs_loop; 5340Sstevel@tonic-gate caddr_t cs_addr; /* base address of io */ 5350Sstevel@tonic-gate off_t cs_offset; /* offset into the base */ 5360Sstevel@tonic-gate caddr_t cs_dbuffer; 5370Sstevel@tonic-gate caddr_t cs_pbuffer; 5380Sstevel@tonic-gate int cs_frags; 5390Sstevel@tonic-gate int cs_strategy_flag; 5400Sstevel@tonic-gate void *cs_strategy_private; 5410Sstevel@tonic-gate md_raidcbuf_t *cs_buflist; 5420Sstevel@tonic-gate int cs_error; 5430Sstevel@tonic-gate int cs_resync_check; 5440Sstevel@tonic-gate int cs_rstate; 5450Sstevel@tonic-gate enum raid_io_stage cs_stage; /* current io stage */ 5460Sstevel@tonic-gate md_raidcbuf_t *cs_pw_inval_list; 5470Sstevel@tonic-gate 5480Sstevel@tonic-gate kmutex_t cs_mx; 5490Sstevel@tonic-gate 5500Sstevel@tonic-gate buf_t cs_pbuf; 5510Sstevel@tonic-gate uint_t cs_pad1; 5520Sstevel@tonic-gate buf_t cs_hbuf; 5530Sstevel@tonic-gate uint_t cs_pad2; 5540Sstevel@tonic-gate /* Add new structure members HERE!! */ 5550Sstevel@tonic-gate buf_t cs_dbuf; 5560Sstevel@tonic-gate /* DO NOT add struture members here; cs_dbuf is dynamically sized */ 5570Sstevel@tonic-gate } md_raidcs_t; 5580Sstevel@tonic-gate 5590Sstevel@tonic-gate /* value definitions for cs_resync_check */ 5600Sstevel@tonic-gate #define RCL_OKAY 0x01 /* write to both orig and alt */ 5610Sstevel@tonic-gate #define RCL_ERRED 0x08 /* treat column as rcs_ERRED */ 5620Sstevel@tonic-gate 5630Sstevel@tonic-gate #define RCL_DATA_MASK 0x000000ff 5640Sstevel@tonic-gate #define RCL_PARITY_MASK 0x0000ff00 5650Sstevel@tonic-gate #define RCL_PARITY_OFFSET 8 /* insure masks match offset */ 5660Sstevel@tonic-gate 5670Sstevel@tonic-gate #define RCL_PARITY(value) (((value) & RCL_PARITY_MASK) >> \ 5680Sstevel@tonic-gate RCL_PARITY_OFFSET) 5690Sstevel@tonic-gate 5700Sstevel@tonic-gate #define RCL_DATA(value) ((value) & RCL_DATA_MASK) 5710Sstevel@tonic-gate 5720Sstevel@tonic-gate /* value definitions for cs_flags */ 5730Sstevel@tonic-gate #define MD_RCS_ISCALL 0x000001 /* call cs_call in interrupt */ 5740Sstevel@tonic-gate #define MD_RCS_UNDBUF 0x000002 /* holding unit data buffer */ 5750Sstevel@tonic-gate #define MD_RCS_UNPBUF 0x000004 /* holding unit parity buffer */ 5760Sstevel@tonic-gate #define MD_RCS_MPBUF 0x000008 5770Sstevel@tonic-gate #define MD_RCS_HAVE_PW_SLOTS 0x000010 /* pw slots gotten */ 5780Sstevel@tonic-gate #define MD_RCS_PWDONE 0x000040 /* pwfrags are decremented */ 5790Sstevel@tonic-gate #define MD_RCS_READER 0x000100 /* reader line lock needed */ 5800Sstevel@tonic-gate #define MD_RCS_WRITER 0x000200 /* writer line lock needed */ 5810Sstevel@tonic-gate #define MD_RCS_LLOCKD 0x000400 /* line lock held */ 5820Sstevel@tonic-gate #define MD_RCS_WAITING 0x000800 /* line lock waiting */ 5830Sstevel@tonic-gate #define MD_RCS_LINE 0x001000 /* full line write */ 5840Sstevel@tonic-gate #define MD_RCS_ERROR 0x010000 /* I/O error on this child */ 5850Sstevel@tonic-gate #define MD_RCS_RECOVERY 0x020000 5860Sstevel@tonic-gate 5870Sstevel@tonic-gate /* value definitions for cs_pflags or cs_dflags */ 5880Sstevel@tonic-gate #define MD_RCS_ISUP 0x0002 5890Sstevel@tonic-gate 5900Sstevel@tonic-gate /* value definitions for gcs_flags */ 5910Sstevel@tonic-gate #define MD_RGCS_ALLOCBUF 0x0001 5920Sstevel@tonic-gate /* returned value from raid_replay() */ 5930Sstevel@tonic-gate #define RAID_RPLY_SUCCESS 0x0000 5940Sstevel@tonic-gate #define RAID_RPLY_ALLOCFAIL 0x0001 5950Sstevel@tonic-gate #define RAID_RPLY_COMPREPLAY 0x0002 5960Sstevel@tonic-gate #define RAID_RPLY_READONLY 0x0004 5970Sstevel@tonic-gate #define RAID_RPLY_EIO 0x0008 5980Sstevel@tonic-gate 5990Sstevel@tonic-gate typedef struct raid_rplybuf { 6000Sstevel@tonic-gate caddr_t rpl_data; 6010Sstevel@tonic-gate buf_t *rpl_buf; 6020Sstevel@tonic-gate } raid_rplybuf_t; 6030Sstevel@tonic-gate 6040Sstevel@tonic-gate typedef struct raid_rplylst { 6050Sstevel@tonic-gate struct raid_rplylst *rpl_next; 6060Sstevel@tonic-gate uint_t rpl_colcnt; 6070Sstevel@tonic-gate long long rpl_id; 6080Sstevel@tonic-gate int rpl_column1; 6090Sstevel@tonic-gate uint_t rpl_slot1; 6100Sstevel@tonic-gate raid_pwhdr_t rpl_pwhdr1; 6110Sstevel@tonic-gate int rpl_column2; 6120Sstevel@tonic-gate uint_t rpl_slot2; 6130Sstevel@tonic-gate raid_pwhdr_t rpl_pwhdr2; 6140Sstevel@tonic-gate } raid_rplylst_t; 6150Sstevel@tonic-gate 6160Sstevel@tonic-gate /* Externals from raid.c */ 6170Sstevel@tonic-gate extern int raid_build_incore(void *, int); 6180Sstevel@tonic-gate extern void reset_raid(mr_unit_t *, minor_t, int); 6190Sstevel@tonic-gate 6200Sstevel@tonic-gate /* Externals from raid_ioctl.c */ 6210Sstevel@tonic-gate extern int md_raid_ioctl(dev_t dev, int cmd, void *data, 6220Sstevel@tonic-gate int mode, IOLOCK *lockp); 6230Sstevel@tonic-gate 6240Sstevel@tonic-gate /* rename named service functions */ 6250Sstevel@tonic-gate md_ren_svc_t raid_rename_check; 6260Sstevel@tonic-gate md_ren_svc_t raid_rename_lock; 6270Sstevel@tonic-gate md_ren_void_svc_t raid_rename_unlock; 6280Sstevel@tonic-gate 6290Sstevel@tonic-gate 6300Sstevel@tonic-gate /* redefinitions of the union shared by resync and init */ 6310Sstevel@tonic-gate #define un_resync_segment _t_un._resync._t_un_resync_segment 6320Sstevel@tonic-gate #define un_resync_index _t_un._resync._t_un_resync_index 6330Sstevel@tonic-gate #define un_resync_line_index _t_un._resync._t_un_resync_line_index 6340Sstevel@tonic-gate 6350Sstevel@tonic-gate #define un_grow_tb _t_un._init._t_un_grow_tb 6360Sstevel@tonic-gate #define un_init_colcnt _t_un._init._t_un_init_colcnt 6370Sstevel@tonic-gate #define un_init_iocnt _t_un._init._t_un_init_iocnt 6380Sstevel@tonic-gate 6390Sstevel@tonic-gate #define MD_RFLAG_NEEDBUF (0x0001) 6400Sstevel@tonic-gate #define MD_RFLAG_CLEAR (0x0002) 6410Sstevel@tonic-gate #define MD_RFLAG_KEEP (0x0004) 6420Sstevel@tonic-gate #define MD_RFLAG_NEEDPW (0x0008) 6430Sstevel@tonic-gate 6440Sstevel@tonic-gate 6450Sstevel@tonic-gate extern void raid_set_state(mr_unit_t *un, int col, 6460Sstevel@tonic-gate rcs_state_t new_state, int force); 6470Sstevel@tonic-gate extern int raid_replay(mr_unit_t *un); 6480Sstevel@tonic-gate extern void raid_commit(mr_unit_t *un, mddb_recid_t *extras); 6490Sstevel@tonic-gate extern char *raid_unit_state(rus_state_t state); 6500Sstevel@tonic-gate extern intptr_t raid_hotspares(); 6510Sstevel@tonic-gate extern void raid_hs_release(hs_cmds_t cmd, mr_unit_t *un, 6520Sstevel@tonic-gate mddb_recid_t *recids, int hs_index); 6530Sstevel@tonic-gate extern int raid_internal_open(minor_t mnum, int flag, int otyp, 6540Sstevel@tonic-gate int oflags); 6550Sstevel@tonic-gate extern int raid_internal_close(minor_t mnum, int otyp, 6560Sstevel@tonic-gate int init_pw, int cflags); 6570Sstevel@tonic-gate extern int raid_build_pwslot(mr_unit_t *unit, int column_index); 6580Sstevel@tonic-gate extern void raid_free_pwslot(mr_unit_t *unit, int column_index); 6590Sstevel@tonic-gate extern void release_resync_request(minor_t mnum); 6600Sstevel@tonic-gate extern int resync_request(minor_t mnum, int column_index, 6610Sstevel@tonic-gate size_t copysize, md_error_t *ep); 6620Sstevel@tonic-gate extern int raid_resync_unit(minor_t mnum, md_error_t *ep); 6630Sstevel@tonic-gate extern void raid_line_reader_lock(md_raidcs_t *cs, 6640Sstevel@tonic-gate int resync_thread); 6650Sstevel@tonic-gate extern void raid_line_exit(md_raidcs_t *cs); 6660Sstevel@tonic-gate extern int raid_state_cnt(mr_unit_t *un, rcs_state_t state); 6670Sstevel@tonic-gate extern int raid_build_pw_reservation(mr_unit_t *un, 6680Sstevel@tonic-gate int colindex); 6690Sstevel@tonic-gate extern int init_pw_area(mr_unit_t *un, md_dev64_t dev_to_write, 6700Sstevel@tonic-gate diskaddr_t pwstart, uint_t col); 6710Sstevel@tonic-gate extern void init_buf(buf_t *bp, int flags, size_t size); 6720Sstevel@tonic-gate extern void destroy_buf(buf_t *bp); 6730Sstevel@tonic-gate extern void reset_buf(buf_t *bp, int flags, size_t size); 6740Sstevel@tonic-gate extern void md_raid_strategy(buf_t *pb, int flag, void *private); 6750Sstevel@tonic-gate extern void raid_free_pw_reservation(mr_unit_t *un, 6760Sstevel@tonic-gate int colindex); 6770Sstevel@tonic-gate extern void raid_fillin_rpw(mr_unit_t *un, 6780Sstevel@tonic-gate raid_pwhdr_t *pwhdrp, int col); 6790Sstevel@tonic-gate #endif /* _KERNEL */ 6800Sstevel@tonic-gate 6810Sstevel@tonic-gate #ifdef __cplusplus 6820Sstevel@tonic-gate } 6830Sstevel@tonic-gate #endif 6840Sstevel@tonic-gate 6850Sstevel@tonic-gate #endif /* _SYS_MD_RAID_H */ 686