17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM * CDDL HEADER START
37836SJohn.Forte@Sun.COM *
47836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM *
87836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM * and limitations under the License.
127836SJohn.Forte@Sun.COM *
137836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM *
197836SJohn.Forte@Sun.COM * CDDL HEADER END
207836SJohn.Forte@Sun.COM */
217836SJohn.Forte@Sun.COM /*
22*9093SRamana.Srikanth@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
237836SJohn.Forte@Sun.COM * Use is subject to license terms.
247836SJohn.Forte@Sun.COM */
257836SJohn.Forte@Sun.COM
267836SJohn.Forte@Sun.COM #include <sys/types.h>
277836SJohn.Forte@Sun.COM #include <sys/ksynch.h>
287836SJohn.Forte@Sun.COM #include <sys/cmn_err.h>
297836SJohn.Forte@Sun.COM #include <sys/kmem.h>
307836SJohn.Forte@Sun.COM #include <sys/stat.h>
317836SJohn.Forte@Sun.COM #include <sys/errno.h>
327836SJohn.Forte@Sun.COM
337836SJohn.Forte@Sun.COM #include "../solaris/nsc_thread.h"
347836SJohn.Forte@Sun.COM #ifdef DS_DDICT
357836SJohn.Forte@Sun.COM #include "../contract.h"
367836SJohn.Forte@Sun.COM #endif
377836SJohn.Forte@Sun.COM #include <sys/nsctl/nsctl.h>
387836SJohn.Forte@Sun.COM
397836SJohn.Forte@Sun.COM #include <sys/kmem.h>
407836SJohn.Forte@Sun.COM #include <sys/cmn_err.h>
417836SJohn.Forte@Sun.COM #include <sys/ddi.h>
427836SJohn.Forte@Sun.COM
437836SJohn.Forte@Sun.COM #include "rdc_io.h"
447836SJohn.Forte@Sun.COM #include "rdc_bitmap.h"
457836SJohn.Forte@Sun.COM #include "rdc_clnt.h"
467836SJohn.Forte@Sun.COM #include "rdc_diskq.h"
477836SJohn.Forte@Sun.COM
487836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_s.h>
497836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_s_k.h>
507836SJohn.Forte@Sun.COM #include <sys/unistat/spcs_errors.h>
517836SJohn.Forte@Sun.COM
527836SJohn.Forte@Sun.COM #ifndef UINT8_MAX
537836SJohn.Forte@Sun.COM #define UINT8_MAX 255
547836SJohn.Forte@Sun.COM #endif
557836SJohn.Forte@Sun.COM
567836SJohn.Forte@Sun.COM #ifndef UINT_MAX
577836SJohn.Forte@Sun.COM #define UINT_MAX 0xffffffff
587836SJohn.Forte@Sun.COM #endif
597836SJohn.Forte@Sun.COM
607836SJohn.Forte@Sun.COM /*
617836SJohn.Forte@Sun.COM * RDC bitmap functions.
627836SJohn.Forte@Sun.COM */
637836SJohn.Forte@Sun.COM
647836SJohn.Forte@Sun.COM /*
657836SJohn.Forte@Sun.COM * RDC cluster integration notes.
667836SJohn.Forte@Sun.COM *
677836SJohn.Forte@Sun.COM * 1. Configuration
687836SJohn.Forte@Sun.COM *
697836SJohn.Forte@Sun.COM * 1.1. Change 'rdc_bitmap_mode' in /usr/kernel/drv/rdc.conf to '1'.
707836SJohn.Forte@Sun.COM *
717836SJohn.Forte@Sun.COM * 2. Operation
727836SJohn.Forte@Sun.COM *
737836SJohn.Forte@Sun.COM * 2.1. SunCluster ensures that only one physical host has any rdc
747836SJohn.Forte@Sun.COM * controlled device imported at any one time. Hence rdc will
757836SJohn.Forte@Sun.COM * only be active on a single node for any set at a time.
767836SJohn.Forte@Sun.COM *
777836SJohn.Forte@Sun.COM * 2.2. So operation from the kernel perspective looks just like
787836SJohn.Forte@Sun.COM * operation on a single, standalone, node.
797836SJohn.Forte@Sun.COM *
807836SJohn.Forte@Sun.COM */
817836SJohn.Forte@Sun.COM
827836SJohn.Forte@Sun.COM struct rdc_bitmap_ops *rdc_bitmap_ops; /* the bitmap ops switch */
837836SJohn.Forte@Sun.COM static int rdc_wrflag; /* write flag for io */
847836SJohn.Forte@Sun.COM int rdc_bitmap_delay = 0;
857836SJohn.Forte@Sun.COM extern nsc_io_t *_rdc_io_hc;
867836SJohn.Forte@Sun.COM
877836SJohn.Forte@Sun.COM int rdc_suspend_diskq(rdc_k_info_t *krdc);
887836SJohn.Forte@Sun.COM
897836SJohn.Forte@Sun.COM /*
907836SJohn.Forte@Sun.COM * rdc_ns_io
917836SJohn.Forte@Sun.COM * Perform read or write on an underlying ns device
927836SJohn.Forte@Sun.COM *
937836SJohn.Forte@Sun.COM * fd - nsc file descriptor
947836SJohn.Forte@Sun.COM * flag - nsc io direction and characteristics flag
957836SJohn.Forte@Sun.COM * fba_pos - offset from beginning of device in FBAs
967836SJohn.Forte@Sun.COM * io_addr - pointer to data buffer
977836SJohn.Forte@Sun.COM * io_len - length of io in bytes
987836SJohn.Forte@Sun.COM */
997836SJohn.Forte@Sun.COM
1007836SJohn.Forte@Sun.COM int
rdc_ns_io(nsc_fd_t * fd,int flag,nsc_off_t fba_pos,uchar_t * io_addr,nsc_size_t io_len)1017836SJohn.Forte@Sun.COM rdc_ns_io(nsc_fd_t *fd, int flag, nsc_off_t fba_pos, uchar_t *io_addr,
1027836SJohn.Forte@Sun.COM nsc_size_t io_len)
1037836SJohn.Forte@Sun.COM {
1047836SJohn.Forte@Sun.COM nsc_buf_t *tmp;
1057836SJohn.Forte@Sun.COM nsc_vec_t *vecp;
1067836SJohn.Forte@Sun.COM uchar_t *vaddr;
1077836SJohn.Forte@Sun.COM size_t copy_len;
1087836SJohn.Forte@Sun.COM int vlen;
1097836SJohn.Forte@Sun.COM int rc;
1107836SJohn.Forte@Sun.COM nsc_size_t fba_req, fba_len;
1117836SJohn.Forte@Sun.COM nsc_size_t maxfbas = 0;
1127836SJohn.Forte@Sun.COM nsc_size_t tocopy;
1137836SJohn.Forte@Sun.COM unsigned char *toaddr;
1147836SJohn.Forte@Sun.COM
1157836SJohn.Forte@Sun.COM rc = nsc_maxfbas(fd, 0, &maxfbas);
1167836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(rc)) {
1177836SJohn.Forte@Sun.COM #ifdef DEBUG
118*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_ns_io: maxfbas failed (%d)", rc);
1197836SJohn.Forte@Sun.COM #endif
1207836SJohn.Forte@Sun.COM maxfbas = 256;
1217836SJohn.Forte@Sun.COM }
1227836SJohn.Forte@Sun.COM toaddr = io_addr;
1237836SJohn.Forte@Sun.COM fba_req = FBA_LEN(io_len);
1247836SJohn.Forte@Sun.COM loop:
1257836SJohn.Forte@Sun.COM tmp = NULL;
1267836SJohn.Forte@Sun.COM fba_len = min(fba_req, maxfbas);
1277836SJohn.Forte@Sun.COM tocopy = min(io_len, FBA_SIZE(fba_len));
1287836SJohn.Forte@Sun.COM ASSERT(tocopy < INT32_MAX);
1297836SJohn.Forte@Sun.COM
1307836SJohn.Forte@Sun.COM rc = nsc_alloc_buf(fd, fba_pos, fba_len, flag, &tmp);
1317836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(rc)) {
1327836SJohn.Forte@Sun.COM if (tmp) {
1337836SJohn.Forte@Sun.COM (void) nsc_free_buf(tmp);
1347836SJohn.Forte@Sun.COM }
1357836SJohn.Forte@Sun.COM return (EIO);
1367836SJohn.Forte@Sun.COM }
1377836SJohn.Forte@Sun.COM
1387836SJohn.Forte@Sun.COM if ((flag & NSC_WRITE) != 0 && (flag & NSC_READ) == 0 &&
1397836SJohn.Forte@Sun.COM FBA_OFF(io_len) != 0) {
1407836SJohn.Forte@Sun.COM /*
1417836SJohn.Forte@Sun.COM * Not overwriting all of the last FBA, so read in the
1427836SJohn.Forte@Sun.COM * old contents now before we overwrite it with the new
1437836SJohn.Forte@Sun.COM * data.
1447836SJohn.Forte@Sun.COM */
1457836SJohn.Forte@Sun.COM rc = nsc_read(tmp, fba_pos+FBA_NUM(io_len), 1, 0);
1467836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(rc)) {
1477836SJohn.Forte@Sun.COM (void) nsc_free_buf(tmp);
1487836SJohn.Forte@Sun.COM return (EIO);
1497836SJohn.Forte@Sun.COM }
1507836SJohn.Forte@Sun.COM }
1517836SJohn.Forte@Sun.COM
1527836SJohn.Forte@Sun.COM vecp = tmp->sb_vec;
1537836SJohn.Forte@Sun.COM vlen = vecp->sv_len;
1547836SJohn.Forte@Sun.COM vaddr = vecp->sv_addr;
1557836SJohn.Forte@Sun.COM
1567836SJohn.Forte@Sun.COM while (tocopy > 0) {
1577836SJohn.Forte@Sun.COM if (vecp->sv_addr == 0 || vecp->sv_len == 0) {
1587836SJohn.Forte@Sun.COM #ifdef DEBUG
159*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_ns_io: ran off end of handle");
1607836SJohn.Forte@Sun.COM #endif
1617836SJohn.Forte@Sun.COM break;
1627836SJohn.Forte@Sun.COM }
1637836SJohn.Forte@Sun.COM
1647836SJohn.Forte@Sun.COM copy_len = (size_t)min(vlen, (int)tocopy);
1657836SJohn.Forte@Sun.COM
1667836SJohn.Forte@Sun.COM if (flag & NSC_WRITE)
1677836SJohn.Forte@Sun.COM bcopy(toaddr, vaddr, copy_len);
1687836SJohn.Forte@Sun.COM else
1697836SJohn.Forte@Sun.COM bcopy(vaddr, toaddr, copy_len);
1707836SJohn.Forte@Sun.COM
1717836SJohn.Forte@Sun.COM toaddr += copy_len;
1727836SJohn.Forte@Sun.COM io_addr += copy_len; /* adjust position in callers buffer */
1737836SJohn.Forte@Sun.COM io_len -= copy_len; /* adjust total byte length remaining */
1747836SJohn.Forte@Sun.COM tocopy -= copy_len; /* adjust chunk byte length remaining */
1757836SJohn.Forte@Sun.COM vaddr += copy_len; /* adjust location in sv_vec_t */
1767836SJohn.Forte@Sun.COM vlen -= copy_len; /* adjust length left in sv_vec_t */
1777836SJohn.Forte@Sun.COM
1787836SJohn.Forte@Sun.COM if (vlen <= 0) {
1797836SJohn.Forte@Sun.COM vecp++;
1807836SJohn.Forte@Sun.COM vaddr = vecp->sv_addr;
1817836SJohn.Forte@Sun.COM vlen = vecp->sv_len;
1827836SJohn.Forte@Sun.COM }
1837836SJohn.Forte@Sun.COM }
1847836SJohn.Forte@Sun.COM
1857836SJohn.Forte@Sun.COM if (flag & NSC_WRITE) {
1867836SJohn.Forte@Sun.COM rc = nsc_write(tmp, tmp->sb_pos, tmp->sb_len, 0);
1877836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(rc)) {
1887836SJohn.Forte@Sun.COM (void) nsc_free_buf(tmp);
1897836SJohn.Forte@Sun.COM return (rc);
1907836SJohn.Forte@Sun.COM }
1917836SJohn.Forte@Sun.COM }
1927836SJohn.Forte@Sun.COM
1937836SJohn.Forte@Sun.COM (void) nsc_free_buf(tmp);
1947836SJohn.Forte@Sun.COM
1957836SJohn.Forte@Sun.COM fba_pos += fba_len;
1967836SJohn.Forte@Sun.COM fba_req -= fba_len;
1977836SJohn.Forte@Sun.COM if (fba_req > 0)
1987836SJohn.Forte@Sun.COM goto loop;
1997836SJohn.Forte@Sun.COM
2007836SJohn.Forte@Sun.COM return (0);
2017836SJohn.Forte@Sun.COM }
2027836SJohn.Forte@Sun.COM
2037836SJohn.Forte@Sun.COM /*
2047836SJohn.Forte@Sun.COM * Must be called with krdc->bmapmutex held.
2057836SJohn.Forte@Sun.COM */
2067836SJohn.Forte@Sun.COM static void
rdc_fill_header(rdc_u_info_t * urdc,rdc_header_t * header)2077836SJohn.Forte@Sun.COM rdc_fill_header(rdc_u_info_t *urdc, rdc_header_t *header)
2087836SJohn.Forte@Sun.COM {
2097836SJohn.Forte@Sun.COM rdc_k_info_t *krdc = &rdc_k_info[urdc->index];
2107836SJohn.Forte@Sun.COM #ifdef DEBUG
2117836SJohn.Forte@Sun.COM ASSERT(MUTEX_HELD(&krdc->bmapmutex));
2127836SJohn.Forte@Sun.COM #endif
2137836SJohn.Forte@Sun.COM
2147836SJohn.Forte@Sun.COM header->magic = RDC_HDR_MAGIC;
2157836SJohn.Forte@Sun.COM (void) strncpy(header->primary.file, urdc->primary.file, NSC_MAXPATH);
2167836SJohn.Forte@Sun.COM (void) strncpy(header->primary.bitmap, urdc->primary.bitmap,
2177836SJohn.Forte@Sun.COM NSC_MAXPATH);
2187836SJohn.Forte@Sun.COM (void) strncpy(header->secondary.file, urdc->secondary.file,
2197836SJohn.Forte@Sun.COM NSC_MAXPATH);
2207836SJohn.Forte@Sun.COM (void) strncpy(header->secondary.bitmap, urdc->secondary.bitmap,
2217836SJohn.Forte@Sun.COM NSC_MAXPATH);
2227836SJohn.Forte@Sun.COM header->flags = urdc->flags | urdc->sync_flags | urdc->bmap_flags;
2237836SJohn.Forte@Sun.COM header->autosync = urdc->autosync;
2247836SJohn.Forte@Sun.COM header->maxqfbas = urdc->maxqfbas;
2257836SJohn.Forte@Sun.COM header->maxqitems = urdc->maxqitems;
2267836SJohn.Forte@Sun.COM header->asyncthr = urdc->asyncthr;
2277836SJohn.Forte@Sun.COM header->syshostid = urdc->syshostid;
2287836SJohn.Forte@Sun.COM header->refcntsize = rdc_refcntsize(krdc);
2297836SJohn.Forte@Sun.COM #ifdef DEBUG_REFCNT
230*9093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
231*9093SRamana.Srikanth@Sun.COM (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
2327836SJohn.Forte@Sun.COM #endif
2337836SJohn.Forte@Sun.COM }
2347836SJohn.Forte@Sun.COM
2357836SJohn.Forte@Sun.COM /*
2367836SJohn.Forte@Sun.COM * Must be called with krdc->bmapmutex held.
2377836SJohn.Forte@Sun.COM */
2387836SJohn.Forte@Sun.COM static int
rdc_read_header(rdc_k_info_t * krdc,rdc_header_t * header)2397836SJohn.Forte@Sun.COM rdc_read_header(rdc_k_info_t *krdc, rdc_header_t *header)
2407836SJohn.Forte@Sun.COM {
2417836SJohn.Forte@Sun.COM int sts;
2427836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
2437836SJohn.Forte@Sun.COM union {
2447836SJohn.Forte@Sun.COM rdc_header_t *current;
2457836SJohn.Forte@Sun.COM rdc_headerv4_t *v4;
2467836SJohn.Forte@Sun.COM } u_hdrp;
2477836SJohn.Forte@Sun.COM
2487836SJohn.Forte@Sun.COM if (krdc == NULL) {
2497836SJohn.Forte@Sun.COM return (-1);
2507836SJohn.Forte@Sun.COM }
2517836SJohn.Forte@Sun.COM
2527836SJohn.Forte@Sun.COM ASSERT(MUTEX_HELD(&krdc->bmapmutex));
2537836SJohn.Forte@Sun.COM
2547836SJohn.Forte@Sun.COM urdc = &rdc_u_info[krdc->index];
2557836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_BMP_FAILED)
2567836SJohn.Forte@Sun.COM return (-1);
2577836SJohn.Forte@Sun.COM
2587836SJohn.Forte@Sun.COM if (krdc->bitmapfd == NULL) {
2597836SJohn.Forte@Sun.COM return (-1);
2607836SJohn.Forte@Sun.COM }
2617836SJohn.Forte@Sun.COM if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
2627836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
2637836SJohn.Forte@Sun.COM return (-1);
2647836SJohn.Forte@Sun.COM }
2657836SJohn.Forte@Sun.COM
2667836SJohn.Forte@Sun.COM if (krdc->bmp_kstats) {
2677836SJohn.Forte@Sun.COM mutex_enter(krdc->bmp_kstats->ks_lock);
2687836SJohn.Forte@Sun.COM kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
2697836SJohn.Forte@Sun.COM mutex_exit(krdc->bmp_kstats->ks_lock);
2707836SJohn.Forte@Sun.COM }
2717836SJohn.Forte@Sun.COM
2727836SJohn.Forte@Sun.COM sts = rdc_ns_io(krdc->bitmapfd, NSC_RDBUF, 0, (uchar_t *)header,
273*9093SRamana.Srikanth@Sun.COM sizeof (rdc_header_t));
2747836SJohn.Forte@Sun.COM
2757836SJohn.Forte@Sun.COM if (krdc->bmp_kstats) {
2767836SJohn.Forte@Sun.COM mutex_enter(krdc->bmp_kstats->ks_lock);
2777836SJohn.Forte@Sun.COM kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
2787836SJohn.Forte@Sun.COM mutex_exit(krdc->bmp_kstats->ks_lock);
2797836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->bmp_kstats)->reads++;
2807836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->bmp_kstats)->nread += sizeof (rdc_header_t);
2817836SJohn.Forte@Sun.COM }
2827836SJohn.Forte@Sun.COM
2837836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(sts)) {
284*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_read_header: %s read failed %d",
2857836SJohn.Forte@Sun.COM urdc->primary.file, sts);
2867836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "read header failed");
2877836SJohn.Forte@Sun.COM }
2887836SJohn.Forte@Sun.COM
2897836SJohn.Forte@Sun.COM _rdc_rlse_devs(krdc, RDC_BMP);
2907836SJohn.Forte@Sun.COM
2917836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(sts))
2927836SJohn.Forte@Sun.COM return (-1);
2937836SJohn.Forte@Sun.COM switch (header->magic) {
2947836SJohn.Forte@Sun.COM case RDC_HDR_V4:
2957836SJohn.Forte@Sun.COM /*
2967836SJohn.Forte@Sun.COM * old header format - upgrade incore copy, disk copy will
2977836SJohn.Forte@Sun.COM * be changed when state is re-written.
2987836SJohn.Forte@Sun.COM */
2997836SJohn.Forte@Sun.COM #ifdef DEBUG
300*9093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!sndr: old style (V4) bit map header");
3017836SJohn.Forte@Sun.COM #endif
3027836SJohn.Forte@Sun.COM header->magic = RDC_HDR_MAGIC;
3037836SJohn.Forte@Sun.COM u_hdrp.current = header;
3047836SJohn.Forte@Sun.COM /* copy down items moved by new maxq??? sizes */
3057836SJohn.Forte@Sun.COM u_hdrp.current->asyncthr = u_hdrp.v4->asyncthr;
3067836SJohn.Forte@Sun.COM u_hdrp.current->syshostid = u_hdrp.v4->syshostid;
3077836SJohn.Forte@Sun.COM u_hdrp.current->maxqitems = u_hdrp.v4->maxqitems;
3087836SJohn.Forte@Sun.COM u_hdrp.current->maxqfbas = u_hdrp.v4->maxqfbas;
3097836SJohn.Forte@Sun.COM u_hdrp.current->refcntsize = 1; /* new field */
3107836SJohn.Forte@Sun.COM #ifdef DEBUG_REFCNT
311*9093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
312*9093SRamana.Srikanth@Sun.COM (int)u_hdrp.current->refcntsize, __LINE__, __FILE__);
3137836SJohn.Forte@Sun.COM #endif
3147836SJohn.Forte@Sun.COM return (0);
3157836SJohn.Forte@Sun.COM case RDC_HDR_MAGIC:
3167836SJohn.Forte@Sun.COM /* current header type */
3177836SJohn.Forte@Sun.COM return (0);
3187836SJohn.Forte@Sun.COM default:
3197836SJohn.Forte@Sun.COM /* not a header we currently understand */
3207836SJohn.Forte@Sun.COM return (0);
3217836SJohn.Forte@Sun.COM }
3227836SJohn.Forte@Sun.COM }
3237836SJohn.Forte@Sun.COM
3247836SJohn.Forte@Sun.COM /*
3257836SJohn.Forte@Sun.COM * Must be called with krdc->bmapmutex held.
3267836SJohn.Forte@Sun.COM */
3277836SJohn.Forte@Sun.COM static int
rdc_write_header(rdc_k_info_t * krdc,rdc_header_t * header)3287836SJohn.Forte@Sun.COM rdc_write_header(rdc_k_info_t *krdc, rdc_header_t *header)
3297836SJohn.Forte@Sun.COM {
3307836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
3317836SJohn.Forte@Sun.COM int sts;
3327836SJohn.Forte@Sun.COM
3337836SJohn.Forte@Sun.COM if (krdc == NULL) {
3347836SJohn.Forte@Sun.COM return (-1);
3357836SJohn.Forte@Sun.COM }
3367836SJohn.Forte@Sun.COM
3377836SJohn.Forte@Sun.COM ASSERT(MUTEX_HELD(&krdc->bmapmutex));
3387836SJohn.Forte@Sun.COM
3397836SJohn.Forte@Sun.COM urdc = &rdc_u_info[krdc->index];
3407836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_BMP_FAILED)
3417836SJohn.Forte@Sun.COM return (-1);
3427836SJohn.Forte@Sun.COM
3437836SJohn.Forte@Sun.COM if (krdc->bitmapfd == NULL) {
3447836SJohn.Forte@Sun.COM return (-1);
3457836SJohn.Forte@Sun.COM }
3467836SJohn.Forte@Sun.COM
3477836SJohn.Forte@Sun.COM if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
3487836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
3497836SJohn.Forte@Sun.COM return (-1);
3507836SJohn.Forte@Sun.COM }
3517836SJohn.Forte@Sun.COM
3527836SJohn.Forte@Sun.COM if (krdc->bmp_kstats) {
3537836SJohn.Forte@Sun.COM mutex_enter(krdc->bmp_kstats->ks_lock);
3547836SJohn.Forte@Sun.COM kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
3557836SJohn.Forte@Sun.COM mutex_exit(krdc->bmp_kstats->ks_lock);
3567836SJohn.Forte@Sun.COM }
3577836SJohn.Forte@Sun.COM
3587836SJohn.Forte@Sun.COM sts = rdc_ns_io(krdc->bitmapfd, rdc_wrflag, 0, (uchar_t *)header,
359*9093SRamana.Srikanth@Sun.COM sizeof (rdc_header_t));
3607836SJohn.Forte@Sun.COM
3617836SJohn.Forte@Sun.COM if (krdc->bmp_kstats) {
3627836SJohn.Forte@Sun.COM mutex_enter(krdc->bmp_kstats->ks_lock);
3637836SJohn.Forte@Sun.COM kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
3647836SJohn.Forte@Sun.COM mutex_exit(krdc->bmp_kstats->ks_lock);
3657836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
3667836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten +=
367*9093SRamana.Srikanth@Sun.COM sizeof (rdc_header_t);
3687836SJohn.Forte@Sun.COM }
3697836SJohn.Forte@Sun.COM
3707836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(sts)) {
371*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_write_header: %s write failed %d",
3727836SJohn.Forte@Sun.COM urdc->primary.file, sts);
3737836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
3747836SJohn.Forte@Sun.COM }
3757836SJohn.Forte@Sun.COM
3767836SJohn.Forte@Sun.COM _rdc_rlse_devs(krdc, RDC_BMP);
3777836SJohn.Forte@Sun.COM
3787836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(sts))
3797836SJohn.Forte@Sun.COM return (-1);
3807836SJohn.Forte@Sun.COM else
3817836SJohn.Forte@Sun.COM return (0);
3827836SJohn.Forte@Sun.COM }
3837836SJohn.Forte@Sun.COM
3847836SJohn.Forte@Sun.COM struct bm_ref_ops rdc_ref_byte_ops;
3857836SJohn.Forte@Sun.COM struct bm_ref_ops rdc_ref_int_ops;
3867836SJohn.Forte@Sun.COM
3877836SJohn.Forte@Sun.COM static void
rdc_set_refcnt_ops(rdc_k_info_t * krdc,size_t refcntsize)3887836SJohn.Forte@Sun.COM rdc_set_refcnt_ops(rdc_k_info_t *krdc, size_t refcntsize)
3897836SJohn.Forte@Sun.COM {
3907836SJohn.Forte@Sun.COM switch (refcntsize) {
3917836SJohn.Forte@Sun.COM default:
3927836SJohn.Forte@Sun.COM /* FALLTHRU */
3937836SJohn.Forte@Sun.COM case sizeof (unsigned char):
3947836SJohn.Forte@Sun.COM krdc->bm_refs = &rdc_ref_byte_ops;
3957836SJohn.Forte@Sun.COM break;
3967836SJohn.Forte@Sun.COM case sizeof (unsigned int):
3977836SJohn.Forte@Sun.COM krdc->bm_refs = &rdc_ref_int_ops;
3987836SJohn.Forte@Sun.COM break;
3997836SJohn.Forte@Sun.COM }
4007836SJohn.Forte@Sun.COM #ifdef DEBUG_REFCNT
401*9093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!sndr: set refcnt ops for refcntsize %d - %d:%s",
402*9093SRamana.Srikanth@Sun.COM (int)refcntsize, __LINE__, __FILE__);
4037836SJohn.Forte@Sun.COM #endif
4047836SJohn.Forte@Sun.COM }
4057836SJohn.Forte@Sun.COM
4067836SJohn.Forte@Sun.COM size_t
rdc_refcntsize(rdc_k_info_t * krdc)4077836SJohn.Forte@Sun.COM rdc_refcntsize(rdc_k_info_t *krdc)
4087836SJohn.Forte@Sun.COM {
4097836SJohn.Forte@Sun.COM if (krdc->bm_refs == &rdc_ref_int_ops)
4107836SJohn.Forte@Sun.COM return (sizeof (unsigned int));
4117836SJohn.Forte@Sun.COM return (sizeof (unsigned char));
4127836SJohn.Forte@Sun.COM }
4137836SJohn.Forte@Sun.COM
4147836SJohn.Forte@Sun.COM int
rdc_read_state(rdc_k_info_t * krdc,int * statep,int * hostidp)4157836SJohn.Forte@Sun.COM rdc_read_state(rdc_k_info_t *krdc, int *statep, int *hostidp)
4167836SJohn.Forte@Sun.COM {
4177836SJohn.Forte@Sun.COM rdc_header_t header;
4187836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
4197836SJohn.Forte@Sun.COM int sts;
4207836SJohn.Forte@Sun.COM
4217836SJohn.Forte@Sun.COM if (krdc == NULL) {
4227836SJohn.Forte@Sun.COM return (-1);
4237836SJohn.Forte@Sun.COM }
4247836SJohn.Forte@Sun.COM
4257836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
4267836SJohn.Forte@Sun.COM
4277836SJohn.Forte@Sun.COM urdc = &rdc_u_info[krdc->index];
4287836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
4297836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
4307836SJohn.Forte@Sun.COM return (-1);
4317836SJohn.Forte@Sun.COM }
4327836SJohn.Forte@Sun.COM
4337836SJohn.Forte@Sun.COM if (krdc->bitmapfd == NULL) {
4347836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
4357836SJohn.Forte@Sun.COM return (-1);
4367836SJohn.Forte@Sun.COM }
4377836SJohn.Forte@Sun.COM
4387836SJohn.Forte@Sun.COM sts = rdc_read_header(krdc, &header);
4397836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
4407836SJohn.Forte@Sun.COM
4417836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(sts)) {
4427836SJohn.Forte@Sun.COM return (-1);
4437836SJohn.Forte@Sun.COM }
4447836SJohn.Forte@Sun.COM
4457836SJohn.Forte@Sun.COM switch (header.magic) {
4467836SJohn.Forte@Sun.COM case RDC_HDR_MAGIC:
4477836SJohn.Forte@Sun.COM *statep = header.flags;
4487836SJohn.Forte@Sun.COM *hostidp = header.syshostid;
4497836SJohn.Forte@Sun.COM rdc_set_refcnt_ops(krdc, header.refcntsize);
4507836SJohn.Forte@Sun.COM #ifdef DEBUG_REFCNT
451*9093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
452*9093SRamana.Srikanth@Sun.COM (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
4537836SJohn.Forte@Sun.COM #endif
4547836SJohn.Forte@Sun.COM sts = 0;
4557836SJohn.Forte@Sun.COM break;
4567836SJohn.Forte@Sun.COM default:
4577836SJohn.Forte@Sun.COM sts = -1;
4587836SJohn.Forte@Sun.COM break;
4597836SJohn.Forte@Sun.COM }
4607836SJohn.Forte@Sun.COM
4617836SJohn.Forte@Sun.COM return (sts);
4627836SJohn.Forte@Sun.COM }
4637836SJohn.Forte@Sun.COM
4647836SJohn.Forte@Sun.COM int
rdc_clear_state(rdc_k_info_t * krdc)4657836SJohn.Forte@Sun.COM rdc_clear_state(rdc_k_info_t *krdc)
4667836SJohn.Forte@Sun.COM {
4677836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
4687836SJohn.Forte@Sun.COM int sts;
4697836SJohn.Forte@Sun.COM rdc_header_t header;
4707836SJohn.Forte@Sun.COM
4717836SJohn.Forte@Sun.COM if (krdc == NULL) {
4727836SJohn.Forte@Sun.COM return (-1);
4737836SJohn.Forte@Sun.COM }
4747836SJohn.Forte@Sun.COM
4757836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
4767836SJohn.Forte@Sun.COM
4777836SJohn.Forte@Sun.COM urdc = &rdc_u_info[krdc->index];
4787836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
4797836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
4807836SJohn.Forte@Sun.COM return (-1);
4817836SJohn.Forte@Sun.COM }
4827836SJohn.Forte@Sun.COM
4837836SJohn.Forte@Sun.COM if (krdc->bitmapfd == NULL) {
4847836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
4857836SJohn.Forte@Sun.COM return (-1);
4867836SJohn.Forte@Sun.COM }
4877836SJohn.Forte@Sun.COM
4887836SJohn.Forte@Sun.COM if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
4897836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
4907836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
4917836SJohn.Forte@Sun.COM return (-1);
4927836SJohn.Forte@Sun.COM }
4937836SJohn.Forte@Sun.COM
4947836SJohn.Forte@Sun.COM bzero(&header, sizeof (header));
4957836SJohn.Forte@Sun.COM
4967836SJohn.Forte@Sun.COM if (krdc->bmp_kstats) {
4977836SJohn.Forte@Sun.COM mutex_enter(krdc->bmp_kstats->ks_lock);
4987836SJohn.Forte@Sun.COM kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
4997836SJohn.Forte@Sun.COM mutex_exit(krdc->bmp_kstats->ks_lock);
5007836SJohn.Forte@Sun.COM }
5017836SJohn.Forte@Sun.COM
5027836SJohn.Forte@Sun.COM sts = rdc_ns_io(krdc->bitmapfd, rdc_wrflag, 0,
5037836SJohn.Forte@Sun.COM (uchar_t *)&header, sizeof (header));
5047836SJohn.Forte@Sun.COM
5057836SJohn.Forte@Sun.COM if (krdc->bmp_kstats) {
5067836SJohn.Forte@Sun.COM mutex_enter(krdc->bmp_kstats->ks_lock);
5077836SJohn.Forte@Sun.COM kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
5087836SJohn.Forte@Sun.COM mutex_exit(krdc->bmp_kstats->ks_lock);
5097836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
5107836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten +=
511*9093SRamana.Srikanth@Sun.COM sizeof (rdc_header_t);
5127836SJohn.Forte@Sun.COM }
5137836SJohn.Forte@Sun.COM
5147836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(sts)) {
515*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_clear_state: %s write failed",
5167836SJohn.Forte@Sun.COM urdc->primary.file);
5177836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
5187836SJohn.Forte@Sun.COM }
5197836SJohn.Forte@Sun.COM
5207836SJohn.Forte@Sun.COM _rdc_rlse_devs(krdc, RDC_BMP);
5217836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
5227836SJohn.Forte@Sun.COM
5237836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(sts))
5247836SJohn.Forte@Sun.COM return (-1);
5257836SJohn.Forte@Sun.COM else
5267836SJohn.Forte@Sun.COM return (0);
5277836SJohn.Forte@Sun.COM }
5287836SJohn.Forte@Sun.COM
5297836SJohn.Forte@Sun.COM void
rdc_write_state(rdc_u_info_t * urdc)5307836SJohn.Forte@Sun.COM rdc_write_state(rdc_u_info_t *urdc)
5317836SJohn.Forte@Sun.COM {
5327836SJohn.Forte@Sun.COM rdc_k_info_t *krdc;
5337836SJohn.Forte@Sun.COM int sts;
5347836SJohn.Forte@Sun.COM rdc_header_t header;
5357836SJohn.Forte@Sun.COM
5367836SJohn.Forte@Sun.COM if (urdc == NULL) {
5377836SJohn.Forte@Sun.COM return;
5387836SJohn.Forte@Sun.COM }
5397836SJohn.Forte@Sun.COM
5407836SJohn.Forte@Sun.COM krdc = &rdc_k_info[urdc->index];
5417836SJohn.Forte@Sun.COM
5427836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
5437836SJohn.Forte@Sun.COM
5447836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
5457836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
5467836SJohn.Forte@Sun.COM return;
5477836SJohn.Forte@Sun.COM }
5487836SJohn.Forte@Sun.COM
5497836SJohn.Forte@Sun.COM if (krdc->bitmapfd == NULL) {
5507836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
5517836SJohn.Forte@Sun.COM return;
5527836SJohn.Forte@Sun.COM }
5537836SJohn.Forte@Sun.COM
5547836SJohn.Forte@Sun.COM if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
5557836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
5567836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
5577836SJohn.Forte@Sun.COM return;
5587836SJohn.Forte@Sun.COM }
5597836SJohn.Forte@Sun.COM
5607836SJohn.Forte@Sun.COM if (krdc->bmp_kstats) {
5617836SJohn.Forte@Sun.COM mutex_enter(krdc->bmp_kstats->ks_lock);
5627836SJohn.Forte@Sun.COM kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
5637836SJohn.Forte@Sun.COM mutex_exit(krdc->bmp_kstats->ks_lock);
5647836SJohn.Forte@Sun.COM }
5657836SJohn.Forte@Sun.COM
5667836SJohn.Forte@Sun.COM sts = rdc_ns_io(krdc->bitmapfd, NSC_RDBUF, 0, (uchar_t *)&header,
5677836SJohn.Forte@Sun.COM sizeof (header));
5687836SJohn.Forte@Sun.COM
5697836SJohn.Forte@Sun.COM if (krdc->bmp_kstats) {
5707836SJohn.Forte@Sun.COM mutex_enter(krdc->bmp_kstats->ks_lock);
5717836SJohn.Forte@Sun.COM kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
5727836SJohn.Forte@Sun.COM mutex_exit(krdc->bmp_kstats->ks_lock);
5737836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->bmp_kstats)->reads++;
5747836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->bmp_kstats)->nread += sizeof (header);
5757836SJohn.Forte@Sun.COM }
5767836SJohn.Forte@Sun.COM
5777836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(sts)) {
578*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_write_state: %s read failed",
5797836SJohn.Forte@Sun.COM urdc->primary.file);
5807836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "read failed");
5817836SJohn.Forte@Sun.COM goto done;
5827836SJohn.Forte@Sun.COM }
5837836SJohn.Forte@Sun.COM
5847836SJohn.Forte@Sun.COM rdc_fill_header(urdc, &header);
5857836SJohn.Forte@Sun.COM
5867836SJohn.Forte@Sun.COM if (krdc->bmp_kstats) {
5877836SJohn.Forte@Sun.COM mutex_enter(krdc->bmp_kstats->ks_lock);
5887836SJohn.Forte@Sun.COM kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
5897836SJohn.Forte@Sun.COM mutex_exit(krdc->bmp_kstats->ks_lock);
5907836SJohn.Forte@Sun.COM }
5917836SJohn.Forte@Sun.COM
5927836SJohn.Forte@Sun.COM sts = rdc_ns_io(krdc->bitmapfd, rdc_wrflag, 0,
5937836SJohn.Forte@Sun.COM (uchar_t *)&header, sizeof (header));
5947836SJohn.Forte@Sun.COM
5957836SJohn.Forte@Sun.COM if (krdc->bmp_kstats) {
5967836SJohn.Forte@Sun.COM mutex_enter(krdc->bmp_kstats->ks_lock);
5977836SJohn.Forte@Sun.COM kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
5987836SJohn.Forte@Sun.COM mutex_exit(krdc->bmp_kstats->ks_lock);
5997836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
6007836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten += sizeof (header);
6017836SJohn.Forte@Sun.COM }
6027836SJohn.Forte@Sun.COM
6037836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(sts)) {
604*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_write_state: %s write failed",
6057836SJohn.Forte@Sun.COM urdc->primary.file);
6067836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
6077836SJohn.Forte@Sun.COM }
6087836SJohn.Forte@Sun.COM
6097836SJohn.Forte@Sun.COM done:
6107836SJohn.Forte@Sun.COM _rdc_rlse_devs(krdc, RDC_BMP);
6117836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
6127836SJohn.Forte@Sun.COM }
6137836SJohn.Forte@Sun.COM
6147836SJohn.Forte@Sun.COM
6157836SJohn.Forte@Sun.COM struct bitmapdata {
6167836SJohn.Forte@Sun.COM uchar_t *data;
6177836SJohn.Forte@Sun.COM size_t len;
6187836SJohn.Forte@Sun.COM };
6197836SJohn.Forte@Sun.COM
6207836SJohn.Forte@Sun.COM static int
rdc_read_bitmap(rdc_k_info_t * krdc,struct bitmapdata * data)6217836SJohn.Forte@Sun.COM rdc_read_bitmap(rdc_k_info_t *krdc, struct bitmapdata *data)
6227836SJohn.Forte@Sun.COM {
6237836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
6247836SJohn.Forte@Sun.COM int sts;
6257836SJohn.Forte@Sun.COM
6267836SJohn.Forte@Sun.COM if (krdc == NULL) {
6277836SJohn.Forte@Sun.COM return (-1);
6287836SJohn.Forte@Sun.COM }
6297836SJohn.Forte@Sun.COM
6307836SJohn.Forte@Sun.COM if (data != NULL) {
6317836SJohn.Forte@Sun.COM data->data = kmem_alloc(krdc->bitmap_size, KM_SLEEP);
6327836SJohn.Forte@Sun.COM data->len = krdc->bitmap_size;
6337836SJohn.Forte@Sun.COM
6347836SJohn.Forte@Sun.COM if (data->data == NULL) {
6357836SJohn.Forte@Sun.COM return (-1);
6367836SJohn.Forte@Sun.COM }
6377836SJohn.Forte@Sun.COM }
6387836SJohn.Forte@Sun.COM
6397836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
6407836SJohn.Forte@Sun.COM
6417836SJohn.Forte@Sun.COM urdc = &rdc_u_info[krdc->index];
6427836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
6437836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
6447836SJohn.Forte@Sun.COM return (-1);
6457836SJohn.Forte@Sun.COM }
6467836SJohn.Forte@Sun.COM
6477836SJohn.Forte@Sun.COM if (krdc->bitmapfd == NULL) {
6487836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
6497836SJohn.Forte@Sun.COM return (-1);
6507836SJohn.Forte@Sun.COM }
6517836SJohn.Forte@Sun.COM
6527836SJohn.Forte@Sun.COM if (data == NULL && krdc->dcio_bitmap == NULL) {
6537836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
6547836SJohn.Forte@Sun.COM return (-1);
6557836SJohn.Forte@Sun.COM }
6567836SJohn.Forte@Sun.COM
6577836SJohn.Forte@Sun.COM if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
658*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_read_bitmap: %s reserve failed",
6597836SJohn.Forte@Sun.COM urdc->primary.file);
6607836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
6617836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
6627836SJohn.Forte@Sun.COM return (-1);
6637836SJohn.Forte@Sun.COM }
6647836SJohn.Forte@Sun.COM
6657836SJohn.Forte@Sun.COM if (krdc->bmp_kstats) {
6667836SJohn.Forte@Sun.COM mutex_enter(krdc->bmp_kstats->ks_lock);
6677836SJohn.Forte@Sun.COM kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
6687836SJohn.Forte@Sun.COM mutex_exit(krdc->bmp_kstats->ks_lock);
6697836SJohn.Forte@Sun.COM }
6707836SJohn.Forte@Sun.COM
6717836SJohn.Forte@Sun.COM sts = rdc_ns_io(krdc->bitmapfd, NSC_RDBUF, RDC_BITMAP_FBA,
672*9093SRamana.Srikanth@Sun.COM data ? data->data : krdc->dcio_bitmap, krdc->bitmap_size);
6737836SJohn.Forte@Sun.COM
6747836SJohn.Forte@Sun.COM if (krdc->bmp_kstats) {
6757836SJohn.Forte@Sun.COM mutex_enter(krdc->bmp_kstats->ks_lock);
6767836SJohn.Forte@Sun.COM kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
6777836SJohn.Forte@Sun.COM mutex_exit(krdc->bmp_kstats->ks_lock);
6787836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->bmp_kstats)->reads++;
6797836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->bmp_kstats)->nread += krdc->bitmap_size;
6807836SJohn.Forte@Sun.COM }
6817836SJohn.Forte@Sun.COM
6827836SJohn.Forte@Sun.COM _rdc_rlse_devs(krdc, RDC_BMP);
6837836SJohn.Forte@Sun.COM
6847836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(sts)) {
685*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_read_bitmap: %s read failed",
6867836SJohn.Forte@Sun.COM urdc->primary.file);
6877836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "read failed");
6887836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
6897836SJohn.Forte@Sun.COM return (-1);
6907836SJohn.Forte@Sun.COM }
6917836SJohn.Forte@Sun.COM
6927836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
6937836SJohn.Forte@Sun.COM return (0);
6947836SJohn.Forte@Sun.COM }
6957836SJohn.Forte@Sun.COM
6967836SJohn.Forte@Sun.COM int
rdc_write_bitmap(rdc_k_info_t * krdc)6977836SJohn.Forte@Sun.COM rdc_write_bitmap(rdc_k_info_t *krdc)
6987836SJohn.Forte@Sun.COM {
6997836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
7007836SJohn.Forte@Sun.COM int sts;
7017836SJohn.Forte@Sun.COM
7027836SJohn.Forte@Sun.COM if (krdc == NULL) {
7037836SJohn.Forte@Sun.COM return (-1);
7047836SJohn.Forte@Sun.COM }
7057836SJohn.Forte@Sun.COM
7067836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
7077836SJohn.Forte@Sun.COM
7087836SJohn.Forte@Sun.COM urdc = &rdc_u_info[krdc->index];
7097836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
7107836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
7117836SJohn.Forte@Sun.COM return (-1);
7127836SJohn.Forte@Sun.COM }
7137836SJohn.Forte@Sun.COM
7147836SJohn.Forte@Sun.COM if (krdc->bitmapfd == NULL) {
7157836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
7167836SJohn.Forte@Sun.COM return (-1);
7177836SJohn.Forte@Sun.COM }
7187836SJohn.Forte@Sun.COM
7197836SJohn.Forte@Sun.COM if (krdc->dcio_bitmap == NULL) {
7207836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
7217836SJohn.Forte@Sun.COM return (-1);
7227836SJohn.Forte@Sun.COM }
7237836SJohn.Forte@Sun.COM
7247836SJohn.Forte@Sun.COM if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
7257836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
7267836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
7277836SJohn.Forte@Sun.COM return (-1);
7287836SJohn.Forte@Sun.COM }
7297836SJohn.Forte@Sun.COM
7307836SJohn.Forte@Sun.COM if (krdc->bmp_kstats) {
7317836SJohn.Forte@Sun.COM mutex_enter(krdc->bmp_kstats->ks_lock);
7327836SJohn.Forte@Sun.COM kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
7337836SJohn.Forte@Sun.COM mutex_exit(krdc->bmp_kstats->ks_lock);
7347836SJohn.Forte@Sun.COM }
7357836SJohn.Forte@Sun.COM
7367836SJohn.Forte@Sun.COM sts = rdc_ns_io(krdc->bitmapfd, rdc_wrflag, RDC_BITMAP_FBA,
737*9093SRamana.Srikanth@Sun.COM krdc->dcio_bitmap, krdc->bitmap_size);
7387836SJohn.Forte@Sun.COM
7397836SJohn.Forte@Sun.COM if (krdc->bmp_kstats) {
7407836SJohn.Forte@Sun.COM mutex_enter(krdc->bmp_kstats->ks_lock);
7417836SJohn.Forte@Sun.COM kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
7427836SJohn.Forte@Sun.COM mutex_exit(krdc->bmp_kstats->ks_lock);
7437836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
7447836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten += krdc->bitmap_size;
7457836SJohn.Forte@Sun.COM }
7467836SJohn.Forte@Sun.COM
7477836SJohn.Forte@Sun.COM _rdc_rlse_devs(krdc, RDC_BMP);
7487836SJohn.Forte@Sun.COM
7497836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(sts)) {
750*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_write_bitmap: %s write failed",
7517836SJohn.Forte@Sun.COM urdc->primary.file);
7527836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
7537836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
7547836SJohn.Forte@Sun.COM return (-1);
7557836SJohn.Forte@Sun.COM }
7567836SJohn.Forte@Sun.COM
7577836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
7587836SJohn.Forte@Sun.COM return (0);
7597836SJohn.Forte@Sun.COM }
7607836SJohn.Forte@Sun.COM
7617836SJohn.Forte@Sun.COM int
rdc_write_bitmap_fba(rdc_k_info_t * krdc,nsc_off_t fba)7627836SJohn.Forte@Sun.COM rdc_write_bitmap_fba(rdc_k_info_t *krdc, nsc_off_t fba)
7637836SJohn.Forte@Sun.COM {
7647836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
7657836SJohn.Forte@Sun.COM int sts;
7667836SJohn.Forte@Sun.COM
7677836SJohn.Forte@Sun.COM if (krdc == NULL) {
7687836SJohn.Forte@Sun.COM return (-1);
7697836SJohn.Forte@Sun.COM }
7707836SJohn.Forte@Sun.COM
7717836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
7727836SJohn.Forte@Sun.COM
7737836SJohn.Forte@Sun.COM urdc = &rdc_u_info[krdc->index];
7747836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
7757836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
7767836SJohn.Forte@Sun.COM return (-1);
7777836SJohn.Forte@Sun.COM }
7787836SJohn.Forte@Sun.COM
7797836SJohn.Forte@Sun.COM if (krdc->bitmapfd == NULL) {
7807836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
7817836SJohn.Forte@Sun.COM return (-1);
7827836SJohn.Forte@Sun.COM }
7837836SJohn.Forte@Sun.COM
7847836SJohn.Forte@Sun.COM if (krdc->dcio_bitmap == NULL) {
7857836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
7867836SJohn.Forte@Sun.COM return (-1);
7877836SJohn.Forte@Sun.COM }
7887836SJohn.Forte@Sun.COM
7897836SJohn.Forte@Sun.COM if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
790*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_write_bitmap_fba: %s reserve failed",
7917836SJohn.Forte@Sun.COM urdc->primary.file);
7927836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
7937836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
7947836SJohn.Forte@Sun.COM return (-1);
7957836SJohn.Forte@Sun.COM }
7967836SJohn.Forte@Sun.COM
7977836SJohn.Forte@Sun.COM if (krdc->bmp_kstats) {
7987836SJohn.Forte@Sun.COM mutex_enter(krdc->bmp_kstats->ks_lock);
7997836SJohn.Forte@Sun.COM kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
8007836SJohn.Forte@Sun.COM mutex_exit(krdc->bmp_kstats->ks_lock);
8017836SJohn.Forte@Sun.COM }
8027836SJohn.Forte@Sun.COM sts = rdc_ns_io(krdc->bitmapfd, rdc_wrflag, RDC_BITMAP_FBA + fba,
803*9093SRamana.Srikanth@Sun.COM krdc->dcio_bitmap + fba * 512, 512);
8047836SJohn.Forte@Sun.COM
8057836SJohn.Forte@Sun.COM if (krdc->bmp_kstats) {
8067836SJohn.Forte@Sun.COM mutex_enter(krdc->bmp_kstats->ks_lock);
8077836SJohn.Forte@Sun.COM kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
8087836SJohn.Forte@Sun.COM mutex_exit(krdc->bmp_kstats->ks_lock);
8097836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
8107836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten += 512;
8117836SJohn.Forte@Sun.COM }
8127836SJohn.Forte@Sun.COM
8137836SJohn.Forte@Sun.COM _rdc_rlse_devs(krdc, RDC_BMP);
8147836SJohn.Forte@Sun.COM
8157836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(sts)) {
816*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_write_bitmap_fba: %s write failed",
8177836SJohn.Forte@Sun.COM urdc->primary.file);
8187836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
8197836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
8207836SJohn.Forte@Sun.COM return (-1);
8217836SJohn.Forte@Sun.COM }
8227836SJohn.Forte@Sun.COM
8237836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
8247836SJohn.Forte@Sun.COM return (0);
8257836SJohn.Forte@Sun.COM }
8267836SJohn.Forte@Sun.COM
8277836SJohn.Forte@Sun.COM
8287836SJohn.Forte@Sun.COM static int
rdc_write_bitmap_pattern(rdc_k_info_t * krdc,const char pattern)8297836SJohn.Forte@Sun.COM rdc_write_bitmap_pattern(rdc_k_info_t *krdc, const char pattern)
8307836SJohn.Forte@Sun.COM {
8317836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
8327836SJohn.Forte@Sun.COM char *buffer;
8337836SJohn.Forte@Sun.COM nsc_buf_t *h;
8347836SJohn.Forte@Sun.COM nsc_vec_t *v;
8357836SJohn.Forte@Sun.COM int rc;
8367836SJohn.Forte@Sun.COM size_t i;
8377836SJohn.Forte@Sun.COM nsc_size_t len;
8387836SJohn.Forte@Sun.COM int off;
8397836SJohn.Forte@Sun.COM size_t buffer_size;
8407836SJohn.Forte@Sun.COM size_t iolen;
8417836SJohn.Forte@Sun.COM nsc_size_t fba_req;
8427836SJohn.Forte@Sun.COM nsc_off_t fba_len, fba_pos;
8437836SJohn.Forte@Sun.COM nsc_size_t maxfbas = 0;
8447836SJohn.Forte@Sun.COM nsc_size_t tocopy;
8457836SJohn.Forte@Sun.COM
8467836SJohn.Forte@Sun.COM if (krdc == NULL) {
8477836SJohn.Forte@Sun.COM return (-1);
8487836SJohn.Forte@Sun.COM }
8497836SJohn.Forte@Sun.COM
8507836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
8517836SJohn.Forte@Sun.COM
8527836SJohn.Forte@Sun.COM urdc = &rdc_u_info[krdc->index];
8537836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
8547836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
8557836SJohn.Forte@Sun.COM return (-1);
8567836SJohn.Forte@Sun.COM }
8577836SJohn.Forte@Sun.COM
8587836SJohn.Forte@Sun.COM if (krdc->bitmapfd == NULL) {
8597836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
8607836SJohn.Forte@Sun.COM return (-1);
8617836SJohn.Forte@Sun.COM }
8627836SJohn.Forte@Sun.COM
8637836SJohn.Forte@Sun.COM if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
8647836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
8657836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
8667836SJohn.Forte@Sun.COM return (-1);
8677836SJohn.Forte@Sun.COM }
8687836SJohn.Forte@Sun.COM
8697836SJohn.Forte@Sun.COM buffer_size = FBA_SIZE(1);
8707836SJohn.Forte@Sun.COM ASSERT(buffer_size < INT32_MAX);
8717836SJohn.Forte@Sun.COM buffer = kmem_alloc(buffer_size, KM_SLEEP);
8727836SJohn.Forte@Sun.COM
8737836SJohn.Forte@Sun.COM for (i = 0; i < buffer_size; i++) {
8747836SJohn.Forte@Sun.COM buffer[i] = pattern;
8757836SJohn.Forte@Sun.COM }
8767836SJohn.Forte@Sun.COM
8777836SJohn.Forte@Sun.COM rc = nsc_maxfbas(krdc->bitmapfd, 0, &maxfbas);
8787836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(rc)) {
8797836SJohn.Forte@Sun.COM #ifdef DEBUG
8807836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
881*9093SRamana.Srikanth@Sun.COM "!rdc_write_bitmap_pattern: maxfbas failed (%d)", rc);
8827836SJohn.Forte@Sun.COM #endif
8837836SJohn.Forte@Sun.COM maxfbas = 256;
8847836SJohn.Forte@Sun.COM }
8857836SJohn.Forte@Sun.COM
8867836SJohn.Forte@Sun.COM fba_req = FBA_LEN(krdc->bitmap_size); /* total FBAs left to copy */
8877836SJohn.Forte@Sun.COM fba_pos = RDC_BITMAP_FBA; /* current FBA position */
8887836SJohn.Forte@Sun.COM tocopy = krdc->bitmap_size; /* total bytes left to copy */
8897836SJohn.Forte@Sun.COM loop:
8907836SJohn.Forte@Sun.COM h = NULL;
8917836SJohn.Forte@Sun.COM fba_len = min(fba_req, maxfbas); /* FBAs to alloc this time */
8927836SJohn.Forte@Sun.COM
8937836SJohn.Forte@Sun.COM rc = nsc_alloc_buf(krdc->bitmapfd, fba_pos, fba_len, rdc_wrflag, &h);
8947836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(rc)) {
895*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_write_bitmap_pattern: %s "
896*9093SRamana.Srikanth@Sun.COM "write failed %d", urdc->primary.file, rc);
8977836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "nsc_alloc_buf failed");
8987836SJohn.Forte@Sun.COM if (h) {
8997836SJohn.Forte@Sun.COM (void) nsc_free_handle(h);
9007836SJohn.Forte@Sun.COM }
9017836SJohn.Forte@Sun.COM
9027836SJohn.Forte@Sun.COM _rdc_rlse_devs(krdc, RDC_BMP);
9037836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
9047836SJohn.Forte@Sun.COM rc = -1;
9057836SJohn.Forte@Sun.COM goto finish;
9067836SJohn.Forte@Sun.COM }
9077836SJohn.Forte@Sun.COM
9087836SJohn.Forte@Sun.COM /* bytes to copy this time */
9097836SJohn.Forte@Sun.COM len = min(tocopy, FBA_SIZE(fba_len));
9107836SJohn.Forte@Sun.COM v = h->sb_vec;
9117836SJohn.Forte@Sun.COM off = 0;
9127836SJohn.Forte@Sun.COM
9137836SJohn.Forte@Sun.COM while (len) {
9147836SJohn.Forte@Sun.COM if (off >= v->sv_len) {
9157836SJohn.Forte@Sun.COM off = 0;
9167836SJohn.Forte@Sun.COM v++;
9177836SJohn.Forte@Sun.COM }
9187836SJohn.Forte@Sun.COM
9197836SJohn.Forte@Sun.COM if (v->sv_addr == 0 || v->sv_len == 0) {
9207836SJohn.Forte@Sun.COM #ifdef DEBUG
9217836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
922*9093SRamana.Srikanth@Sun.COM "!rdc_write_bitmap_pattern: ran off end of handle");
9237836SJohn.Forte@Sun.COM #endif
9247836SJohn.Forte@Sun.COM break;
9257836SJohn.Forte@Sun.COM }
9267836SJohn.Forte@Sun.COM
9277836SJohn.Forte@Sun.COM iolen = (size_t)min(len, buffer_size);
9287836SJohn.Forte@Sun.COM
9297836SJohn.Forte@Sun.COM bcopy(buffer, (char *)(v->sv_addr + off), iolen);
9307836SJohn.Forte@Sun.COM off += iolen;
9317836SJohn.Forte@Sun.COM len -= iolen;
9327836SJohn.Forte@Sun.COM }
9337836SJohn.Forte@Sun.COM
9347836SJohn.Forte@Sun.COM rc = nsc_write(h, h->sb_pos, h->sb_len, 0);
9357836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(rc)) {
936*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_write_bitmap_pattern: "
937*9093SRamana.Srikanth@Sun.COM "%s write failed %d", urdc->primary.file, rc);
9387836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
9397836SJohn.Forte@Sun.COM (void) nsc_free_buf(h);
9407836SJohn.Forte@Sun.COM _rdc_rlse_devs(krdc, RDC_BMP);
9417836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
9427836SJohn.Forte@Sun.COM rc = -1;
9437836SJohn.Forte@Sun.COM goto finish;
9447836SJohn.Forte@Sun.COM }
9457836SJohn.Forte@Sun.COM
9467836SJohn.Forte@Sun.COM (void) nsc_free_buf(h);
9477836SJohn.Forte@Sun.COM
9487836SJohn.Forte@Sun.COM fba_pos += fba_len;
9497836SJohn.Forte@Sun.COM fba_req -= fba_len;
9507836SJohn.Forte@Sun.COM tocopy -= FBA_SIZE(fba_len); /* adjust byte length remaining */
9517836SJohn.Forte@Sun.COM if (fba_req > 0)
9527836SJohn.Forte@Sun.COM goto loop;
9537836SJohn.Forte@Sun.COM
9547836SJohn.Forte@Sun.COM _rdc_rlse_devs(krdc, RDC_BMP);
9557836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
9567836SJohn.Forte@Sun.COM rc = 0;
9577836SJohn.Forte@Sun.COM finish:
9587836SJohn.Forte@Sun.COM kmem_free(buffer, buffer_size);
9597836SJohn.Forte@Sun.COM return (rc);
9607836SJohn.Forte@Sun.COM }
9617836SJohn.Forte@Sun.COM
9627836SJohn.Forte@Sun.COM
9637836SJohn.Forte@Sun.COM /*
9647836SJohn.Forte@Sun.COM * rdc_write_bitmap_fill()
9657836SJohn.Forte@Sun.COM *
9667836SJohn.Forte@Sun.COM * Write a bitmap full of 1's out to disk without touching the
9677836SJohn.Forte@Sun.COM * in-memory bitmap.
9687836SJohn.Forte@Sun.COM */
9697836SJohn.Forte@Sun.COM int
rdc_write_bitmap_fill(rdc_k_info_t * krdc)9707836SJohn.Forte@Sun.COM rdc_write_bitmap_fill(rdc_k_info_t *krdc)
9717836SJohn.Forte@Sun.COM {
9727836SJohn.Forte@Sun.COM return (rdc_write_bitmap_pattern(krdc, 0xff));
9737836SJohn.Forte@Sun.COM }
9747836SJohn.Forte@Sun.COM
9757836SJohn.Forte@Sun.COM
9767836SJohn.Forte@Sun.COM void
rdc_merge_bitmaps(rdc_k_info_t * src,rdc_k_info_t * dst)9777836SJohn.Forte@Sun.COM rdc_merge_bitmaps(rdc_k_info_t *src, rdc_k_info_t *dst)
9787836SJohn.Forte@Sun.COM {
9797836SJohn.Forte@Sun.COM if (src->dcio_bitmap == NULL || dst->dcio_bitmap == NULL)
9807836SJohn.Forte@Sun.COM return;
9817836SJohn.Forte@Sun.COM
9827836SJohn.Forte@Sun.COM rdc_lor(src->dcio_bitmap, dst->dcio_bitmap,
9837836SJohn.Forte@Sun.COM min(src->bitmap_size, dst->bitmap_size));
9847836SJohn.Forte@Sun.COM if (dst->bitmap_write > 0)
9857836SJohn.Forte@Sun.COM (void) rdc_write_bitmap(dst);
9867836SJohn.Forte@Sun.COM }
9877836SJohn.Forte@Sun.COM
9887836SJohn.Forte@Sun.COM
9897836SJohn.Forte@Sun.COM /*
9907836SJohn.Forte@Sun.COM * bitmap size in bytes, vol_size fba's
9917836SJohn.Forte@Sun.COM */
9927836SJohn.Forte@Sun.COM
9937836SJohn.Forte@Sun.COM size_t
rdc_ref_size_possible(nsc_size_t bitmap_size,nsc_size_t vol_size)9947836SJohn.Forte@Sun.COM rdc_ref_size_possible(nsc_size_t bitmap_size, nsc_size_t vol_size)
9957836SJohn.Forte@Sun.COM {
9967836SJohn.Forte@Sun.COM nsc_size_t ref_size;
9977836SJohn.Forte@Sun.COM nsc_size_t bitmap_end_fbas;
9987836SJohn.Forte@Sun.COM
9997836SJohn.Forte@Sun.COM bitmap_end_fbas = RDC_BITMAP_FBA + FBA_LEN(bitmap_size);
1000*9093SRamana.Srikanth@Sun.COM ref_size = FBA_LEN(bitmap_size * BITS_IN_BYTE * sizeof (unsigned char));
10017836SJohn.Forte@Sun.COM if (bitmap_end_fbas + ref_size > vol_size)
10027836SJohn.Forte@Sun.COM return ((size_t)0);
10037836SJohn.Forte@Sun.COM
1004*9093SRamana.Srikanth@Sun.COM ref_size = FBA_LEN(bitmap_size * BITS_IN_BYTE * sizeof (unsigned int));
10057836SJohn.Forte@Sun.COM if (bitmap_end_fbas + ref_size > vol_size)
10067836SJohn.Forte@Sun.COM return (sizeof (unsigned char));
10077836SJohn.Forte@Sun.COM return (sizeof (unsigned int));
10087836SJohn.Forte@Sun.COM }
10097836SJohn.Forte@Sun.COM
10107836SJohn.Forte@Sun.COM int
rdc_move_bitmap(rdc_k_info_t * krdc,char * newbitmap)10117836SJohn.Forte@Sun.COM rdc_move_bitmap(rdc_k_info_t *krdc, char *newbitmap)
10127836SJohn.Forte@Sun.COM {
10137836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
10147836SJohn.Forte@Sun.COM nsc_fd_t *oldfd;
10157836SJohn.Forte@Sun.COM nsc_fd_t *newfd = NULL;
10167836SJohn.Forte@Sun.COM rdc_header_t header;
10177836SJohn.Forte@Sun.COM int sts;
10187836SJohn.Forte@Sun.COM nsc_size_t vol_size;
10197836SJohn.Forte@Sun.COM nsc_size_t req_size;
10207836SJohn.Forte@Sun.COM size_t ref_size;
10217836SJohn.Forte@Sun.COM
10227836SJohn.Forte@Sun.COM if (krdc == NULL) {
10237836SJohn.Forte@Sun.COM return (-1);
10247836SJohn.Forte@Sun.COM }
10257836SJohn.Forte@Sun.COM
10267836SJohn.Forte@Sun.COM if (krdc->bitmapfd == NULL) {
10277836SJohn.Forte@Sun.COM return (-1);
10287836SJohn.Forte@Sun.COM }
10297836SJohn.Forte@Sun.COM
10307836SJohn.Forte@Sun.COM req_size = RDC_BITMAP_FBA + FBA_LEN(krdc->bitmap_size);
10317836SJohn.Forte@Sun.COM if (RDC_IS_DISKQ(krdc->group)) {
10327836SJohn.Forte@Sun.COM /* new volume must support at least the old refcntsize */
10337836SJohn.Forte@Sun.COM req_size += FBA_LEN(krdc->bitmap_size * BITS_IN_BYTE *
1034*9093SRamana.Srikanth@Sun.COM rdc_refcntsize(krdc));
10357836SJohn.Forte@Sun.COM #ifdef DEBUG_REFCNT
1036*9093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
1037*9093SRamana.Srikanth@Sun.COM (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
10387836SJohn.Forte@Sun.COM #endif
10397836SJohn.Forte@Sun.COM }
10407836SJohn.Forte@Sun.COM
10417836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
10427836SJohn.Forte@Sun.COM
10437836SJohn.Forte@Sun.COM if (rdc_read_header(krdc, &header) < 0) {
10447836SJohn.Forte@Sun.COM #ifdef DEBUG
1045*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_move_bitmap: Read old header failed");
10467836SJohn.Forte@Sun.COM #endif
10477836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
10487836SJohn.Forte@Sun.COM return (-1);
10497836SJohn.Forte@Sun.COM }
10507836SJohn.Forte@Sun.COM
10517836SJohn.Forte@Sun.COM oldfd = krdc->bitmapfd;
10527836SJohn.Forte@Sun.COM
10537836SJohn.Forte@Sun.COM newfd = nsc_open(newbitmap, NSC_RDCHR_ID|NSC_FILE|NSC_RDWR, 0, 0, 0);
10547836SJohn.Forte@Sun.COM if (newfd == NULL) {
10557836SJohn.Forte@Sun.COM newfd = nsc_open(newbitmap,
10567836SJohn.Forte@Sun.COM NSC_RDCHR_ID|NSC_CACHE|NSC_DEVICE|NSC_RDWR, 0, 0, 0);
10577836SJohn.Forte@Sun.COM if (newfd == NULL) {
10587836SJohn.Forte@Sun.COM /* Can't open new bitmap */
10597836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1060*9093SRamana.Srikanth@Sun.COM "!rdc_move_bitmap: Cannot open new bitmap %s",
10617836SJohn.Forte@Sun.COM newbitmap);
10627836SJohn.Forte@Sun.COM goto fail;
10637836SJohn.Forte@Sun.COM }
10647836SJohn.Forte@Sun.COM }
10657836SJohn.Forte@Sun.COM
10667836SJohn.Forte@Sun.COM sts = nsc_reserve(newfd, 0);
10677836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(sts)) {
1068*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_move_bitmap: Reserve failed for %s",
10697836SJohn.Forte@Sun.COM newbitmap);
10707836SJohn.Forte@Sun.COM goto fail;
10717836SJohn.Forte@Sun.COM }
10727836SJohn.Forte@Sun.COM sts = nsc_partsize(newfd, &vol_size);
10737836SJohn.Forte@Sun.COM nsc_release(newfd);
10747836SJohn.Forte@Sun.COM
10757836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(sts)) {
10767836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1077*9093SRamana.Srikanth@Sun.COM "!rdc_move_bitmap: nsc_partsize failed for %s", newbitmap);
10787836SJohn.Forte@Sun.COM goto fail;
10797836SJohn.Forte@Sun.COM }
10807836SJohn.Forte@Sun.COM
10817836SJohn.Forte@Sun.COM ref_size = rdc_ref_size_possible(krdc->bitmap_size, vol_size);
10827836SJohn.Forte@Sun.COM
10837836SJohn.Forte@Sun.COM if (vol_size < req_size) {
10847836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1085*9093SRamana.Srikanth@Sun.COM "!rdc_move_bitmap: bitmap %s too small: %" NSC_SZFMT
10867836SJohn.Forte@Sun.COM " vs %" NSC_SZFMT " blocks", newbitmap, vol_size, req_size);
10877836SJohn.Forte@Sun.COM goto fail;
10887836SJohn.Forte@Sun.COM }
10897836SJohn.Forte@Sun.COM
10907836SJohn.Forte@Sun.COM mutex_enter(&krdc->devices->id_rlock);
10917836SJohn.Forte@Sun.COM krdc->bitmapfd = newfd; /* swap under lock */
10927836SJohn.Forte@Sun.COM if (krdc->bmaprsrv > 0) {
10937836SJohn.Forte@Sun.COM sts = nsc_reserve(krdc->bitmapfd, 0);
10947836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(sts)) {
10957836SJohn.Forte@Sun.COM krdc->bitmapfd = oldfd; /* replace under lock */
10967836SJohn.Forte@Sun.COM mutex_exit(&krdc->devices->id_rlock);
10977836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1098*9093SRamana.Srikanth@Sun.COM "!rdc_move_bitmap: Reserve failed for %s",
10997836SJohn.Forte@Sun.COM newbitmap);
11007836SJohn.Forte@Sun.COM goto fail;
11017836SJohn.Forte@Sun.COM }
11027836SJohn.Forte@Sun.COM }
11037836SJohn.Forte@Sun.COM rdc_set_refcnt_ops(krdc, ref_size);
11047836SJohn.Forte@Sun.COM #ifdef DEBUG_REFCNT
1105*9093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
1106*9093SRamana.Srikanth@Sun.COM (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
11077836SJohn.Forte@Sun.COM #endif
11087836SJohn.Forte@Sun.COM mutex_exit(&krdc->devices->id_rlock);
11097836SJohn.Forte@Sun.COM
11107836SJohn.Forte@Sun.COM /* Forget newfd now it is krdc->bitmapfd */
11117836SJohn.Forte@Sun.COM newfd = NULL;
11127836SJohn.Forte@Sun.COM
11137836SJohn.Forte@Sun.COM /* Put new bitmap name into header and user-visible data structure */
11147836SJohn.Forte@Sun.COM urdc = &rdc_u_info[krdc->index];
11157836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
11167836SJohn.Forte@Sun.COM (void) strncpy(header.primary.bitmap, newbitmap, NSC_MAXPATH);
11177836SJohn.Forte@Sun.COM (void) strncpy(urdc->primary.bitmap, newbitmap, NSC_MAXPATH);
11187836SJohn.Forte@Sun.COM } else {
11197836SJohn.Forte@Sun.COM (void) strncpy(header.secondary.bitmap, newbitmap, NSC_MAXPATH);
11207836SJohn.Forte@Sun.COM (void) strncpy(urdc->secondary.bitmap, newbitmap, NSC_MAXPATH);
11217836SJohn.Forte@Sun.COM }
11227836SJohn.Forte@Sun.COM
11237836SJohn.Forte@Sun.COM if (rdc_write_header(krdc, &header) < 0) {
11247836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1125*9093SRamana.Srikanth@Sun.COM "!rdc_move_bitmap: Write header %s failed", newbitmap);
11267836SJohn.Forte@Sun.COM goto fail;
11277836SJohn.Forte@Sun.COM }
11287836SJohn.Forte@Sun.COM
11297836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
11307836SJohn.Forte@Sun.COM
11317836SJohn.Forte@Sun.COM if (rdc_write_bitmap(krdc) < 0) {
11327836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
11337836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1134*9093SRamana.Srikanth@Sun.COM "!rdc_move_bitmap: Write bitmap %s failed", newbitmap);
11357836SJohn.Forte@Sun.COM goto fail;
11367836SJohn.Forte@Sun.COM }
11377836SJohn.Forte@Sun.COM
11387836SJohn.Forte@Sun.COM /* Unintercept the old bitmap */
11397836SJohn.Forte@Sun.COM if (krdc->b_tok) {
11407836SJohn.Forte@Sun.COM int rc;
11417836SJohn.Forte@Sun.COM
11427836SJohn.Forte@Sun.COM rdc_group_exit(krdc);
11437836SJohn.Forte@Sun.COM rc = nsc_unregister_path(krdc->b_tok, 0);
11447836SJohn.Forte@Sun.COM if (rc)
1145*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_move_bitmap: "
1146*9093SRamana.Srikanth@Sun.COM "unregister bitmap failed %d", rc);
11477836SJohn.Forte@Sun.COM else
11487836SJohn.Forte@Sun.COM krdc->b_tok = nsc_register_path(newbitmap,
11497836SJohn.Forte@Sun.COM NSC_CACHE | NSC_DEVICE, _rdc_io_hc);
11507836SJohn.Forte@Sun.COM rdc_group_enter(krdc);
11517836SJohn.Forte@Sun.COM }
11527836SJohn.Forte@Sun.COM
11537836SJohn.Forte@Sun.COM /* clear the old bitmap header */
11547836SJohn.Forte@Sun.COM bzero(&header, sizeof (header));
11557836SJohn.Forte@Sun.COM
11567836SJohn.Forte@Sun.COM sts = nsc_held(oldfd) ? 0 : nsc_reserve(oldfd, 0);
11577836SJohn.Forte@Sun.COM if (sts == 0) {
11587836SJohn.Forte@Sun.COM
11597836SJohn.Forte@Sun.COM if (krdc->bmp_kstats) {
11607836SJohn.Forte@Sun.COM mutex_enter(krdc->bmp_kstats->ks_lock);
11617836SJohn.Forte@Sun.COM kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
11627836SJohn.Forte@Sun.COM mutex_exit(krdc->bmp_kstats->ks_lock);
11637836SJohn.Forte@Sun.COM }
11647836SJohn.Forte@Sun.COM
11657836SJohn.Forte@Sun.COM sts = rdc_ns_io(oldfd, rdc_wrflag, 0,
11667836SJohn.Forte@Sun.COM (uchar_t *)&header, sizeof (header));
11677836SJohn.Forte@Sun.COM
11687836SJohn.Forte@Sun.COM if (krdc->bmp_kstats) {
11697836SJohn.Forte@Sun.COM mutex_enter(krdc->bmp_kstats->ks_lock);
11707836SJohn.Forte@Sun.COM kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
11717836SJohn.Forte@Sun.COM mutex_exit(krdc->bmp_kstats->ks_lock);
11727836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
11737836SJohn.Forte@Sun.COM KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten +=
1174*9093SRamana.Srikanth@Sun.COM sizeof (header);
11757836SJohn.Forte@Sun.COM }
11767836SJohn.Forte@Sun.COM
11777836SJohn.Forte@Sun.COM }
11787836SJohn.Forte@Sun.COM #ifdef DEBUG
11797836SJohn.Forte@Sun.COM if (sts != 0) {
11807836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1181*9093SRamana.Srikanth@Sun.COM "!rdc_move_bitmap: unable to clear bitmap header on %s",
11827836SJohn.Forte@Sun.COM nsc_pathname(oldfd));
11837836SJohn.Forte@Sun.COM }
11847836SJohn.Forte@Sun.COM #endif
11857836SJohn.Forte@Sun.COM
11867836SJohn.Forte@Sun.COM /* nsc_close will undo any reservation */
11877836SJohn.Forte@Sun.COM if (nsc_close(oldfd) != 0) {
11887836SJohn.Forte@Sun.COM #ifdef DEBUG
1189*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_move_bitmap: close old bitmap failed");
11907836SJohn.Forte@Sun.COM #else
11917836SJohn.Forte@Sun.COM ;
11927836SJohn.Forte@Sun.COM /*EMPTY*/
11937836SJohn.Forte@Sun.COM #endif
11947836SJohn.Forte@Sun.COM }
11957836SJohn.Forte@Sun.COM
11967836SJohn.Forte@Sun.COM return (0);
11977836SJohn.Forte@Sun.COM
11987836SJohn.Forte@Sun.COM fail:
11997836SJohn.Forte@Sun.COM /* Close newfd if it was unused */
12007836SJohn.Forte@Sun.COM if (newfd && newfd != krdc->bitmapfd) {
12017836SJohn.Forte@Sun.COM (void) nsc_close(newfd);
12027836SJohn.Forte@Sun.COM newfd = NULL;
12037836SJohn.Forte@Sun.COM }
12047836SJohn.Forte@Sun.COM
12057836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
12067836SJohn.Forte@Sun.COM return (-1);
12077836SJohn.Forte@Sun.COM }
12087836SJohn.Forte@Sun.COM
12097836SJohn.Forte@Sun.COM
12107836SJohn.Forte@Sun.COM void
rdc_close_bitmap(rdc_k_info_t * krdc)12117836SJohn.Forte@Sun.COM rdc_close_bitmap(rdc_k_info_t *krdc)
12127836SJohn.Forte@Sun.COM {
12137836SJohn.Forte@Sun.COM
12147836SJohn.Forte@Sun.COM if (krdc == NULL) {
12157836SJohn.Forte@Sun.COM return;
12167836SJohn.Forte@Sun.COM }
12177836SJohn.Forte@Sun.COM
12187836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
12197836SJohn.Forte@Sun.COM
12207836SJohn.Forte@Sun.COM if (krdc->bitmapfd) {
12217836SJohn.Forte@Sun.COM if (nsc_close(krdc->bitmapfd) != 0) {
12227836SJohn.Forte@Sun.COM #ifdef DEBUG
1223*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!nsc_close on bitmap failed");
12247836SJohn.Forte@Sun.COM #else
12257836SJohn.Forte@Sun.COM ;
12267836SJohn.Forte@Sun.COM /*EMPTY*/
12277836SJohn.Forte@Sun.COM #endif
12287836SJohn.Forte@Sun.COM }
12297836SJohn.Forte@Sun.COM krdc->bitmapfd = 0;
12307836SJohn.Forte@Sun.COM }
12317836SJohn.Forte@Sun.COM
12327836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
12337836SJohn.Forte@Sun.COM }
12347836SJohn.Forte@Sun.COM
12357836SJohn.Forte@Sun.COM void
rdc_free_bitmap(rdc_k_info_t * krdc,int cmd)12367836SJohn.Forte@Sun.COM rdc_free_bitmap(rdc_k_info_t *krdc, int cmd)
12377836SJohn.Forte@Sun.COM {
12387836SJohn.Forte@Sun.COM rdc_header_t header;
12397836SJohn.Forte@Sun.COM rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
12407836SJohn.Forte@Sun.COM
12417836SJohn.Forte@Sun.COM if (krdc == NULL) {
12427836SJohn.Forte@Sun.COM return;
12437836SJohn.Forte@Sun.COM }
12447836SJohn.Forte@Sun.COM
12457836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
12467836SJohn.Forte@Sun.COM
12477836SJohn.Forte@Sun.COM if (cmd != RDC_CMD_SUSPEND) {
12487836SJohn.Forte@Sun.COM
12497836SJohn.Forte@Sun.COM bzero((char *)&header, sizeof (rdc_header_t));
12507836SJohn.Forte@Sun.COM
12517836SJohn.Forte@Sun.COM if (krdc->bitmapfd)
12527836SJohn.Forte@Sun.COM (void) rdc_write_header(krdc, &header);
12537836SJohn.Forte@Sun.COM } else {
12547836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
12557836SJohn.Forte@Sun.COM /* gotta drop mutex, in case q needs to fail */
12567836SJohn.Forte@Sun.COM if (RDC_IS_DISKQ(krdc->group) && rdc_suspend_diskq(krdc) < 0) {
12577836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1258*9093SRamana.Srikanth@Sun.COM "!rdc_free_bitmap: diskq suspend failed");
12597836SJohn.Forte@Sun.COM }
12607836SJohn.Forte@Sun.COM
12617836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
12627836SJohn.Forte@Sun.COM if (rdc_read_header(krdc, &header) < 0) {
12637836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1264*9093SRamana.Srikanth@Sun.COM "!rdc_free_bitmap: Read header failed");
12657836SJohn.Forte@Sun.COM } else {
12667836SJohn.Forte@Sun.COM rdc_fill_header(urdc, &header);
12677836SJohn.Forte@Sun.COM
12687836SJohn.Forte@Sun.COM (void) rdc_write_header(krdc, &header);
12697836SJohn.Forte@Sun.COM }
12707836SJohn.Forte@Sun.COM }
12717836SJohn.Forte@Sun.COM
12727836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
12737836SJohn.Forte@Sun.COM
12747836SJohn.Forte@Sun.COM if (krdc->dcio_bitmap != NULL) {
12757836SJohn.Forte@Sun.COM if (cmd == RDC_CMD_SUSPEND) {
12767836SJohn.Forte@Sun.COM if (krdc->bitmapfd)
12777836SJohn.Forte@Sun.COM (void) rdc_write_bitmap(krdc);
12787836SJohn.Forte@Sun.COM }
12797836SJohn.Forte@Sun.COM
12807836SJohn.Forte@Sun.COM kmem_free(krdc->dcio_bitmap, krdc->bitmap_size);
12817836SJohn.Forte@Sun.COM krdc->dcio_bitmap = NULL;
12827836SJohn.Forte@Sun.COM }
12837836SJohn.Forte@Sun.COM if (krdc->bitmap_ref != NULL) {
12847836SJohn.Forte@Sun.COM kmem_free(krdc->bitmap_ref, (krdc->bitmap_size * BITS_IN_BYTE *
12857836SJohn.Forte@Sun.COM BMAP_REF_PREF_SIZE));
12867836SJohn.Forte@Sun.COM krdc->bitmap_ref = NULL;
12877836SJohn.Forte@Sun.COM }
12887836SJohn.Forte@Sun.COM
12897836SJohn.Forte@Sun.COM krdc->bitmap_size = 0;
12907836SJohn.Forte@Sun.COM }
12917836SJohn.Forte@Sun.COM
12927836SJohn.Forte@Sun.COM static int
rdc_alloc_bitmap(rdc_k_info_t * krdc)12937836SJohn.Forte@Sun.COM rdc_alloc_bitmap(rdc_k_info_t *krdc)
12947836SJohn.Forte@Sun.COM {
12957836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
12967836SJohn.Forte@Sun.COM char *bitmapname;
12977836SJohn.Forte@Sun.COM nsc_size_t bitmap_ref_size;
12987836SJohn.Forte@Sun.COM
12997836SJohn.Forte@Sun.COM if (krdc == NULL) {
13007836SJohn.Forte@Sun.COM return (-1);
13017836SJohn.Forte@Sun.COM }
13027836SJohn.Forte@Sun.COM
13037836SJohn.Forte@Sun.COM urdc = &rdc_u_info[krdc->index];
13047836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_PRIMARY)
13057836SJohn.Forte@Sun.COM bitmapname = &urdc->primary.bitmap[0];
13067836SJohn.Forte@Sun.COM else
13077836SJohn.Forte@Sun.COM bitmapname = &urdc->secondary.bitmap[0];
13087836SJohn.Forte@Sun.COM
13097836SJohn.Forte@Sun.COM if (krdc->dcio_bitmap) {
13107836SJohn.Forte@Sun.COM #ifdef DEBUG
13117836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1312*9093SRamana.Srikanth@Sun.COM "!rdc_alloc_bitmap: bitmap %s already allocated",
13137836SJohn.Forte@Sun.COM bitmapname);
13147836SJohn.Forte@Sun.COM #endif
13157836SJohn.Forte@Sun.COM return (0);
13167836SJohn.Forte@Sun.COM }
13177836SJohn.Forte@Sun.COM
13187836SJohn.Forte@Sun.COM if (urdc->volume_size == 0)
13197836SJohn.Forte@Sun.COM return (-1);
13207836SJohn.Forte@Sun.COM
13217836SJohn.Forte@Sun.COM krdc->bitmap_size = BMAP_LOG_BYTES(urdc->volume_size);
13227836SJohn.Forte@Sun.COM /* Round up */
13237836SJohn.Forte@Sun.COM krdc->bitmap_size = (krdc->bitmap_size + 511) / 512 * 512;
13247836SJohn.Forte@Sun.COM
13257836SJohn.Forte@Sun.COM krdc->dcio_bitmap = (uchar_t *)kmem_zalloc(krdc->bitmap_size,
13267836SJohn.Forte@Sun.COM KM_SLEEP);
13277836SJohn.Forte@Sun.COM if (krdc->dcio_bitmap == NULL) {
1328*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_alloc_bitmap: alloc %" NSC_SZFMT
13297836SJohn.Forte@Sun.COM " failed for %s", krdc->bitmap_size, bitmapname);
13307836SJohn.Forte@Sun.COM return (-1);
13317836SJohn.Forte@Sun.COM }
13327836SJohn.Forte@Sun.COM
13337836SJohn.Forte@Sun.COM /*
13347836SJohn.Forte@Sun.COM * use largest ref count type size as we haven't opened the bitmap
13357836SJohn.Forte@Sun.COM * volume yet to find out what has acutally be used.
13367836SJohn.Forte@Sun.COM */
13377836SJohn.Forte@Sun.COM bitmap_ref_size = krdc->bitmap_size * BITS_IN_BYTE * BMAP_REF_PREF_SIZE;
13387836SJohn.Forte@Sun.COM if ((rdc_get_vflags(urdc) & RDC_PRIMARY) &&
13397836SJohn.Forte@Sun.COM ((krdc->type_flag & RDC_ASYNCMODE) != 0)) {
13407836SJohn.Forte@Sun.COM krdc->bitmap_ref = (uchar_t *)kmem_zalloc(bitmap_ref_size,
13417836SJohn.Forte@Sun.COM KM_SLEEP);
13427836SJohn.Forte@Sun.COM if (krdc->bitmap_ref == NULL) {
13437836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1344*9093SRamana.Srikanth@Sun.COM "!rdc_alloc_bitmap: ref alloc %" NSC_SZFMT
13457836SJohn.Forte@Sun.COM " failed for %s",
13467836SJohn.Forte@Sun.COM bitmap_ref_size, bitmapname);
13477836SJohn.Forte@Sun.COM return (-1);
13487836SJohn.Forte@Sun.COM }
13497836SJohn.Forte@Sun.COM }
13507836SJohn.Forte@Sun.COM
13517836SJohn.Forte@Sun.COM return (0);
13527836SJohn.Forte@Sun.COM }
13537836SJohn.Forte@Sun.COM
13547836SJohn.Forte@Sun.COM
13557836SJohn.Forte@Sun.COM static int
rdc_open_bitmap(rdc_k_info_t * krdc)13567836SJohn.Forte@Sun.COM rdc_open_bitmap(rdc_k_info_t *krdc)
13577836SJohn.Forte@Sun.COM {
13587836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
13597836SJohn.Forte@Sun.COM int sts;
13607836SJohn.Forte@Sun.COM uint_t hints = 0;
13617836SJohn.Forte@Sun.COM nsc_size_t vol_size;
13627836SJohn.Forte@Sun.COM char *bitmapname;
13637836SJohn.Forte@Sun.COM nsc_size_t req_size;
13647836SJohn.Forte@Sun.COM nsc_size_t bit_size;
13657836SJohn.Forte@Sun.COM
13667836SJohn.Forte@Sun.COM urdc = &rdc_u_info[krdc->index];
13677836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_PRIMARY)
13687836SJohn.Forte@Sun.COM bitmapname = &urdc->primary.bitmap[0];
13697836SJohn.Forte@Sun.COM else
13707836SJohn.Forte@Sun.COM bitmapname = &urdc->secondary.bitmap[0];
13717836SJohn.Forte@Sun.COM
13727836SJohn.Forte@Sun.COM urdc->bits_set = 0;
13737836SJohn.Forte@Sun.COM
13747836SJohn.Forte@Sun.COM bit_size = req_size = RDC_BITMAP_FBA + FBA_LEN(krdc->bitmap_size);
13757836SJohn.Forte@Sun.COM if (RDC_IS_DISKQ(krdc->group)) {
13767836SJohn.Forte@Sun.COM req_size += FBA_LEN(krdc->bitmap_size * BITS_IN_BYTE *
13777836SJohn.Forte@Sun.COM sizeof (unsigned char));
13787836SJohn.Forte@Sun.COM }
13797836SJohn.Forte@Sun.COM
13807836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
13817836SJohn.Forte@Sun.COM
13827836SJohn.Forte@Sun.COM rdc_set_refcnt_ops(krdc, sizeof (unsigned char));
13837836SJohn.Forte@Sun.COM #ifdef DEBUG_REFCNT
1384*9093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
1385*9093SRamana.Srikanth@Sun.COM (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
13867836SJohn.Forte@Sun.COM #endif
13877836SJohn.Forte@Sun.COM if (krdc->bitmapfd == NULL)
13887836SJohn.Forte@Sun.COM krdc->bitmapfd = nsc_open(bitmapname,
13897836SJohn.Forte@Sun.COM NSC_RDCHR_ID|NSC_FILE|NSC_RDWR, 0, 0, 0);
13907836SJohn.Forte@Sun.COM if (krdc->bitmapfd == NULL) {
13917836SJohn.Forte@Sun.COM krdc->bitmapfd = nsc_open(bitmapname,
13927836SJohn.Forte@Sun.COM NSC_RDCHR_ID|NSC_CACHE|NSC_DEVICE|NSC_RDWR, 0, 0, 0);
13937836SJohn.Forte@Sun.COM if (krdc->bitmapfd == NULL) {
1394*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_open_bitmap: Unable to open %s",
13957836SJohn.Forte@Sun.COM bitmapname);
13967836SJohn.Forte@Sun.COM goto fail;
13977836SJohn.Forte@Sun.COM }
13987836SJohn.Forte@Sun.COM }
13997836SJohn.Forte@Sun.COM
14007836SJohn.Forte@Sun.COM sts = _rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL);
14017836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(sts)) {
1402*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_open_bitmap: Reserve failed for %s",
14037836SJohn.Forte@Sun.COM bitmapname);
14047836SJohn.Forte@Sun.COM goto fail;
14057836SJohn.Forte@Sun.COM }
14067836SJohn.Forte@Sun.COM sts = nsc_partsize(krdc->bitmapfd, &vol_size);
14077836SJohn.Forte@Sun.COM _rdc_rlse_devs(krdc, RDC_BMP);
14087836SJohn.Forte@Sun.COM
14097836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(sts)) {
14107836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1411*9093SRamana.Srikanth@Sun.COM "!rdc_open_bitmap: nsc_partsize failed for %s", bitmapname);
14127836SJohn.Forte@Sun.COM goto fail;
14137836SJohn.Forte@Sun.COM }
14147836SJohn.Forte@Sun.COM
14157836SJohn.Forte@Sun.COM if (vol_size < req_size) {
14167836SJohn.Forte@Sun.COM /* minimum size supports unsigned char reference counts */
14177836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1418*9093SRamana.Srikanth@Sun.COM "!rdc_open_bitmap: bitmap %s too small: %" NSC_SZFMT " vs %"
14197836SJohn.Forte@Sun.COM NSC_SZFMT "blocks",
14207836SJohn.Forte@Sun.COM bitmapname, vol_size, req_size);
14217836SJohn.Forte@Sun.COM goto fail;
14227836SJohn.Forte@Sun.COM }
14237836SJohn.Forte@Sun.COM
14247836SJohn.Forte@Sun.COM if (rdc_bitmap_mode == RDC_BMP_NEVER) {
14257836SJohn.Forte@Sun.COM krdc->bitmap_write = 0; /* forced off */
14267836SJohn.Forte@Sun.COM } else if (rdc_bitmap_mode == RDC_BMP_ALWAYS ||
14277836SJohn.Forte@Sun.COM (nsc_node_hints(&hints) == 0 && (hints & NSC_FORCED_WRTHRU) == 0)) {
14287836SJohn.Forte@Sun.COM krdc->bitmap_write = 1; /* forced or autodetect on */
14297836SJohn.Forte@Sun.COM } else {
14307836SJohn.Forte@Sun.COM /* autodetect off */
14317836SJohn.Forte@Sun.COM krdc->bitmap_write = 0;
14327836SJohn.Forte@Sun.COM }
14337836SJohn.Forte@Sun.COM
14347836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
14357836SJohn.Forte@Sun.COM if (RDC_IS_DISKQ(krdc->group) && (rdc_refcntsize(krdc) <
14367836SJohn.Forte@Sun.COM BMAP_REF_PREF_SIZE)) {
14377836SJohn.Forte@Sun.COM /* test for larger ref counts */
14387836SJohn.Forte@Sun.COM #ifdef DEBUG_REFCNT
1439*9093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
1440*9093SRamana.Srikanth@Sun.COM (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
14417836SJohn.Forte@Sun.COM #endif
14427836SJohn.Forte@Sun.COM req_size = bit_size;
14437836SJohn.Forte@Sun.COM req_size += FBA_LEN(krdc->bitmap_size * BITS_IN_BYTE *
14447836SJohn.Forte@Sun.COM sizeof (unsigned int));
14457836SJohn.Forte@Sun.COM if (vol_size >= req_size)
14467836SJohn.Forte@Sun.COM rdc_set_refcnt_ops(krdc, sizeof (unsigned int));
14477836SJohn.Forte@Sun.COM }
14487836SJohn.Forte@Sun.COM #ifdef DEBUG_REFCNT
1449*9093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
1450*9093SRamana.Srikanth@Sun.COM (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
14517836SJohn.Forte@Sun.COM #endif
14527836SJohn.Forte@Sun.COM return (0);
14537836SJohn.Forte@Sun.COM
14547836SJohn.Forte@Sun.COM fail:
14557836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
14567836SJohn.Forte@Sun.COM return (-1);
14577836SJohn.Forte@Sun.COM }
14587836SJohn.Forte@Sun.COM
14597836SJohn.Forte@Sun.COM int
rdc_enable_bitmap(rdc_k_info_t * krdc,int set)14607836SJohn.Forte@Sun.COM rdc_enable_bitmap(rdc_k_info_t *krdc, int set)
14617836SJohn.Forte@Sun.COM {
14627836SJohn.Forte@Sun.COM rdc_header_t header;
14637836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
14647836SJohn.Forte@Sun.COM char *bitmapname;
14657836SJohn.Forte@Sun.COM
14667836SJohn.Forte@Sun.COM urdc = &rdc_u_info[krdc->index];
14677836SJohn.Forte@Sun.COM
14687836SJohn.Forte@Sun.COM if (rdc_alloc_bitmap(krdc) < 0)
14697836SJohn.Forte@Sun.COM goto fail;
14707836SJohn.Forte@Sun.COM
14717836SJohn.Forte@Sun.COM if (rdc_open_bitmap(krdc) < 0)
14727836SJohn.Forte@Sun.COM goto fail;
14737836SJohn.Forte@Sun.COM
14747836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_PRIMARY)
14757836SJohn.Forte@Sun.COM bitmapname = &urdc->primary.bitmap[0];
14767836SJohn.Forte@Sun.COM else
14777836SJohn.Forte@Sun.COM bitmapname = &urdc->secondary.bitmap[0];
14787836SJohn.Forte@Sun.COM
14797836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
14807836SJohn.Forte@Sun.COM
14817836SJohn.Forte@Sun.COM rdc_clr_flags(urdc, RDC_BMP_FAILED);
14827836SJohn.Forte@Sun.COM if (rdc_read_header(krdc, &header) < 0) {
14837836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1484*9093SRamana.Srikanth@Sun.COM "!rdc_enable_bitmap: Read header %s failed", bitmapname);
14857836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
14867836SJohn.Forte@Sun.COM goto fail;
14877836SJohn.Forte@Sun.COM }
14887836SJohn.Forte@Sun.COM
14897836SJohn.Forte@Sun.COM rdc_fill_header(urdc, &header);
14907836SJohn.Forte@Sun.COM rdc_set_refcnt_ops(krdc, (size_t)header.refcntsize);
14917836SJohn.Forte@Sun.COM
14927836SJohn.Forte@Sun.COM if (set)
14937836SJohn.Forte@Sun.COM (void) RDC_FILL_BITMAP(krdc, FALSE);
14947836SJohn.Forte@Sun.COM
14957836SJohn.Forte@Sun.COM if (rdc_write_header(krdc, &header) < 0) {
14967836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1497*9093SRamana.Srikanth@Sun.COM "!rdc_enable_bitmap: Write header %s failed",
14987836SJohn.Forte@Sun.COM bitmapname);
14997836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
15007836SJohn.Forte@Sun.COM goto fail;
15017836SJohn.Forte@Sun.COM }
15027836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
15037836SJohn.Forte@Sun.COM
15047836SJohn.Forte@Sun.COM if (rdc_write_bitmap(krdc) < 0) {
15057836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1506*9093SRamana.Srikanth@Sun.COM "!rdc_enable_bitmap: Write bitmap %s failed",
15077836SJohn.Forte@Sun.COM bitmapname);
15087836SJohn.Forte@Sun.COM goto fail;
15097836SJohn.Forte@Sun.COM }
15107836SJohn.Forte@Sun.COM
15117836SJohn.Forte@Sun.COM return (0);
15127836SJohn.Forte@Sun.COM
15137836SJohn.Forte@Sun.COM fail:
15147836SJohn.Forte@Sun.COM rdc_free_bitmap(krdc, RDC_CMD_ENABLE);
15157836SJohn.Forte@Sun.COM rdc_close_bitmap(krdc);
15167836SJohn.Forte@Sun.COM
15177836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
15187836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "I/O failed");
15197836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
15207836SJohn.Forte@Sun.COM return (-1);
15217836SJohn.Forte@Sun.COM }
15227836SJohn.Forte@Sun.COM
15237836SJohn.Forte@Sun.COM static int
_rdc_rdwr_refcnt(rdc_k_info_t * krdc,int rwflg)15247836SJohn.Forte@Sun.COM _rdc_rdwr_refcnt(rdc_k_info_t *krdc, int rwflg)
15257836SJohn.Forte@Sun.COM {
15267836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
15277836SJohn.Forte@Sun.COM int rc;
15287836SJohn.Forte@Sun.COM nsc_off_t offset;
15297836SJohn.Forte@Sun.COM nsc_size_t len;
15307836SJohn.Forte@Sun.COM
15317836SJohn.Forte@Sun.COM urdc = &rdc_u_info[krdc->index];
15327836SJohn.Forte@Sun.COM
15337836SJohn.Forte@Sun.COM #ifdef DEBUG_REFCNT
1534*9093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!rdc_rdwr_refcnt: %s refcount for %s",
15357836SJohn.Forte@Sun.COM (rwflg == NSC_READ) ? "resuming" : "writing",
15367836SJohn.Forte@Sun.COM urdc->primary.bitmap);
15377836SJohn.Forte@Sun.COM #endif
15387836SJohn.Forte@Sun.COM ASSERT(MUTEX_HELD(QLOCK((&krdc->group->diskq))));
15397836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
15407836SJohn.Forte@Sun.COM
15417836SJohn.Forte@Sun.COM if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
1542*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_rdwr_refcnt: reserve failed");
15437836SJohn.Forte@Sun.COM goto fail;
15447836SJohn.Forte@Sun.COM }
15457836SJohn.Forte@Sun.COM
15467836SJohn.Forte@Sun.COM if (krdc->bitmap_size == 0) {
1547*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_rdwr_refcnt: NULL bitmap!");
15487836SJohn.Forte@Sun.COM goto fail;
15497836SJohn.Forte@Sun.COM }
15507836SJohn.Forte@Sun.COM
15517836SJohn.Forte@Sun.COM offset = RDC_BITREF_FBA(krdc);
15527836SJohn.Forte@Sun.COM len = krdc->bitmap_size * BITS_IN_BYTE * rdc_refcntsize(krdc);
15537836SJohn.Forte@Sun.COM
15547836SJohn.Forte@Sun.COM rc = rdc_ns_io(krdc->bitmapfd, rwflg, offset,
15557836SJohn.Forte@Sun.COM (uchar_t *)krdc->bitmap_ref, len);
15567836SJohn.Forte@Sun.COM
15577836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(rc)) {
1558*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!unable to %s refcount from bitmap %s",
15597836SJohn.Forte@Sun.COM (rwflg == NSC_READ) ? "retrieve" : "write",
15607836SJohn.Forte@Sun.COM urdc->primary.bitmap);
15617836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "refcount I/O failed");
15627836SJohn.Forte@Sun.COM goto fail;
15637836SJohn.Forte@Sun.COM }
15647836SJohn.Forte@Sun.COM
15657836SJohn.Forte@Sun.COM _rdc_rlse_devs(krdc, RDC_BMP);
15667836SJohn.Forte@Sun.COM
15677836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
15687836SJohn.Forte@Sun.COM
15697836SJohn.Forte@Sun.COM #ifdef DEBUG_REFCNT
1570*9093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!rdc_rdwr_refcnt: %s refcount for %s",
15717836SJohn.Forte@Sun.COM (rwflg == NSC_READ) ? "resumed" : "wrote",
15727836SJohn.Forte@Sun.COM urdc->primary.bitmap);
15737836SJohn.Forte@Sun.COM #endif
15747836SJohn.Forte@Sun.COM return (0);
15757836SJohn.Forte@Sun.COM
15767836SJohn.Forte@Sun.COM fail:
15777836SJohn.Forte@Sun.COM _rdc_rlse_devs(krdc, RDC_BMP);
15787836SJohn.Forte@Sun.COM
15797836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
15807836SJohn.Forte@Sun.COM
15817836SJohn.Forte@Sun.COM return (-1);
15827836SJohn.Forte@Sun.COM
15837836SJohn.Forte@Sun.COM }
15847836SJohn.Forte@Sun.COM
15857836SJohn.Forte@Sun.COM /*
15867836SJohn.Forte@Sun.COM * rdc_read_refcount
15877836SJohn.Forte@Sun.COM * read the stored refcount from disk
15887836SJohn.Forte@Sun.COM * queue lock is held
15897836SJohn.Forte@Sun.COM */
15907836SJohn.Forte@Sun.COM int
rdc_read_refcount(rdc_k_info_t * krdc)15917836SJohn.Forte@Sun.COM rdc_read_refcount(rdc_k_info_t *krdc)
15927836SJohn.Forte@Sun.COM {
15937836SJohn.Forte@Sun.COM int rc;
15947836SJohn.Forte@Sun.COM
15957836SJohn.Forte@Sun.COM rc = _rdc_rdwr_refcnt(krdc, NSC_READ);
15967836SJohn.Forte@Sun.COM
15977836SJohn.Forte@Sun.COM return (rc);
15987836SJohn.Forte@Sun.COM }
15997836SJohn.Forte@Sun.COM
16007836SJohn.Forte@Sun.COM /*
16017836SJohn.Forte@Sun.COM * rdc_write_refcount
16027836SJohn.Forte@Sun.COM * writes krdc->bitmap_ref to the diskq
16037836SJohn.Forte@Sun.COM * called with qlock held
16047836SJohn.Forte@Sun.COM */
16057836SJohn.Forte@Sun.COM int
rdc_write_refcount(rdc_k_info_t * krdc)16067836SJohn.Forte@Sun.COM rdc_write_refcount(rdc_k_info_t *krdc)
16077836SJohn.Forte@Sun.COM {
16087836SJohn.Forte@Sun.COM int rc;
16097836SJohn.Forte@Sun.COM
16107836SJohn.Forte@Sun.COM rc = _rdc_rdwr_refcnt(krdc, NSC_WRBUF);
16117836SJohn.Forte@Sun.COM
16127836SJohn.Forte@Sun.COM return (rc);
16137836SJohn.Forte@Sun.COM }
16147836SJohn.Forte@Sun.COM
16157836SJohn.Forte@Sun.COM static int
rdc_resume_state(rdc_k_info_t * krdc,const rdc_header_t * header)16167836SJohn.Forte@Sun.COM rdc_resume_state(rdc_k_info_t *krdc, const rdc_header_t *header)
16177836SJohn.Forte@Sun.COM {
16187836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
16197836SJohn.Forte@Sun.COM char *bitmapname;
16207836SJohn.Forte@Sun.COM
16217836SJohn.Forte@Sun.COM urdc = &rdc_u_info[krdc->index];
16227836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_PRIMARY)
16237836SJohn.Forte@Sun.COM bitmapname = &urdc->primary.bitmap[0];
16247836SJohn.Forte@Sun.COM else
16257836SJohn.Forte@Sun.COM bitmapname = &urdc->secondary.bitmap[0];
16267836SJohn.Forte@Sun.COM
16277836SJohn.Forte@Sun.COM if (header->magic != RDC_HDR_MAGIC) {
1628*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_resume_state: Bad magic in %s",
16297836SJohn.Forte@Sun.COM bitmapname);
16307836SJohn.Forte@Sun.COM return (-1);
16317836SJohn.Forte@Sun.COM }
16327836SJohn.Forte@Sun.COM
16337836SJohn.Forte@Sun.COM if (strncmp(urdc->primary.file, header->primary.file,
16347836SJohn.Forte@Sun.COM NSC_MAXPATH) != 0) {
16357836SJohn.Forte@Sun.COM #ifdef DEBUG
16367836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1637*9093SRamana.Srikanth@Sun.COM "!rdc_resume_state: Found %s Expected %s",
16387836SJohn.Forte@Sun.COM header->primary.file, urdc->primary.file);
16397836SJohn.Forte@Sun.COM #endif /* DEBUG */
16407836SJohn.Forte@Sun.COM return (-1);
16417836SJohn.Forte@Sun.COM }
16427836SJohn.Forte@Sun.COM
16437836SJohn.Forte@Sun.COM if (strncmp(urdc->secondary.file, header->secondary.file,
16447836SJohn.Forte@Sun.COM NSC_MAXPATH) != 0) {
16457836SJohn.Forte@Sun.COM #ifdef DEBUG
16467836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1647*9093SRamana.Srikanth@Sun.COM "!rdc_resume_state: Found %s Expected %s",
16487836SJohn.Forte@Sun.COM header->secondary.file, urdc->secondary.file);
16497836SJohn.Forte@Sun.COM #endif /* DEBUG */
16507836SJohn.Forte@Sun.COM return (-1);
16517836SJohn.Forte@Sun.COM }
16527836SJohn.Forte@Sun.COM
16537836SJohn.Forte@Sun.COM if (strncmp(urdc->primary.bitmap, header->primary.bitmap,
16547836SJohn.Forte@Sun.COM NSC_MAXPATH) != 0) {
16557836SJohn.Forte@Sun.COM #ifdef DEBUG
16567836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1657*9093SRamana.Srikanth@Sun.COM "!rdc_resume_state: Found %s Expected %s",
16587836SJohn.Forte@Sun.COM header->primary.bitmap, urdc->primary.bitmap);
16597836SJohn.Forte@Sun.COM #endif /* DEBUG */
16607836SJohn.Forte@Sun.COM return (-1);
16617836SJohn.Forte@Sun.COM }
16627836SJohn.Forte@Sun.COM
16637836SJohn.Forte@Sun.COM if (strncmp(urdc->secondary.bitmap, header->secondary.bitmap,
16647836SJohn.Forte@Sun.COM NSC_MAXPATH) != 0) {
16657836SJohn.Forte@Sun.COM #ifdef DEBUG
16667836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1667*9093SRamana.Srikanth@Sun.COM "!rdc_resume_state: Found %s Expected %s",
16687836SJohn.Forte@Sun.COM header->secondary.bitmap, urdc->secondary.bitmap);
16697836SJohn.Forte@Sun.COM #endif /* DEBUG */
16707836SJohn.Forte@Sun.COM return (-1);
16717836SJohn.Forte@Sun.COM }
16727836SJohn.Forte@Sun.COM
16737836SJohn.Forte@Sun.COM if (header->maxqfbas)
16747836SJohn.Forte@Sun.COM urdc->maxqfbas = header->maxqfbas;
16757836SJohn.Forte@Sun.COM
16767836SJohn.Forte@Sun.COM if (header->maxqitems)
16777836SJohn.Forte@Sun.COM urdc->maxqitems = header->maxqitems;
16787836SJohn.Forte@Sun.COM
16797836SJohn.Forte@Sun.COM if (header->autosync >= 0)
16807836SJohn.Forte@Sun.COM urdc->autosync = header->autosync;
16817836SJohn.Forte@Sun.COM
16827836SJohn.Forte@Sun.COM if (header->asyncthr)
16837836SJohn.Forte@Sun.COM urdc->asyncthr = header->asyncthr;
16847836SJohn.Forte@Sun.COM
16857836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
16867836SJohn.Forte@Sun.COM rdc_set_refcnt_ops(krdc, header->refcntsize);
16877836SJohn.Forte@Sun.COM #ifdef DEBUG_REFCNT
1688*9093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
1689*9093SRamana.Srikanth@Sun.COM (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
16907836SJohn.Forte@Sun.COM #endif
16917836SJohn.Forte@Sun.COM if (header->flags & RDC_VOL_FAILED)
16927836SJohn.Forte@Sun.COM rdc_set_flags(urdc, RDC_VOL_FAILED);
16937836SJohn.Forte@Sun.COM if (header->flags & RDC_QUEUING)
16947836SJohn.Forte@Sun.COM rdc_set_flags(urdc, RDC_QUEUING);
16957836SJohn.Forte@Sun.COM
16967836SJohn.Forte@Sun.COM rdc_clr_flags(urdc, RDC_SYNC_NEEDED | RDC_RSYNC_NEEDED);
16977836SJohn.Forte@Sun.COM rdc_set_mflags(urdc, (header->flags & RDC_RSYNC_NEEDED));
16987836SJohn.Forte@Sun.COM rdc_set_flags(urdc, (header->flags & RDC_SYNC_NEEDED));
16997836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
17007836SJohn.Forte@Sun.COM
17017836SJohn.Forte@Sun.COM if (urdc->flags & RDC_VOL_FAILED) {
17027836SJohn.Forte@Sun.COM
17037836SJohn.Forte@Sun.COM /* Our disk was failed so set all the bits in the bitmap */
17047836SJohn.Forte@Sun.COM
17057836SJohn.Forte@Sun.COM if (RDC_FILL_BITMAP(krdc, TRUE) != 0) {
17067836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1707*9093SRamana.Srikanth@Sun.COM "!rdc_resume_state: Fill bitmap %s failed",
17087836SJohn.Forte@Sun.COM bitmapname);
17097836SJohn.Forte@Sun.COM return (-1);
17107836SJohn.Forte@Sun.COM }
17117836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
17127836SJohn.Forte@Sun.COM if (IS_STATE(urdc, RDC_QUEUING))
17137836SJohn.Forte@Sun.COM rdc_clr_flags(urdc, RDC_QUEUING);
17147836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
17157836SJohn.Forte@Sun.COM } else {
17167836SJohn.Forte@Sun.COM /* Header was good, so read in the bitmap */
17177836SJohn.Forte@Sun.COM
17187836SJohn.Forte@Sun.COM if (rdc_read_bitmap(krdc, NULL) < 0) {
17197836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1720*9093SRamana.Srikanth@Sun.COM "!rdc_resume_state: Read bitmap %s failed",
17217836SJohn.Forte@Sun.COM bitmapname);
17227836SJohn.Forte@Sun.COM return (-1);
17237836SJohn.Forte@Sun.COM }
17247836SJohn.Forte@Sun.COM
17257836SJohn.Forte@Sun.COM urdc->bits_set = RDC_COUNT_BITMAP(krdc);
17267836SJohn.Forte@Sun.COM
17277836SJohn.Forte@Sun.COM /*
17287836SJohn.Forte@Sun.COM * Check if another node went down with bits set, but
17297836SJohn.Forte@Sun.COM * without setting logging mode.
17307836SJohn.Forte@Sun.COM */
17317836SJohn.Forte@Sun.COM if (urdc->bits_set != 0 &&
17327836SJohn.Forte@Sun.COM (rdc_get_vflags(urdc) & RDC_ENABLED) &&
17337836SJohn.Forte@Sun.COM !(rdc_get_vflags(urdc) & RDC_LOGGING)) {
17347836SJohn.Forte@Sun.COM rdc_group_log(krdc, RDC_NOFLUSH | RDC_NOREMOTE, NULL);
17357836SJohn.Forte@Sun.COM }
17367836SJohn.Forte@Sun.COM }
17377836SJohn.Forte@Sun.COM
17387836SJohn.Forte@Sun.COM /* if we are using a disk queue, read in the reference count bits */
17397836SJohn.Forte@Sun.COM if (RDC_IS_DISKQ(krdc->group)) {
17407836SJohn.Forte@Sun.COM disk_queue *q = &krdc->group->diskq;
17417836SJohn.Forte@Sun.COM mutex_enter(QLOCK(q));
17427836SJohn.Forte@Sun.COM if ((rdc_read_refcount(krdc) < 0)) {
17437836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1744*9093SRamana.Srikanth@Sun.COM "!rdc_resume_state: Resume bitmap %s's refcount"
17457836SJohn.Forte@Sun.COM "failed",
17467836SJohn.Forte@Sun.COM urdc->primary.bitmap);
17477836SJohn.Forte@Sun.COM mutex_exit(QLOCK(q));
17487836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
17497836SJohn.Forte@Sun.COM if (IS_STATE(urdc, RDC_QUEUING))
17507836SJohn.Forte@Sun.COM rdc_clr_flags(urdc, RDC_QUEUING);
17517836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
17527836SJohn.Forte@Sun.COM return (-1);
17537836SJohn.Forte@Sun.COM }
17547836SJohn.Forte@Sun.COM mutex_exit(QLOCK(q));
17557836SJohn.Forte@Sun.COM }
17567836SJohn.Forte@Sun.COM
17577836SJohn.Forte@Sun.COM return (0);
17587836SJohn.Forte@Sun.COM }
17597836SJohn.Forte@Sun.COM
17607836SJohn.Forte@Sun.COM
17617836SJohn.Forte@Sun.COM int
rdc_resume_bitmap(rdc_k_info_t * krdc)17627836SJohn.Forte@Sun.COM rdc_resume_bitmap(rdc_k_info_t *krdc)
17637836SJohn.Forte@Sun.COM {
17647836SJohn.Forte@Sun.COM rdc_header_t header;
17657836SJohn.Forte@Sun.COM rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
17667836SJohn.Forte@Sun.COM char *bitmapname;
17677836SJohn.Forte@Sun.COM
17687836SJohn.Forte@Sun.COM if (rdc_alloc_bitmap(krdc) < 0)
17697836SJohn.Forte@Sun.COM goto allocfail;
17707836SJohn.Forte@Sun.COM
17717836SJohn.Forte@Sun.COM if (rdc_open_bitmap(krdc) < 0)
17727836SJohn.Forte@Sun.COM goto fail;
17737836SJohn.Forte@Sun.COM
17747836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_PRIMARY)
17757836SJohn.Forte@Sun.COM bitmapname = &urdc->primary.bitmap[0];
17767836SJohn.Forte@Sun.COM else
17777836SJohn.Forte@Sun.COM bitmapname = &urdc->secondary.bitmap[0];
17787836SJohn.Forte@Sun.COM
17797836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
17807836SJohn.Forte@Sun.COM
17817836SJohn.Forte@Sun.COM rdc_clr_flags(urdc, RDC_BMP_FAILED);
17827836SJohn.Forte@Sun.COM if (rdc_read_header(krdc, &header) < 0) {
17837836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1784*9093SRamana.Srikanth@Sun.COM "!rdc_resume_bitmap: Read header %s failed", bitmapname);
17857836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
17867836SJohn.Forte@Sun.COM goto fail;
17877836SJohn.Forte@Sun.COM }
17887836SJohn.Forte@Sun.COM
17897836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
17907836SJohn.Forte@Sun.COM
17917836SJohn.Forte@Sun.COM /* Resuming from the bitmap, so do some checking */
17927836SJohn.Forte@Sun.COM
17937836SJohn.Forte@Sun.COM /*CONSTCOND*/
17947836SJohn.Forte@Sun.COM ASSERT(FBA_LEN(sizeof (rdc_header_t)) <= RDC_BITMAP_FBA);
17957836SJohn.Forte@Sun.COM /*CONSTCOND*/
17967836SJohn.Forte@Sun.COM ASSERT(sizeof (rdc_header_t) >= sizeof (rdc_headerv2_t));
17977836SJohn.Forte@Sun.COM
17987836SJohn.Forte@Sun.COM if (header.magic == RDC_HDR_V2) {
17997836SJohn.Forte@Sun.COM rdc_headerv2_t *hdr_v2 = (rdc_headerv2_t *)&header;
18007836SJohn.Forte@Sun.COM rdc_header_t new_header;
18017836SJohn.Forte@Sun.COM
18027836SJohn.Forte@Sun.COM #ifdef DEBUG
18037836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1804*9093SRamana.Srikanth@Sun.COM "!rdc_resume_bitmap: Converting v2 header for bitmap %s",
18057836SJohn.Forte@Sun.COM bitmapname);
18067836SJohn.Forte@Sun.COM #endif
18077836SJohn.Forte@Sun.COM bzero((char *)&new_header, sizeof (rdc_header_t));
18087836SJohn.Forte@Sun.COM
18097836SJohn.Forte@Sun.COM new_header.autosync = -1;
18107836SJohn.Forte@Sun.COM new_header.magic = RDC_HDR_MAGIC;
18117836SJohn.Forte@Sun.COM new_header.syshostid = urdc->syshostid;
18127836SJohn.Forte@Sun.COM
18137836SJohn.Forte@Sun.COM if (hdr_v2->volume_failed)
18147836SJohn.Forte@Sun.COM new_header.flags |= RDC_VOL_FAILED;
18157836SJohn.Forte@Sun.COM if (hdr_v2->sync_needed == RDC_SYNC)
18167836SJohn.Forte@Sun.COM new_header.flags |= RDC_SYNC_NEEDED;
18177836SJohn.Forte@Sun.COM if (hdr_v2->sync_needed == RDC_FULL_SYNC)
18187836SJohn.Forte@Sun.COM new_header.flags |= RDC_SYNC_NEEDED;
18197836SJohn.Forte@Sun.COM if (hdr_v2->sync_needed == RDC_REV_SYNC)
18207836SJohn.Forte@Sun.COM new_header.flags |= RDC_RSYNC_NEEDED;
18217836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
18227836SJohn.Forte@Sun.COM (void) strncpy(new_header.primary.file,
18237836SJohn.Forte@Sun.COM hdr_v2->filename, NSC_MAXPATH);
18247836SJohn.Forte@Sun.COM (void) strncpy(new_header.primary.bitmap,
18257836SJohn.Forte@Sun.COM hdr_v2->bitmapname, NSC_MAXPATH);
18267836SJohn.Forte@Sun.COM (void) strncpy(new_header.secondary.file,
18277836SJohn.Forte@Sun.COM urdc->secondary.file, NSC_MAXPATH);
18287836SJohn.Forte@Sun.COM (void) strncpy(new_header.secondary.bitmap,
18297836SJohn.Forte@Sun.COM urdc->secondary.bitmap, NSC_MAXPATH);
18307836SJohn.Forte@Sun.COM } else {
18317836SJohn.Forte@Sun.COM (void) strncpy(new_header.secondary.file,
18327836SJohn.Forte@Sun.COM hdr_v2->filename, NSC_MAXPATH);
18337836SJohn.Forte@Sun.COM (void) strncpy(new_header.secondary.bitmap,
18347836SJohn.Forte@Sun.COM hdr_v2->bitmapname, NSC_MAXPATH);
18357836SJohn.Forte@Sun.COM (void) strncpy(new_header.primary.file,
18367836SJohn.Forte@Sun.COM urdc->primary.file, NSC_MAXPATH);
18377836SJohn.Forte@Sun.COM (void) strncpy(new_header.primary.bitmap,
18387836SJohn.Forte@Sun.COM urdc->primary.bitmap, NSC_MAXPATH);
18397836SJohn.Forte@Sun.COM }
18407836SJohn.Forte@Sun.COM
18417836SJohn.Forte@Sun.COM bcopy(&new_header, &header, sizeof (rdc_header_t));
18427836SJohn.Forte@Sun.COM
18437836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
18447836SJohn.Forte@Sun.COM if (rdc_write_header(krdc, &header) < 0) {
18457836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
18467836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1847*9093SRamana.Srikanth@Sun.COM "!rdc_resume_bitmap: Write header %s failed",
18487836SJohn.Forte@Sun.COM bitmapname);
18497836SJohn.Forte@Sun.COM goto fail;
18507836SJohn.Forte@Sun.COM }
18517836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
18527836SJohn.Forte@Sun.COM
18537836SJohn.Forte@Sun.COM } else if (header.magic == RDC_HDR_V3) {
18547836SJohn.Forte@Sun.COM /*
18557836SJohn.Forte@Sun.COM * just update asyncthr and magic, and then we're done
18567836SJohn.Forte@Sun.COM */
18577836SJohn.Forte@Sun.COM header.magic = RDC_HDR_MAGIC;
18587836SJohn.Forte@Sun.COM header.asyncthr = RDC_ASYNCTHR;
18597836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
18607836SJohn.Forte@Sun.COM if (rdc_write_header(krdc, &header) < 0) {
18617836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
18627836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1863*9093SRamana.Srikanth@Sun.COM "!rdc_resume_bitmap: Write header %s failed",
18647836SJohn.Forte@Sun.COM bitmapname);
18657836SJohn.Forte@Sun.COM goto fail;
18667836SJohn.Forte@Sun.COM }
18677836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
18687836SJohn.Forte@Sun.COM }
18697836SJohn.Forte@Sun.COM
18707836SJohn.Forte@Sun.COM if (rdc_resume_state(krdc, &header) == 0)
18717836SJohn.Forte@Sun.COM return (0);
18727836SJohn.Forte@Sun.COM
18737836SJohn.Forte@Sun.COM rdc_close_bitmap(krdc);
18747836SJohn.Forte@Sun.COM
18757836SJohn.Forte@Sun.COM fail:
18767836SJohn.Forte@Sun.COM (void) RDC_FILL_BITMAP(krdc, FALSE);
18777836SJohn.Forte@Sun.COM rdc_clr_flags(urdc, RDC_QUEUING);
18787836SJohn.Forte@Sun.COM if (krdc->bitmap_ref)
18797836SJohn.Forte@Sun.COM bzero(krdc->bitmap_ref, krdc->bitmap_size * BITS_IN_BYTE *
18807836SJohn.Forte@Sun.COM rdc_refcntsize(krdc));
18817836SJohn.Forte@Sun.COM
18827836SJohn.Forte@Sun.COM allocfail:
18837836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
18847836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "resume bitmap failed");
18857836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
18867836SJohn.Forte@Sun.COM
18877836SJohn.Forte@Sun.COM return (-1);
18887836SJohn.Forte@Sun.COM }
18897836SJohn.Forte@Sun.COM
18907836SJohn.Forte@Sun.COM void
rdc_std_zero_bitref(rdc_k_info_t * krdc)18917836SJohn.Forte@Sun.COM rdc_std_zero_bitref(rdc_k_info_t *krdc)
18927836SJohn.Forte@Sun.COM {
18937836SJohn.Forte@Sun.COM nsc_size_t vol_size;
18947836SJohn.Forte@Sun.COM int sts;
18957836SJohn.Forte@Sun.COM size_t newrefcntsize;
18967836SJohn.Forte@Sun.COM
18977836SJohn.Forte@Sun.COM if (krdc->bitmap_ref) {
18987836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
18997836SJohn.Forte@Sun.COM bzero(krdc->bitmap_ref, krdc->bitmap_size * BITS_IN_BYTE *
19007836SJohn.Forte@Sun.COM BMAP_REF_PREF_SIZE);
19017836SJohn.Forte@Sun.COM if (RDC_IS_DISKQ(krdc->group) && rdc_refcntsize(krdc) !=
19027836SJohn.Forte@Sun.COM BMAP_REF_PREF_SIZE) {
19037836SJohn.Forte@Sun.COM /* see if we can upgrade the size of the ref counters */
19047836SJohn.Forte@Sun.COM sts = _rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL);
19057836SJohn.Forte@Sun.COM if (!RDC_SUCCESS(sts)) {
19067836SJohn.Forte@Sun.COM goto nochange;
19077836SJohn.Forte@Sun.COM }
19087836SJohn.Forte@Sun.COM sts = nsc_partsize(krdc->bitmapfd, &vol_size);
19097836SJohn.Forte@Sun.COM
19107836SJohn.Forte@Sun.COM newrefcntsize = rdc_ref_size_possible(krdc->bitmap_size,
1911*9093SRamana.Srikanth@Sun.COM vol_size);
19127836SJohn.Forte@Sun.COM if (newrefcntsize > rdc_refcntsize(krdc)) {
19137836SJohn.Forte@Sun.COM rdc_set_refcnt_ops(krdc, newrefcntsize);
19147836SJohn.Forte@Sun.COM #ifdef DEBUG_REFCNT
1915*9093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
1916*9093SRamana.Srikanth@Sun.COM (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
19177836SJohn.Forte@Sun.COM #endif
19187836SJohn.Forte@Sun.COM }
19197836SJohn.Forte@Sun.COM nochange:
19207836SJohn.Forte@Sun.COM _rdc_rlse_devs(krdc, RDC_BMP);
19217836SJohn.Forte@Sun.COM }
19227836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
19237836SJohn.Forte@Sun.COM }
19247836SJohn.Forte@Sun.COM }
19257836SJohn.Forte@Sun.COM
19267836SJohn.Forte@Sun.COM int
rdc_reset_bitmap(rdc_k_info_t * krdc)19277836SJohn.Forte@Sun.COM rdc_reset_bitmap(rdc_k_info_t *krdc)
19287836SJohn.Forte@Sun.COM {
19297836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
19307836SJohn.Forte@Sun.COM rdc_header_t header;
19317836SJohn.Forte@Sun.COM char *bitmapname;
19327836SJohn.Forte@Sun.COM
19337836SJohn.Forte@Sun.COM urdc = &rdc_u_info[krdc->index];
19347836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_PRIMARY)
19357836SJohn.Forte@Sun.COM bitmapname = &urdc->primary.bitmap[0];
19367836SJohn.Forte@Sun.COM else
19377836SJohn.Forte@Sun.COM bitmapname = &urdc->secondary.bitmap[0];
19387836SJohn.Forte@Sun.COM
19397836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
19407836SJohn.Forte@Sun.COM
19417836SJohn.Forte@Sun.COM rdc_clr_flags(urdc, RDC_BMP_FAILED);
19427836SJohn.Forte@Sun.COM if (rdc_read_header(krdc, &header) < 0) {
19437836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1944*9093SRamana.Srikanth@Sun.COM "!rdc_reset_bitmap: Read header %s failed", bitmapname);
19457836SJohn.Forte@Sun.COM goto fail_with_mutex;
19467836SJohn.Forte@Sun.COM }
19477836SJohn.Forte@Sun.COM
19487836SJohn.Forte@Sun.COM rdc_fill_header(urdc, &header);
19497836SJohn.Forte@Sun.COM
19507836SJohn.Forte@Sun.COM if (rdc_write_header(krdc, &header) < 0) {
19517836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1952*9093SRamana.Srikanth@Sun.COM "!rdc_reset_bitmap: Write header %s failed",
19537836SJohn.Forte@Sun.COM bitmapname);
19547836SJohn.Forte@Sun.COM goto fail_with_mutex;
19557836SJohn.Forte@Sun.COM }
19567836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
19577836SJohn.Forte@Sun.COM
19587836SJohn.Forte@Sun.COM if (krdc->bitmap_write == -1)
19597836SJohn.Forte@Sun.COM krdc->bitmap_write = 0;
19607836SJohn.Forte@Sun.COM
19617836SJohn.Forte@Sun.COM if (krdc->bitmap_write == 0) {
19627836SJohn.Forte@Sun.COM if (rdc_write_bitmap_fill(krdc) < 0) {
19637836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1964*9093SRamana.Srikanth@Sun.COM "!rdc_reset_bitmap: Write bitmap %s failed",
19657836SJohn.Forte@Sun.COM bitmapname);
19667836SJohn.Forte@Sun.COM goto fail;
19677836SJohn.Forte@Sun.COM }
19687836SJohn.Forte@Sun.COM krdc->bitmap_write = -1;
19697836SJohn.Forte@Sun.COM } else if (rdc_write_bitmap(krdc) < 0) {
19707836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
1971*9093SRamana.Srikanth@Sun.COM "!rdc_reset_bitmap: Write bitmap %s failed",
19727836SJohn.Forte@Sun.COM bitmapname);
19737836SJohn.Forte@Sun.COM goto fail;
19747836SJohn.Forte@Sun.COM }
19757836SJohn.Forte@Sun.COM
19767836SJohn.Forte@Sun.COM return (0);
19777836SJohn.Forte@Sun.COM
19787836SJohn.Forte@Sun.COM fail:
19797836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
19807836SJohn.Forte@Sun.COM fail_with_mutex:
19817836SJohn.Forte@Sun.COM rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reset failed");
19827836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
19837836SJohn.Forte@Sun.COM #ifdef DEBUG
1984*9093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!SNDR: unable to reset bitmap for %s:%s",
1985*9093SRamana.Srikanth@Sun.COM urdc->secondary.intf, urdc->secondary.file);
19867836SJohn.Forte@Sun.COM #endif
19877836SJohn.Forte@Sun.COM return (-1);
19887836SJohn.Forte@Sun.COM }
19897836SJohn.Forte@Sun.COM
19907836SJohn.Forte@Sun.COM
19917836SJohn.Forte@Sun.COM /*
19927836SJohn.Forte@Sun.COM * General bitmap operations
19937836SJohn.Forte@Sun.COM */
19947836SJohn.Forte@Sun.COM
19957836SJohn.Forte@Sun.COM /*
19967836SJohn.Forte@Sun.COM * rdc_set_bitmap_many()
19977836SJohn.Forte@Sun.COM *
19987836SJohn.Forte@Sun.COM * Used during reverse syncs to a 1-to-many primary to keep the 'many'
19997836SJohn.Forte@Sun.COM * bitmaps up to date.
20007836SJohn.Forte@Sun.COM */
20017836SJohn.Forte@Sun.COM void
rdc_set_bitmap_many(rdc_k_info_t * krdc,nsc_off_t pos,nsc_size_t len)20027836SJohn.Forte@Sun.COM rdc_set_bitmap_many(rdc_k_info_t *krdc, nsc_off_t pos, nsc_size_t len)
20037836SJohn.Forte@Sun.COM {
20047836SJohn.Forte@Sun.COM uint_t dummy;
20057836SJohn.Forte@Sun.COM
20067836SJohn.Forte@Sun.COM #ifdef DEBUG
20077836SJohn.Forte@Sun.COM rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
20087836SJohn.Forte@Sun.COM if (!(rdc_get_vflags(urdc) & RDC_PRIMARY)) {
20097836SJohn.Forte@Sun.COM cmn_err(CE_PANIC, "rdc_set_bitmap_many: not primary, urdc %p",
20107836SJohn.Forte@Sun.COM (void *) urdc);
20117836SJohn.Forte@Sun.COM }
20127836SJohn.Forte@Sun.COM #endif
20137836SJohn.Forte@Sun.COM
20147836SJohn.Forte@Sun.COM if (IS_MANY(krdc)) {
20157836SJohn.Forte@Sun.COM rdc_k_info_t *krd;
20167836SJohn.Forte@Sun.COM rdc_u_info_t *urd;
20177836SJohn.Forte@Sun.COM
20187836SJohn.Forte@Sun.COM rdc_many_enter(krdc);
20197836SJohn.Forte@Sun.COM
20207836SJohn.Forte@Sun.COM for (krd = krdc->many_next; krd != krdc; krd = krd->many_next) {
20217836SJohn.Forte@Sun.COM urd = &rdc_u_info[krd->index];
20227836SJohn.Forte@Sun.COM if (!IS_ENABLED(urd))
20237836SJohn.Forte@Sun.COM continue;
20247836SJohn.Forte@Sun.COM ASSERT(urd->flags & RDC_PRIMARY);
20257836SJohn.Forte@Sun.COM (void) RDC_SET_BITMAP(krd, pos, len, &dummy);
20267836SJohn.Forte@Sun.COM }
20277836SJohn.Forte@Sun.COM
20287836SJohn.Forte@Sun.COM rdc_many_exit(krdc);
20297836SJohn.Forte@Sun.COM }
20307836SJohn.Forte@Sun.COM }
20317836SJohn.Forte@Sun.COM
20327836SJohn.Forte@Sun.COM
20337836SJohn.Forte@Sun.COM static int
_rdc_net_bmap(const struct bmap6 * b6,net_bdata6 * bd6)20347836SJohn.Forte@Sun.COM _rdc_net_bmap(const struct bmap6 *b6, net_bdata6 *bd6)
20357836SJohn.Forte@Sun.COM {
20367836SJohn.Forte@Sun.COM rdc_k_info_t *krdc = &rdc_k_info[b6->cd];
20377836SJohn.Forte@Sun.COM struct timeval t;
20387836SJohn.Forte@Sun.COM int e, ret;
20397836SJohn.Forte@Sun.COM uint64_t left;
2040*9093SRamana.Srikanth@Sun.COM uint64_t bmap_blksize;
2041*9093SRamana.Srikanth@Sun.COM
2042*9093SRamana.Srikanth@Sun.COM bmap_blksize = krdc->rpc_version < RDC_VERSION7 ?
2043*9093SRamana.Srikanth@Sun.COM BMAP_BLKSIZE : BMAP_BLKSIZEV7;
20447836SJohn.Forte@Sun.COM
20457836SJohn.Forte@Sun.COM t.tv_sec = rdc_rpc_tmout;
20467836SJohn.Forte@Sun.COM t.tv_usec = 0;
20477836SJohn.Forte@Sun.COM
20487836SJohn.Forte@Sun.COM if (bd6->data.data_val == NULL) {
20497836SJohn.Forte@Sun.COM return (EINVAL);
20507836SJohn.Forte@Sun.COM }
20517836SJohn.Forte@Sun.COM
20527836SJohn.Forte@Sun.COM left = b6->size;
20537836SJohn.Forte@Sun.COM bd6->endoblk = 0;
20547836SJohn.Forte@Sun.COM while (left) {
20557836SJohn.Forte@Sun.COM if (left >= bmap_blksize)
20567836SJohn.Forte@Sun.COM bd6->size = (int)bmap_blksize;
20577836SJohn.Forte@Sun.COM else
20587836SJohn.Forte@Sun.COM bd6->size = (int)left;
20597836SJohn.Forte@Sun.COM
20607836SJohn.Forte@Sun.COM bd6->data.data_len = bd6->size;
20617836SJohn.Forte@Sun.COM
20627836SJohn.Forte@Sun.COM if ((uint64_t)bd6->size > left) {
20637836SJohn.Forte@Sun.COM left = 0;
20647836SJohn.Forte@Sun.COM } else {
20657836SJohn.Forte@Sun.COM left -= bd6->size;
20667836SJohn.Forte@Sun.COM }
20677836SJohn.Forte@Sun.COM /*
20687836SJohn.Forte@Sun.COM * mark the last block sent.
20697836SJohn.Forte@Sun.COM */
20707836SJohn.Forte@Sun.COM if (left == 0) {
20717836SJohn.Forte@Sun.COM bd6->endoblk = 1;
20727836SJohn.Forte@Sun.COM }
20737836SJohn.Forte@Sun.COM ASSERT(krdc->rpc_version);
20747836SJohn.Forte@Sun.COM if (krdc->rpc_version <= RDC_VERSION5) {
20757836SJohn.Forte@Sun.COM struct net_bdata bd;
20767836SJohn.Forte@Sun.COM bd.cd = bd6->cd;
20777836SJohn.Forte@Sun.COM bd.offset = bd6->offset;
20787836SJohn.Forte@Sun.COM bd.size = bd6->size;
20797836SJohn.Forte@Sun.COM bd.data.data_len = bd6->data.data_len;
20807836SJohn.Forte@Sun.COM bd.data.data_val = bd6->data.data_val;
20817836SJohn.Forte@Sun.COM e = rdc_clnt_call(krdc->lsrv, RDCPROC_BDATA,
20827836SJohn.Forte@Sun.COM krdc->rpc_version, xdr_net_bdata, (char *)&bd,
20837836SJohn.Forte@Sun.COM xdr_int, (char *)&ret, &t);
20847836SJohn.Forte@Sun.COM } else {
20857836SJohn.Forte@Sun.COM e = rdc_clnt_call(krdc->lsrv, RDCPROC_BDATA6,
20867836SJohn.Forte@Sun.COM krdc->rpc_version, xdr_net_bdata6, (char *)bd6,
20877836SJohn.Forte@Sun.COM xdr_int, (char *)&ret, &t);
20887836SJohn.Forte@Sun.COM }
20897836SJohn.Forte@Sun.COM if (e || ret) {
20907836SJohn.Forte@Sun.COM if (e)
20917836SJohn.Forte@Sun.COM ret = e;
20927836SJohn.Forte@Sun.COM return (ret);
20937836SJohn.Forte@Sun.COM }
20947836SJohn.Forte@Sun.COM bd6->offset += bmap_blksize;
20957836SJohn.Forte@Sun.COM bd6->data.data_val += bmap_blksize;
20967836SJohn.Forte@Sun.COM }
20977836SJohn.Forte@Sun.COM return (0);
20987836SJohn.Forte@Sun.COM }
20997836SJohn.Forte@Sun.COM
21007836SJohn.Forte@Sun.COM
21017836SJohn.Forte@Sun.COM /*
21027836SJohn.Forte@Sun.COM * Standard bitmap operations (combined kmem/disk bitmaps).
21037836SJohn.Forte@Sun.COM */
21047836SJohn.Forte@Sun.COM
21057836SJohn.Forte@Sun.COM /*
21067836SJohn.Forte@Sun.COM * rdc_std_set_bitmask(pos, len, &bitmask)
21077836SJohn.Forte@Sun.COM * set a bitmask for this range. used to clear the correct
21087836SJohn.Forte@Sun.COM * bits after flushing
21097836SJohn.Forte@Sun.COM */
21107836SJohn.Forte@Sun.COM static void
rdc_std_set_bitmask(const nsc_off_t fba_pos,const nsc_size_t fba_len,uint_t * bitmask)21117836SJohn.Forte@Sun.COM rdc_std_set_bitmask(const nsc_off_t fba_pos, const nsc_size_t fba_len,
21127836SJohn.Forte@Sun.COM uint_t *bitmask)
21137836SJohn.Forte@Sun.COM {
21147836SJohn.Forte@Sun.COM int first, st, en;
21157836SJohn.Forte@Sun.COM if (bitmask)
21167836SJohn.Forte@Sun.COM *bitmask = 0;
21177836SJohn.Forte@Sun.COM else
21187836SJohn.Forte@Sun.COM return;
21197836SJohn.Forte@Sun.COM
21207836SJohn.Forte@Sun.COM first = st = FBA_TO_LOG_NUM(fba_pos);
21217836SJohn.Forte@Sun.COM en = FBA_TO_LOG_NUM(fba_pos + fba_len - 1);
21227836SJohn.Forte@Sun.COM while (st <= en) {
21237836SJohn.Forte@Sun.COM BMAP_BIT_SET((uchar_t *)bitmask, st - first);
21247836SJohn.Forte@Sun.COM st++;
21257836SJohn.Forte@Sun.COM }
21267836SJohn.Forte@Sun.COM
21277836SJohn.Forte@Sun.COM }
21287836SJohn.Forte@Sun.COM /*
21297836SJohn.Forte@Sun.COM * rdc_std_set_bitmap(krdc, fba_pos, fba_len, &bitmask)
21307836SJohn.Forte@Sun.COM *
21317836SJohn.Forte@Sun.COM * Mark modified segments in the dual copy file bitmap
21327836SJohn.Forte@Sun.COM * to provide fast recovery
21337836SJohn.Forte@Sun.COM * Note that bitmask allows for 32 segments, which at 32k per segment equals
21347836SJohn.Forte@Sun.COM * 1 megabyte. If we ever allow more than this to be transferred in one
21357836SJohn.Forte@Sun.COM * operation, or decrease the segment size, then this code will have to be
21367836SJohn.Forte@Sun.COM * changed accordingly.
21377836SJohn.Forte@Sun.COM */
21387836SJohn.Forte@Sun.COM
21397836SJohn.Forte@Sun.COM static int
rdc_std_set_bitmap(rdc_k_info_t * krdc,const nsc_off_t fba_pos,const nsc_size_t fba_len,uint_t * bitmask)21407836SJohn.Forte@Sun.COM rdc_std_set_bitmap(rdc_k_info_t *krdc, const nsc_off_t fba_pos,
21417836SJohn.Forte@Sun.COM const nsc_size_t fba_len, uint_t *bitmask)
21427836SJohn.Forte@Sun.COM {
21437836SJohn.Forte@Sun.COM int first, st, en;
21447836SJohn.Forte@Sun.COM int fbaset = 0;
21457836SJohn.Forte@Sun.COM nsc_off_t fba = 0;
21467836SJohn.Forte@Sun.COM int printerr = 10;
21477836SJohn.Forte@Sun.COM int tries = RDC_FUTILE_ATTEMPTS;
21487836SJohn.Forte@Sun.COM int queuing = RDC_QUEUING;
21497836SJohn.Forte@Sun.COM rdc_u_info_t *urdc;
21507836SJohn.Forte@Sun.COM
21517836SJohn.Forte@Sun.COM if (bitmask)
21527836SJohn.Forte@Sun.COM *bitmask = 0;
21537836SJohn.Forte@Sun.COM else
21547836SJohn.Forte@Sun.COM return (-1);
21557836SJohn.Forte@Sun.COM
21567836SJohn.Forte@Sun.COM urdc = &rdc_u_info[krdc->index];
21577836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_BMP_FAILED)
21587836SJohn.Forte@Sun.COM return (-1);
21597836SJohn.Forte@Sun.COM
21607836SJohn.Forte@Sun.COM if (krdc->bitmap_write == 0) {
21617836SJohn.Forte@Sun.COM if (rdc_write_bitmap_fill(krdc) < 0)
21627836SJohn.Forte@Sun.COM return (-1);
21637836SJohn.Forte@Sun.COM krdc->bitmap_write = -1;
21647836SJohn.Forte@Sun.COM }
21657836SJohn.Forte@Sun.COM first = st = FBA_TO_LOG_NUM(fba_pos);
21667836SJohn.Forte@Sun.COM en = FBA_TO_LOG_NUM(fba_pos + fba_len - 1);
21677836SJohn.Forte@Sun.COM ASSERT(st <= en);
21687836SJohn.Forte@Sun.COM while (st <= en) {
21697836SJohn.Forte@Sun.COM int use_ref;
21707836SJohn.Forte@Sun.COM again:
21717836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
21727836SJohn.Forte@Sun.COM
21737836SJohn.Forte@Sun.COM if (krdc->dcio_bitmap == NULL) {
21747836SJohn.Forte@Sun.COM #ifdef DEBUG
2175*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_std_set_bitmap: "
2176*9093SRamana.Srikanth@Sun.COM "recovery bitmaps not allocated");
21777836SJohn.Forte@Sun.COM #endif
2178*9093SRamana.Srikanth@Sun.COM mutex_exit(&krdc->bmapmutex);
2179*9093SRamana.Srikanth@Sun.COM return (-1);
21807836SJohn.Forte@Sun.COM }
21817836SJohn.Forte@Sun.COM
21827836SJohn.Forte@Sun.COM use_ref = IS_PRIMARY(urdc) && IS_ASYNC(urdc) &&
21837836SJohn.Forte@Sun.COM ((rdc_get_vflags(urdc) & RDC_QUEUING) ||
21847836SJohn.Forte@Sun.COM !(rdc_get_vflags(urdc) & RDC_LOGGING));
21857836SJohn.Forte@Sun.COM
21867836SJohn.Forte@Sun.COM
21877836SJohn.Forte@Sun.COM if (!BMAP_BIT_ISSET(krdc->dcio_bitmap, st)) {
21887836SJohn.Forte@Sun.COM BMAP_BIT_SET(krdc->dcio_bitmap, st);
21897836SJohn.Forte@Sun.COM if (use_ref) {
21907836SJohn.Forte@Sun.COM ASSERT(BMAP_REF_ISSET(krdc, st) ==
21917836SJohn.Forte@Sun.COM 0);
21927836SJohn.Forte@Sun.COM BMAP_REF_FORCE(krdc, st, 1);
21937836SJohn.Forte@Sun.COM }
21947836SJohn.Forte@Sun.COM BMAP_BIT_SET((uchar_t *)bitmask, st - first);
21957836SJohn.Forte@Sun.COM urdc->bits_set++;
21967836SJohn.Forte@Sun.COM if ((!fbaset) || fba != BIT_TO_FBA(st)) {
21977836SJohn.Forte@Sun.COM if (fbaset && krdc->bitmap_write > 0) {
21987836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
21997836SJohn.Forte@Sun.COM if (rdc_write_bitmap_fba(krdc, fba) < 0)
22007836SJohn.Forte@Sun.COM return (-1);
22017836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
22027836SJohn.Forte@Sun.COM }
22037836SJohn.Forte@Sun.COM fba = BIT_TO_FBA(st);
22047836SJohn.Forte@Sun.COM fbaset = 1;
22057836SJohn.Forte@Sun.COM }
22067836SJohn.Forte@Sun.COM } else {
22077836SJohn.Forte@Sun.COM /*
22087836SJohn.Forte@Sun.COM * Just bump reference count
22097836SJohn.Forte@Sun.COM * For logging or syncing we do not care what the reference
22107836SJohn.Forte@Sun.COM * is as it will be forced back on the state transition.
22117836SJohn.Forte@Sun.COM */
22127836SJohn.Forte@Sun.COM if (use_ref) {
22137836SJohn.Forte@Sun.COM if (BMAP_REF_ISSET(krdc, st) ==
22147836SJohn.Forte@Sun.COM BMAP_REF_MAXVAL(krdc)) {
22157836SJohn.Forte@Sun.COM /*
22167836SJohn.Forte@Sun.COM * Rollover of reference count.
22177836SJohn.Forte@Sun.COM */
22187836SJohn.Forte@Sun.COM
22197836SJohn.Forte@Sun.COM if (!(rdc_get_vflags(urdc) &
22207836SJohn.Forte@Sun.COM RDC_VOL_FAILED)) {
22217836SJohn.Forte@Sun.COM /*
22227836SJohn.Forte@Sun.COM * Impose throttle to help dump
22237836SJohn.Forte@Sun.COM * queue
22247836SJohn.Forte@Sun.COM */
22257836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
22267836SJohn.Forte@Sun.COM delay(4);
22277836SJohn.Forte@Sun.COM rdc_bitmap_delay++;
22287836SJohn.Forte@Sun.COM if (printerr--) {
2229*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!SNDR: bitmap reference count maxed out for %s:%s",
22307836SJohn.Forte@Sun.COM urdc->secondary.intf, urdc->secondary.file);
22317836SJohn.Forte@Sun.COM
22327836SJohn.Forte@Sun.COM }
22337836SJohn.Forte@Sun.COM
22347836SJohn.Forte@Sun.COM if ((tries-- <= 0) &&
22357836SJohn.Forte@Sun.COM IS_STATE(urdc, queuing)) {
2236*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!SNDR: giving up on reference count, logging set"
22377836SJohn.Forte@Sun.COM " %s:%s", urdc->secondary.intf, urdc->secondary.file);
22387836SJohn.Forte@Sun.COM rdc_group_enter(krdc);
22397836SJohn.Forte@Sun.COM rdc_group_log(krdc,
22407836SJohn.Forte@Sun.COM RDC_NOFLUSH |
22417836SJohn.Forte@Sun.COM RDC_NOREMOTE|
22427836SJohn.Forte@Sun.COM RDC_FORCE_GROUP,
22437836SJohn.Forte@Sun.COM "ref count retry limit exceeded");
22447836SJohn.Forte@Sun.COM rdc_group_exit(krdc);
22457836SJohn.Forte@Sun.COM }
22467836SJohn.Forte@Sun.COM goto again;
22477836SJohn.Forte@Sun.COM }
22487836SJohn.Forte@Sun.COM } else {
22497836SJohn.Forte@Sun.COM BMAP_REF_SET(krdc, st);
22507836SJohn.Forte@Sun.COM }
22517836SJohn.Forte@Sun.COM }
22527836SJohn.Forte@Sun.COM }
22537836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
22547836SJohn.Forte@Sun.COM st++;
22557836SJohn.Forte@Sun.COM }
22567836SJohn.Forte@Sun.COM if (fbaset && krdc->bitmap_write > 0) {
22577836SJohn.Forte@Sun.COM if (rdc_write_bitmap_fba(krdc, fba) < 0)
22587836SJohn.Forte@Sun.COM return (-1);
22597836SJohn.Forte@Sun.COM }
22607836SJohn.Forte@Sun.COM return (0);
22617836SJohn.Forte@Sun.COM }
22627836SJohn.Forte@Sun.COM
22637836SJohn.Forte@Sun.COM static void
rdc_std_clr_bitmap(rdc_k_info_t * krdc,const nsc_off_t fba_pos,const nsc_size_t fba_len,const uint_t bitmask,const int force)22647836SJohn.Forte@Sun.COM rdc_std_clr_bitmap(rdc_k_info_t *krdc, const nsc_off_t fba_pos,
22657836SJohn.Forte@Sun.COM const nsc_size_t fba_len, const uint_t bitmask, const int force)
22667836SJohn.Forte@Sun.COM {
22677836SJohn.Forte@Sun.COM int first, st, en;
22687836SJohn.Forte@Sun.COM nsc_off_t fba = 0;
22697836SJohn.Forte@Sun.COM int fbaset = 0;
22707836SJohn.Forte@Sun.COM uint_t bm = bitmask;
22717836SJohn.Forte@Sun.COM uchar_t *ptr = (uchar_t *)&bm;
22727836SJohn.Forte@Sun.COM rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
22737836SJohn.Forte@Sun.COM
22747836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_BMP_FAILED)
22757836SJohn.Forte@Sun.COM return;
22767836SJohn.Forte@Sun.COM
22777836SJohn.Forte@Sun.COM first = st = FBA_TO_LOG_NUM(fba_pos);
22787836SJohn.Forte@Sun.COM en = FBA_TO_LOG_NUM(fba_pos + fba_len - 1);
22797836SJohn.Forte@Sun.COM ASSERT(st <= en);
22807836SJohn.Forte@Sun.COM while (st <= en) {
22817836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
22827836SJohn.Forte@Sun.COM
22837836SJohn.Forte@Sun.COM if (krdc->dcio_bitmap == NULL) {
22847836SJohn.Forte@Sun.COM #ifdef DEBUG
2285*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_std_clr_bitmap: "
2286*9093SRamana.Srikanth@Sun.COM "recovery bitmaps not allocated");
22877836SJohn.Forte@Sun.COM #endif
2288*9093SRamana.Srikanth@Sun.COM mutex_exit(&krdc->bmapmutex);
2289*9093SRamana.Srikanth@Sun.COM return;
22907836SJohn.Forte@Sun.COM }
22917836SJohn.Forte@Sun.COM
22927836SJohn.Forte@Sun.COM if (((bitmask == 0xffffffff) ||
22937836SJohn.Forte@Sun.COM (BMAP_BIT_ISSET(ptr, st - first))) &&
22947836SJohn.Forte@Sun.COM BMAP_BIT_ISSET(krdc->dcio_bitmap, st)) {
22957836SJohn.Forte@Sun.COM
22967836SJohn.Forte@Sun.COM int use_ref = IS_PRIMARY(urdc) && IS_ASYNC(urdc) &&
22977836SJohn.Forte@Sun.COM ((rdc_get_vflags(urdc) & RDC_QUEUING) ||
22987836SJohn.Forte@Sun.COM !(rdc_get_vflags(urdc) & RDC_LOGGING));
22997836SJohn.Forte@Sun.COM
23007836SJohn.Forte@Sun.COM if (force || (use_ref == 0)) {
23017836SJohn.Forte@Sun.COM if (krdc->bitmap_ref)
23027836SJohn.Forte@Sun.COM BMAP_REF_FORCE(krdc, st, 0);
23037836SJohn.Forte@Sun.COM } else if (use_ref) {
23047836SJohn.Forte@Sun.COM if (BMAP_REF_ISSET(krdc, st) != 0)
23057836SJohn.Forte@Sun.COM BMAP_REF_CLR(krdc, st);
23067836SJohn.Forte@Sun.COM
23077836SJohn.Forte@Sun.COM }
23087836SJohn.Forte@Sun.COM
23097836SJohn.Forte@Sun.COM if ((use_ref == 0) || (use_ref &&
23107836SJohn.Forte@Sun.COM !BMAP_REF_ISSET(krdc, st))) {
23117836SJohn.Forte@Sun.COM BMAP_BIT_CLR(krdc->dcio_bitmap, st);
23127836SJohn.Forte@Sun.COM
23137836SJohn.Forte@Sun.COM urdc->bits_set--;
23147836SJohn.Forte@Sun.COM if (!fbaset || fba != BIT_TO_FBA(st)) {
23157836SJohn.Forte@Sun.COM if (fbaset &&
2316*9093SRamana.Srikanth@Sun.COM krdc->bitmap_write > 0) {
23177836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
23187836SJohn.Forte@Sun.COM if (rdc_write_bitmap_fba(krdc,
23197836SJohn.Forte@Sun.COM fba) < 0)
23207836SJohn.Forte@Sun.COM return;
23217836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
23227836SJohn.Forte@Sun.COM }
23237836SJohn.Forte@Sun.COM fba = BIT_TO_FBA(st);
23247836SJohn.Forte@Sun.COM fbaset = 1;
23257836SJohn.Forte@Sun.COM }
23267836SJohn.Forte@Sun.COM }
23277836SJohn.Forte@Sun.COM }
23287836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
23297836SJohn.Forte@Sun.COM st++;
23307836SJohn.Forte@Sun.COM }
23317836SJohn.Forte@Sun.COM if (fbaset && krdc->bitmap_write > 0) {
23327836SJohn.Forte@Sun.COM if (rdc_write_bitmap_fba(krdc, fba) < 0)
23337836SJohn.Forte@Sun.COM return;
23347836SJohn.Forte@Sun.COM }
23357836SJohn.Forte@Sun.COM }
23367836SJohn.Forte@Sun.COM
23377836SJohn.Forte@Sun.COM /*
23387836SJohn.Forte@Sun.COM * make sure that this bit is set. if it isn't, set it
23397836SJohn.Forte@Sun.COM * used when transitioning from async to sync while going
23407836SJohn.Forte@Sun.COM * from rep to log. an overlapping sync write may unconditionally
23417836SJohn.Forte@Sun.COM * clear the bit that has not been replicated. when the queue
23427836SJohn.Forte@Sun.COM * is being dumped or this is called just to make sure pending stuff
23437836SJohn.Forte@Sun.COM * is in the bitmap
23447836SJohn.Forte@Sun.COM */
23457836SJohn.Forte@Sun.COM void
rdc_std_check_bit(rdc_k_info_t * krdc,nsc_off_t pos,nsc_size_t len)23467836SJohn.Forte@Sun.COM rdc_std_check_bit(rdc_k_info_t *krdc, nsc_off_t pos, nsc_size_t len)
23477836SJohn.Forte@Sun.COM {
23487836SJohn.Forte@Sun.COM int st;
23497836SJohn.Forte@Sun.COM int en;
23507836SJohn.Forte@Sun.COM nsc_off_t fba;
23517836SJohn.Forte@Sun.COM rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
23527836SJohn.Forte@Sun.COM st = FBA_TO_LOG_NUM(pos);
23537836SJohn.Forte@Sun.COM en = FBA_TO_LOG_NUM(pos + len - 1);
23547836SJohn.Forte@Sun.COM
23557836SJohn.Forte@Sun.COM if (rdc_get_vflags(urdc) & RDC_BMP_FAILED)
23567836SJohn.Forte@Sun.COM return;
23577836SJohn.Forte@Sun.COM
23587836SJohn.Forte@Sun.COM while (st <= en) {
23597836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
23607836SJohn.Forte@Sun.COM
23617836SJohn.Forte@Sun.COM if (krdc->dcio_bitmap == NULL) {
23627836SJohn.Forte@Sun.COM #ifdef DEBUG
2363*9093SRamana.Srikanth@Sun.COM cmn_err(CE_WARN, "!rdc_std_check_bit: "
2364*9093SRamana.Srikanth@Sun.COM "recovery bitmaps not allocated");
23657836SJohn.Forte@Sun.COM #endif
2366*9093SRamana.Srikanth@Sun.COM mutex_exit(&krdc->bmapmutex);
2367*9093SRamana.Srikanth@Sun.COM return;
23687836SJohn.Forte@Sun.COM }
23697836SJohn.Forte@Sun.COM
23707836SJohn.Forte@Sun.COM if (!BMAP_BIT_ISSET(krdc->dcio_bitmap, st)) {
23717836SJohn.Forte@Sun.COM BMAP_BIT_SET(krdc->dcio_bitmap, st);
23727836SJohn.Forte@Sun.COM if (krdc->bitmap_write > 0) {
23737836SJohn.Forte@Sun.COM fba = BIT_TO_FBA(st);
23747836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
23757836SJohn.Forte@Sun.COM (void) rdc_write_bitmap_fba(krdc, fba);
23767836SJohn.Forte@Sun.COM mutex_enter(&krdc->bmapmutex);
23777836SJohn.Forte@Sun.COM }
23787836SJohn.Forte@Sun.COM urdc->bits_set++;
23797836SJohn.Forte@Sun.COM
23807836SJohn.Forte@Sun.COM }
23817836SJohn.Forte@Sun.COM mutex_exit(&krdc->bmapmutex);
23827836SJohn.Forte@Sun.COM st++;
23837836SJohn.Forte@Sun.COM }
23847836SJohn.Forte@Sun.COM
23857836SJohn.Forte@Sun.COM }
23867836SJohn.Forte@Sun.COM
23877836SJohn.Forte@Sun.COM /*
23887836SJohn.Forte@Sun.COM * rdc_std_count_dirty(krdc):
23897836SJohn.Forte@Sun.COM *
23907836SJohn.Forte@Sun.COM * Determine the number of segments that need to be flushed, This should
23917836SJohn.Forte@Sun.COM * agree with the number of segments logged, but since we don't lock when
23927836SJohn.Forte@Sun.COM * we increment, we force these values to agree
23937836SJohn.Forte@Sun.COM */
23947836SJohn.Forte@Sun.COM static int
rdc_std_count_dirty(rdc_k_info_t * krdc)23957836SJohn.Forte@Sun.COM rdc_std_count_dirty(rdc_k_info_t *krdc)
23967836SJohn.Forte@Sun.COM {
23977836SJohn.Forte@Sun.COM rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
23987836SJohn.Forte@Sun.COM int i, count, size;
23997836SJohn.Forte@Sun.COM
24007836SJohn.Forte@Sun.COM if (krdc->dcio_bitmap == NULL) {
24017836SJohn.Forte@Sun.COM #ifdef DEBUG
24027836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
2403*9093SRamana.Srikanth@Sun.COM "!rdc_std_count_dirty: no bitmap configured for %s",
24047836SJohn.Forte@Sun.COM urdc->primary.file);
24057836SJohn.Forte@Sun.COM #endif
24067836SJohn.Forte@Sun.COM return (0);
24077836SJohn.Forte@Sun.COM }
24087836SJohn.Forte@Sun.COM
24097836SJohn.Forte@Sun.COM count = 0;
24107836SJohn.Forte@Sun.COM ASSERT(urdc->volume_size != 0);
24117836SJohn.Forte@Sun.COM size = FBA_TO_LOG_LEN(urdc->volume_size);
24127836SJohn.Forte@Sun.COM for (i = 0; i < size; i++)
24137836SJohn.Forte@Sun.COM if (BMAP_BIT_ISSET(krdc->dcio_bitmap, i))
24147836SJohn.Forte@Sun.COM count++;
24157836SJohn.Forte@Sun.COM
24167836SJohn.Forte@Sun.COM if (count > size)
24177836SJohn.Forte@Sun.COM count = size;
24187836SJohn.Forte@Sun.COM
24197836SJohn.Forte@Sun.COM return (count);
24207836SJohn.Forte@Sun.COM }
24217836SJohn.Forte@Sun.COM
24227836SJohn.Forte@Sun.COM
24237836SJohn.Forte@Sun.COM static int
rdc_std_bit_isset(rdc_k_info_t * krdc,const int bit)24247836SJohn.Forte@Sun.COM rdc_std_bit_isset(rdc_k_info_t *krdc, const int bit)
24257836SJohn.Forte@Sun.COM {
24267836SJohn.Forte@Sun.COM return (BMAP_BIT_ISSET(krdc->dcio_bitmap, bit));
24277836SJohn.Forte@Sun.COM }
24287836SJohn.Forte@Sun.COM
24297836SJohn.Forte@Sun.COM
24307836SJohn.Forte@Sun.COM /*
24317836SJohn.Forte@Sun.COM * rdc_std_fill_bitmap(krdc, write)
24327836SJohn.Forte@Sun.COM *
24337836SJohn.Forte@Sun.COM * Called to force bitmaps to a fully dirty state
24347836SJohn.Forte@Sun.COM */
24357836SJohn.Forte@Sun.COM static int
rdc_std_fill_bitmap(rdc_k_info_t * krdc,const int write)24367836SJohn.Forte@Sun.COM rdc_std_fill_bitmap(rdc_k_info_t *krdc, const int write)
24377836SJohn.Forte@Sun.COM {
24387836SJohn.Forte@Sun.COM rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
24397836SJohn.Forte@Sun.COM int i, size;
24407836SJohn.Forte@Sun.COM
24417836SJohn.Forte@Sun.COM if (krdc->dcio_bitmap == NULL) {
24427836SJohn.Forte@Sun.COM #ifdef DEBUG
24437836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
2444*9093SRamana.Srikanth@Sun.COM "!rdc_std_fill_bitmap: no bitmap configured for %s",
24457836SJohn.Forte@Sun.COM urdc->primary.file);
24467836SJohn.Forte@Sun.COM #endif
24477836SJohn.Forte@Sun.COM return (-1);
24487836SJohn.Forte@Sun.COM }
24497836SJohn.Forte@Sun.COM
24507836SJohn.Forte@Sun.COM ASSERT(urdc->volume_size != 0);
24517836SJohn.Forte@Sun.COM size = FBA_TO_LOG_LEN(urdc->volume_size);
24527836SJohn.Forte@Sun.COM for (i = 0; i < size; i++)
24537836SJohn.Forte@Sun.COM BMAP_BIT_SET(krdc->dcio_bitmap, i);
24547836SJohn.Forte@Sun.COM
24557836SJohn.Forte@Sun.COM urdc->bits_set = size;
24567836SJohn.Forte@Sun.COM
24577836SJohn.Forte@Sun.COM if (write)
24587836SJohn.Forte@Sun.COM return (rdc_write_bitmap(krdc));
24597836SJohn.Forte@Sun.COM
24607836SJohn.Forte@Sun.COM return (0);
24617836SJohn.Forte@Sun.COM }
24627836SJohn.Forte@Sun.COM
24637836SJohn.Forte@Sun.COM
24647836SJohn.Forte@Sun.COM /*
24657836SJohn.Forte@Sun.COM * rdc_std_zero_bitmap(krdc)
24667836SJohn.Forte@Sun.COM *
24677836SJohn.Forte@Sun.COM * Called on the secondary after a sync has completed to force bitmaps
24687836SJohn.Forte@Sun.COM * to a fully clean state
24697836SJohn.Forte@Sun.COM */
24707836SJohn.Forte@Sun.COM static void
rdc_std_zero_bitmap(rdc_k_info_t * krdc)24717836SJohn.Forte@Sun.COM rdc_std_zero_bitmap(rdc_k_info_t *krdc)
24727836SJohn.Forte@Sun.COM {
24737836SJohn.Forte@Sun.COM rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
24747836SJohn.Forte@Sun.COM int i, size;
24757836SJohn.Forte@Sun.COM
24767836SJohn.Forte@Sun.COM if (krdc->dcio_bitmap == NULL) {
24777836SJohn.Forte@Sun.COM #ifdef DEBUG
24787836SJohn.Forte@Sun.COM cmn_err(CE_WARN,
2479*9093SRamana.Srikanth@Sun.COM "!rdc_std_zero_bitmap: no bitmap configured for %s",
24807836SJohn.Forte@Sun.COM urdc->primary.file);
24817836SJohn.Forte@Sun.COM #endif
24827836SJohn.Forte@Sun.COM return;
24837836SJohn.Forte@Sun.COM }
24847836SJohn.Forte@Sun.COM #ifdef DEBUG
2485*9093SRamana.Srikanth@Sun.COM cmn_err(CE_NOTE, "!Clearing bitmap for %s", urdc->secondary.file);
24867836SJohn.Forte@Sun.COM #endif
24877836SJohn.Forte@Sun.COM
24887836SJohn.Forte@Sun.COM ASSERT(urdc->volume_size != 0);
24897836SJohn.Forte@Sun.COM size = FBA_TO_LOG_LEN(urdc->volume_size);
24907836SJohn.Forte@Sun.COM for (i = 0; i < size; i++)
24917836SJohn.Forte@Sun.COM BMAP_BIT_CLR(krdc->dcio_bitmap, i);
24927836SJohn.Forte@Sun.COM if (krdc->bitmap_write > 0)
24937836SJohn.Forte@Sun.COM (void) rdc_write_bitmap(krdc);
24947836SJohn.Forte@Sun.COM
24957836SJohn.Forte@Sun.COM urdc->bits_set = 0;
24967836SJohn.Forte@Sun.COM }
24977836SJohn.Forte@Sun.COM
24987836SJohn.Forte@Sun.COM
24997836SJohn.Forte@Sun.COM /*
25007836SJohn.Forte@Sun.COM * rdc_std_net_bmap()
25017836SJohn.Forte@Sun.COM *
25027836SJohn.Forte@Sun.COM * WARNING acts as both client and server
25037836SJohn.Forte@Sun.COM */
25047836SJohn.Forte@Sun.COM static int
rdc_std_net_bmap(const struct bmap6 * b)25057836SJohn.Forte@Sun.COM rdc_std_net_bmap(const struct bmap6 *b)
25067836SJohn.Forte@Sun.COM {
25077836SJohn.Forte@Sun.COM rdc_k_info_t *krdc = &rdc_k_info[b->cd];
25087836SJohn.Forte@Sun.COM struct net_bdata6 bd;
25097836SJohn.Forte@Sun.COM
25107836SJohn.Forte@Sun.COM bd.data.data_val = (char *)krdc->dcio_bitmap;
25117836SJohn.Forte@Sun.COM bd.cd = b->dual;
25127836SJohn.Forte@Sun.COM bd.offset = 0;
25137836SJohn.Forte@Sun.COM
25147836SJohn.Forte@Sun.COM return (_rdc_net_bmap(b, &bd));
25157836SJohn.Forte@Sun.COM }
25167836SJohn.Forte@Sun.COM
25177836SJohn.Forte@Sun.COM
25187836SJohn.Forte@Sun.COM /*
25197836SJohn.Forte@Sun.COM * rdc_std_net_bdata
25207836SJohn.Forte@Sun.COM */
25217836SJohn.Forte@Sun.COM static int
rdc_std_net_bdata(const struct net_bdata6 * bd)25227836SJohn.Forte@Sun.COM rdc_std_net_bdata(const struct net_bdata6 *bd)
25237836SJohn.Forte@Sun.COM {
25247836SJohn.Forte@Sun.COM rdc_k_info_t *krdc = &rdc_k_info[bd->cd];
25257836SJohn.Forte@Sun.COM
25267836SJohn.Forte@Sun.COM rdc_lor((uchar_t *)bd->data.data_val,
25277836SJohn.Forte@Sun.COM (uchar_t *)(((char *)krdc->dcio_bitmap) + bd->offset), bd->size);
25287836SJohn.Forte@Sun.COM
25297836SJohn.Forte@Sun.COM return (0);
25307836SJohn.Forte@Sun.COM }
25317836SJohn.Forte@Sun.COM
25327836SJohn.Forte@Sun.COM
25337836SJohn.Forte@Sun.COM static struct rdc_bitmap_ops rdc_std_bitmap_ops = {
25347836SJohn.Forte@Sun.COM rdc_std_set_bitmap,
25357836SJohn.Forte@Sun.COM rdc_std_clr_bitmap,
25367836SJohn.Forte@Sun.COM rdc_std_count_dirty,
25377836SJohn.Forte@Sun.COM rdc_std_bit_isset,
25387836SJohn.Forte@Sun.COM rdc_std_fill_bitmap,
25397836SJohn.Forte@Sun.COM rdc_std_zero_bitmap,
25407836SJohn.Forte@Sun.COM rdc_std_net_bmap,
25417836SJohn.Forte@Sun.COM rdc_std_net_bdata,
25427836SJohn.Forte@Sun.COM rdc_std_zero_bitref,
25437836SJohn.Forte@Sun.COM rdc_std_set_bitmask,
25447836SJohn.Forte@Sun.COM rdc_std_check_bit
25457836SJohn.Forte@Sun.COM };
25467836SJohn.Forte@Sun.COM
25477836SJohn.Forte@Sun.COM
25487836SJohn.Forte@Sun.COM void
rdc_bitmap_init()25497836SJohn.Forte@Sun.COM rdc_bitmap_init()
25507836SJohn.Forte@Sun.COM {
25517836SJohn.Forte@Sun.COM rdc_bitmap_ops = &rdc_std_bitmap_ops;
25527836SJohn.Forte@Sun.COM rdc_wrflag = NSC_WRITE;
25537836SJohn.Forte@Sun.COM }
25547836SJohn.Forte@Sun.COM
25557836SJohn.Forte@Sun.COM static void
rdc_bmap_ref_byte_set(rdc_k_info_t * krdc,int ind)25567836SJohn.Forte@Sun.COM rdc_bmap_ref_byte_set(rdc_k_info_t *krdc, int ind)
25577836SJohn.Forte@Sun.COM {
25587836SJohn.Forte@Sun.COM unsigned char *bmap = (unsigned char *)krdc->bitmap_ref;
25597836SJohn.Forte@Sun.COM
25607836SJohn.Forte@Sun.COM ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned char));
25617836SJohn.Forte@Sun.COM bmap[ind]++;
25627836SJohn.Forte@Sun.COM }
25637836SJohn.Forte@Sun.COM
25647836SJohn.Forte@Sun.COM static void
rdc_bmap_ref_byte_clr(rdc_k_info_t * krdc,int ind)25657836SJohn.Forte@Sun.COM rdc_bmap_ref_byte_clr(rdc_k_info_t *krdc, int ind)
25667836SJohn.Forte@Sun.COM {
25677836SJohn.Forte@Sun.COM unsigned char *bmap = (unsigned char *)krdc->bitmap_ref;
25687836SJohn.Forte@Sun.COM
25697836SJohn.Forte@Sun.COM ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned char));
25707836SJohn.Forte@Sun.COM bmap[ind]--;
25717836SJohn.Forte@Sun.COM }
25727836SJohn.Forte@Sun.COM
25737836SJohn.Forte@Sun.COM static unsigned int
rdc_bmap_ref_byte_isset(rdc_k_info_t * krdc,int ind)25747836SJohn.Forte@Sun.COM rdc_bmap_ref_byte_isset(rdc_k_info_t *krdc, int ind)
25757836SJohn.Forte@Sun.COM {
25767836SJohn.Forte@Sun.COM unsigned char *bmap = (unsigned char *)krdc->bitmap_ref;
25777836SJohn.Forte@Sun.COM
25787836SJohn.Forte@Sun.COM ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned char));
25797836SJohn.Forte@Sun.COM return ((unsigned int)(bmap[ind]));
25807836SJohn.Forte@Sun.COM }
25817836SJohn.Forte@Sun.COM
25827836SJohn.Forte@Sun.COM static void
rdc_bmap_ref_byte_force(rdc_k_info_t * krdc,int ind,unsigned int val)25837836SJohn.Forte@Sun.COM rdc_bmap_ref_byte_force(rdc_k_info_t *krdc, int ind, unsigned int val)
25847836SJohn.Forte@Sun.COM {
25857836SJohn.Forte@Sun.COM unsigned char *bmap = (unsigned char *)krdc->bitmap_ref;
25867836SJohn.Forte@Sun.COM
25877836SJohn.Forte@Sun.COM ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned char));
25887836SJohn.Forte@Sun.COM bmap[ind] = (unsigned char) val;
25897836SJohn.Forte@Sun.COM }
25907836SJohn.Forte@Sun.COM
25917836SJohn.Forte@Sun.COM /* ARGSUSED */
25927836SJohn.Forte@Sun.COM static unsigned int
rdc_bmap_ref_byte_maxval(rdc_k_info_t * krdc)25937836SJohn.Forte@Sun.COM rdc_bmap_ref_byte_maxval(rdc_k_info_t *krdc)
25947836SJohn.Forte@Sun.COM {
25957836SJohn.Forte@Sun.COM ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned char));
25967836SJohn.Forte@Sun.COM return ((unsigned int)(UINT8_MAX));
25977836SJohn.Forte@Sun.COM }
25987836SJohn.Forte@Sun.COM
25997836SJohn.Forte@Sun.COM struct bm_ref_ops rdc_ref_byte_ops = {
26007836SJohn.Forte@Sun.COM rdc_bmap_ref_byte_set,
26017836SJohn.Forte@Sun.COM rdc_bmap_ref_byte_clr,
26027836SJohn.Forte@Sun.COM rdc_bmap_ref_byte_isset,
26037836SJohn.Forte@Sun.COM rdc_bmap_ref_byte_force,
26047836SJohn.Forte@Sun.COM rdc_bmap_ref_byte_maxval,
26057836SJohn.Forte@Sun.COM sizeof (unsigned char)
26067836SJohn.Forte@Sun.COM };
26077836SJohn.Forte@Sun.COM
26087836SJohn.Forte@Sun.COM static void
rdc_bmap_ref_int_set(rdc_k_info_t * krdc,int ind)26097836SJohn.Forte@Sun.COM rdc_bmap_ref_int_set(rdc_k_info_t *krdc, int ind)
26107836SJohn.Forte@Sun.COM {
26117836SJohn.Forte@Sun.COM unsigned int *bmap = (unsigned int *)krdc->bitmap_ref;
26127836SJohn.Forte@Sun.COM
26137836SJohn.Forte@Sun.COM ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned int));
26147836SJohn.Forte@Sun.COM bmap[ind]++;
26157836SJohn.Forte@Sun.COM }
26167836SJohn.Forte@Sun.COM
26177836SJohn.Forte@Sun.COM static void
rdc_bmap_ref_int_clr(rdc_k_info_t * krdc,int ind)26187836SJohn.Forte@Sun.COM rdc_bmap_ref_int_clr(rdc_k_info_t *krdc, int ind)
26197836SJohn.Forte@Sun.COM {
26207836SJohn.Forte@Sun.COM unsigned int *bmap = (unsigned int *)krdc->bitmap_ref;
26217836SJohn.Forte@Sun.COM
26227836SJohn.Forte@Sun.COM ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned int));
26237836SJohn.Forte@Sun.COM bmap[ind]--;
26247836SJohn.Forte@Sun.COM }
26257836SJohn.Forte@Sun.COM
26267836SJohn.Forte@Sun.COM static unsigned int
rdc_bmap_ref_int_isset(rdc_k_info_t * krdc,int ind)26277836SJohn.Forte@Sun.COM rdc_bmap_ref_int_isset(rdc_k_info_t *krdc, int ind)
26287836SJohn.Forte@Sun.COM {
26297836SJohn.Forte@Sun.COM unsigned int *bmap = (unsigned int *)krdc->bitmap_ref;
26307836SJohn.Forte@Sun.COM
26317836SJohn.Forte@Sun.COM ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned int));
26327836SJohn.Forte@Sun.COM return ((bmap[ind]));
26337836SJohn.Forte@Sun.COM }
26347836SJohn.Forte@Sun.COM
26357836SJohn.Forte@Sun.COM static void
rdc_bmap_ref_int_force(rdc_k_info_t * krdc,int ind,unsigned int val)26367836SJohn.Forte@Sun.COM rdc_bmap_ref_int_force(rdc_k_info_t *krdc, int ind, unsigned int val)
26377836SJohn.Forte@Sun.COM {
26387836SJohn.Forte@Sun.COM unsigned int *bmap = (unsigned int *)krdc->bitmap_ref;
26397836SJohn.Forte@Sun.COM
26407836SJohn.Forte@Sun.COM ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned int));
26417836SJohn.Forte@Sun.COM bmap[ind] = val;
26427836SJohn.Forte@Sun.COM }
26437836SJohn.Forte@Sun.COM
26447836SJohn.Forte@Sun.COM /* ARGSUSED */
26457836SJohn.Forte@Sun.COM static unsigned int
rdc_bmap_ref_int_maxval(rdc_k_info_t * krdc)26467836SJohn.Forte@Sun.COM rdc_bmap_ref_int_maxval(rdc_k_info_t *krdc)
26477836SJohn.Forte@Sun.COM {
26487836SJohn.Forte@Sun.COM ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned int));
26497836SJohn.Forte@Sun.COM return ((unsigned int)(UINT_MAX));
26507836SJohn.Forte@Sun.COM }
26517836SJohn.Forte@Sun.COM
26527836SJohn.Forte@Sun.COM struct bm_ref_ops rdc_ref_int_ops = {
26537836SJohn.Forte@Sun.COM rdc_bmap_ref_int_set,
26547836SJohn.Forte@Sun.COM rdc_bmap_ref_int_clr,
26557836SJohn.Forte@Sun.COM rdc_bmap_ref_int_isset,
26567836SJohn.Forte@Sun.COM rdc_bmap_ref_int_force,
26577836SJohn.Forte@Sun.COM rdc_bmap_ref_int_maxval,
26587836SJohn.Forte@Sun.COM sizeof (unsigned int)
26597836SJohn.Forte@Sun.COM };
2660