--- old/usr/src/uts/common/avs/ns/rdc/rdc_bitmap.c	Fri Jul 27 15:35:57 2018
+++ /dev/null	Fri Jul 27 15:07:21 2018
@@ -1,2659 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#include <sys/types.h>
-#include <sys/ksynch.h>
-#include <sys/cmn_err.h>
-#include <sys/kmem.h>
-#include <sys/stat.h>
-#include <sys/errno.h>
-
-#include "../solaris/nsc_thread.h"
-#ifdef DS_DDICT
-#include "../contract.h"
-#endif
-#include <sys/nsctl/nsctl.h>
-
-#include <sys/kmem.h>
-#include <sys/cmn_err.h>
-#include <sys/ddi.h>
-
-#include "rdc_io.h"
-#include "rdc_bitmap.h"
-#include "rdc_clnt.h"
-#include "rdc_diskq.h"
-
-#include <sys/unistat/spcs_s.h>
-#include <sys/unistat/spcs_s_k.h>
-#include <sys/unistat/spcs_errors.h>
-
-#ifndef UINT8_MAX
-#define	UINT8_MAX 255
-#endif
-
-#ifndef UINT_MAX
-#define	UINT_MAX 0xffffffff
-#endif
-
-/*
- * RDC bitmap functions.
- */
-
-/*
- * RDC cluster integration notes.
- *
- * 1. Configuration
- *
- * 1.1. Change 'rdc_bitmap_mode' in /usr/kernel/drv/rdc.conf to '1'.
- *
- * 2. Operation
- *
- * 2.1. SunCluster ensures that only one physical host has any rdc
- *	controlled device imported at any one time.  Hence rdc will
- *	only be active on a single node for any set at a time.
- *
- * 2.2. So operation from the kernel perspective looks just like
- *	operation on a single, standalone, node.
- *
- */
-
-struct rdc_bitmap_ops *rdc_bitmap_ops;		/* the bitmap ops switch */
-static int rdc_wrflag;				/* write flag for io */
-int rdc_bitmap_delay = 0;
-extern nsc_io_t *_rdc_io_hc;
-
-int rdc_suspend_diskq(rdc_k_info_t *krdc);
-
-/*
- * rdc_ns_io
- *	Perform read or write on an underlying ns device
- *
- * fd		- nsc file descriptor
- * flag		- nsc io direction and characteristics flag
- * fba_pos	- offset from beginning of device in FBAs
- * io_addr	- pointer to data buffer
- * io_len	- length of io in bytes
- */
-
-int
-rdc_ns_io(nsc_fd_t *fd, int flag, nsc_off_t fba_pos, uchar_t *io_addr,
-    nsc_size_t io_len)
-{
-	nsc_buf_t *tmp;
-	nsc_vec_t *vecp;
-	uchar_t	*vaddr;
-	size_t	copy_len;
-	int	vlen;
-	int	rc;
-	nsc_size_t	fba_req, fba_len;
-	nsc_size_t	maxfbas = 0;
-	nsc_size_t	tocopy;
-	unsigned char *toaddr;
-
-	rc = nsc_maxfbas(fd, 0, &maxfbas);
-	if (!RDC_SUCCESS(rc)) {
-#ifdef DEBUG
-		cmn_err(CE_WARN, "!rdc_ns_io: maxfbas failed (%d)", rc);
-#endif
-		maxfbas = 256;
-	}
-	toaddr = io_addr;
-	fba_req = FBA_LEN(io_len);
-loop:
-	tmp = NULL;
-	fba_len = min(fba_req, maxfbas);
-	tocopy = min(io_len, FBA_SIZE(fba_len));
-	ASSERT(tocopy < INT32_MAX);
-
-	rc = nsc_alloc_buf(fd, fba_pos, fba_len, flag, &tmp);
-	if (!RDC_SUCCESS(rc)) {
-		if (tmp) {
-			(void) nsc_free_buf(tmp);
-		}
-		return (EIO);
-	}
-
-	if ((flag & NSC_WRITE) != 0 && (flag & NSC_READ) == 0 &&
-	    FBA_OFF(io_len) != 0) {
-		/*
-		 * Not overwriting all of the last FBA, so read in the
-		 * old contents now before we overwrite it with the new
-		 * data.
-		 */
-		rc = nsc_read(tmp, fba_pos+FBA_NUM(io_len), 1, 0);
-		if (!RDC_SUCCESS(rc)) {
-			(void) nsc_free_buf(tmp);
-			return (EIO);
-		}
-	}
-
-	vecp = tmp->sb_vec;
-	vlen = vecp->sv_len;
-	vaddr = vecp->sv_addr;
-
-	while (tocopy > 0) {
-		if (vecp->sv_addr == 0 || vecp->sv_len == 0) {
-#ifdef DEBUG
-			cmn_err(CE_WARN, "!rdc_ns_io: ran off end of handle");
-#endif
-			break;
-		}
-
-		copy_len = (size_t)min(vlen, (int)tocopy);
-
-		if (flag & NSC_WRITE)
-			bcopy(toaddr, vaddr, copy_len);
-		else
-			bcopy(vaddr, toaddr, copy_len);
-
-		toaddr += copy_len;
-		io_addr += copy_len;	/* adjust position in callers buffer */
-		io_len -= copy_len;	/* adjust total byte length remaining */
-		tocopy -= copy_len;	/* adjust chunk byte length remaining */
-		vaddr += copy_len;	/* adjust location in sv_vec_t */
-		vlen -= copy_len;	/* adjust length left in sv_vec_t */
-
-		if (vlen <= 0) {
-			vecp++;
-			vaddr = vecp->sv_addr;
-			vlen = vecp->sv_len;
-		}
-	}
-
-	if (flag & NSC_WRITE) {
-		rc = nsc_write(tmp, tmp->sb_pos, tmp->sb_len, 0);
-		if (!RDC_SUCCESS(rc)) {
-			(void) nsc_free_buf(tmp);
-			return (rc);
-		}
-	}
-
-	(void) nsc_free_buf(tmp);
-
-	fba_pos += fba_len;
-	fba_req -= fba_len;
-	if (fba_req > 0)
-		goto loop;
-
-	return (0);
-}
-
-/*
- * Must be called with krdc->bmapmutex held.
- */
-static void
-rdc_fill_header(rdc_u_info_t *urdc, rdc_header_t *header)
-{
-	rdc_k_info_t *krdc = &rdc_k_info[urdc->index];
-#ifdef DEBUG
-	ASSERT(MUTEX_HELD(&krdc->bmapmutex));
-#endif
-
-	header->magic = RDC_HDR_MAGIC;
-	(void) strncpy(header->primary.file, urdc->primary.file, NSC_MAXPATH);
-	(void) strncpy(header->primary.bitmap, urdc->primary.bitmap,
-	    NSC_MAXPATH);
-	(void) strncpy(header->secondary.file, urdc->secondary.file,
-	    NSC_MAXPATH);
-	(void) strncpy(header->secondary.bitmap, urdc->secondary.bitmap,
-	    NSC_MAXPATH);
-	header->flags = urdc->flags | urdc->sync_flags | urdc->bmap_flags;
-	header->autosync = urdc->autosync;
-	header->maxqfbas = urdc->maxqfbas;
-	header->maxqitems = urdc->maxqitems;
-	header->asyncthr = urdc->asyncthr;
-	header->syshostid = urdc->syshostid;
-	header->refcntsize = rdc_refcntsize(krdc);
-#ifdef DEBUG_REFCNT
-	cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
-	    (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
-#endif
-}
-
-/*
- * Must be called with krdc->bmapmutex held.
- */
-static int
-rdc_read_header(rdc_k_info_t *krdc, rdc_header_t *header)
-{
-	int sts;
-	rdc_u_info_t *urdc;
-	union {
-		rdc_header_t *current;
-		rdc_headerv4_t *v4;
-	} u_hdrp;
-
-	if (krdc == NULL) {
-		return (-1);
-	}
-
-	ASSERT(MUTEX_HELD(&krdc->bmapmutex));
-
-	urdc = &rdc_u_info[krdc->index];
-	if (rdc_get_vflags(urdc) & RDC_BMP_FAILED)
-		return (-1);
-
-	if (krdc->bitmapfd == NULL) {
-		return (-1);
-	}
-	if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
-		rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
-		return (-1);
-	}
-
-	if (krdc->bmp_kstats) {
-		mutex_enter(krdc->bmp_kstats->ks_lock);
-		kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
-		mutex_exit(krdc->bmp_kstats->ks_lock);
-	}
-
-	sts = rdc_ns_io(krdc->bitmapfd, NSC_RDBUF, 0, (uchar_t *)header,
-	    sizeof (rdc_header_t));
-
-	if (krdc->bmp_kstats) {
-		mutex_enter(krdc->bmp_kstats->ks_lock);
-		kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
-		mutex_exit(krdc->bmp_kstats->ks_lock);
-		KSTAT_IO_PTR(krdc->bmp_kstats)->reads++;
-		KSTAT_IO_PTR(krdc->bmp_kstats)->nread += sizeof (rdc_header_t);
-	}
-
-	if (!RDC_SUCCESS(sts)) {
-		cmn_err(CE_WARN, "!rdc_read_header: %s read failed %d",
-		    urdc->primary.file, sts);
-		rdc_set_flags_log(urdc, RDC_BMP_FAILED, "read header failed");
-	}
-
-	_rdc_rlse_devs(krdc, RDC_BMP);
-
-	if (!RDC_SUCCESS(sts))
-		return (-1);
-	switch (header->magic) {
-	case RDC_HDR_V4:
-		/*
-		 * old header format - upgrade incore copy, disk copy will
-		 * be changed when state is re-written.
-		 */
-#ifdef DEBUG
-		cmn_err(CE_NOTE, "!sndr: old style (V4) bit map header");
-#endif
-		header->magic = RDC_HDR_MAGIC;
-		u_hdrp.current = header;
-		/* copy down items moved by new maxq??? sizes */
-		u_hdrp.current->asyncthr = u_hdrp.v4->asyncthr;
-		u_hdrp.current->syshostid = u_hdrp.v4->syshostid;
-		u_hdrp.current->maxqitems = u_hdrp.v4->maxqitems;
-		u_hdrp.current->maxqfbas = u_hdrp.v4->maxqfbas;
-		u_hdrp.current->refcntsize = 1;	/* new field */
-#ifdef DEBUG_REFCNT
-	cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
-	    (int)u_hdrp.current->refcntsize, __LINE__, __FILE__);
-#endif
-		return (0);
-	case RDC_HDR_MAGIC:
-		/* current header type */
-		return (0);
-	default:
-		/* not a header we currently understand */
-		return (0);
-	}
-}
-
-/*
- * Must be called with krdc->bmapmutex held.
- */
-static int
-rdc_write_header(rdc_k_info_t *krdc, rdc_header_t *header)
-{
-	rdc_u_info_t *urdc;
-	int sts;
-
-	if (krdc == NULL) {
-		return (-1);
-	}
-
-	ASSERT(MUTEX_HELD(&krdc->bmapmutex));
-
-	urdc = &rdc_u_info[krdc->index];
-	if (rdc_get_vflags(urdc) & RDC_BMP_FAILED)
-		return (-1);
-
-	if (krdc->bitmapfd == NULL) {
-		return (-1);
-	}
-
-	if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
-		rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
-		return (-1);
-	}
-
-	if (krdc->bmp_kstats) {
-		mutex_enter(krdc->bmp_kstats->ks_lock);
-		kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
-		mutex_exit(krdc->bmp_kstats->ks_lock);
-	}
-
-	sts = rdc_ns_io(krdc->bitmapfd, rdc_wrflag, 0, (uchar_t *)header,
-	    sizeof (rdc_header_t));
-
-	if (krdc->bmp_kstats) {
-		mutex_enter(krdc->bmp_kstats->ks_lock);
-		kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
-		mutex_exit(krdc->bmp_kstats->ks_lock);
-		KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
-		KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten +=
-		    sizeof (rdc_header_t);
-	}
-
-	if (!RDC_SUCCESS(sts)) {
-		cmn_err(CE_WARN, "!rdc_write_header: %s write failed %d",
-		    urdc->primary.file, sts);
-		rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
-	}
-
-	_rdc_rlse_devs(krdc, RDC_BMP);
-
-	if (!RDC_SUCCESS(sts))
-		return (-1);
-	else
-		return (0);
-}
-
-struct bm_ref_ops rdc_ref_byte_ops;
-struct bm_ref_ops rdc_ref_int_ops;
-
-static void
-rdc_set_refcnt_ops(rdc_k_info_t *krdc, size_t refcntsize)
-{
-	switch (refcntsize) {
-	default:
-		/* FALLTHRU */
-	case sizeof (unsigned char):
-		krdc->bm_refs = &rdc_ref_byte_ops;
-		break;
-	case sizeof (unsigned int):
-		krdc->bm_refs = &rdc_ref_int_ops;
-		break;
-	}
-#ifdef DEBUG_REFCNT
-	cmn_err(CE_NOTE, "!sndr: set refcnt ops for refcntsize %d - %d:%s",
-	    (int)refcntsize, __LINE__, __FILE__);
-#endif
-}
-
-size_t
-rdc_refcntsize(rdc_k_info_t *krdc)
-{
-	if (krdc->bm_refs == &rdc_ref_int_ops)
-		return (sizeof (unsigned int));
-	return (sizeof (unsigned char));
-}
-
-int
-rdc_read_state(rdc_k_info_t *krdc, int *statep, int *hostidp)
-{
-	rdc_header_t header;
-	rdc_u_info_t *urdc;
-	int sts;
-
-	if (krdc == NULL) {
-		return (-1);
-	}
-
-	mutex_enter(&krdc->bmapmutex);
-
-	urdc = &rdc_u_info[krdc->index];
-	if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	if (krdc->bitmapfd == NULL) {
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	sts = rdc_read_header(krdc, &header);
-	mutex_exit(&krdc->bmapmutex);
-
-	if (!RDC_SUCCESS(sts)) {
-		return (-1);
-	}
-
-	switch (header.magic) {
-	case RDC_HDR_MAGIC:
-		*statep = header.flags;
-		*hostidp = header.syshostid;
-		rdc_set_refcnt_ops(krdc, header.refcntsize);
-#ifdef DEBUG_REFCNT
-	cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
-	    (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
-#endif
-		sts = 0;
-		break;
-	default:
-		sts = -1;
-		break;
-	}
-
-	return (sts);
-}
-
-int
-rdc_clear_state(rdc_k_info_t *krdc)
-{
-	rdc_u_info_t *urdc;
-	int sts;
-	rdc_header_t header;
-
-	if (krdc == NULL) {
-		return (-1);
-	}
-
-	mutex_enter(&krdc->bmapmutex);
-
-	urdc = &rdc_u_info[krdc->index];
-	if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	if (krdc->bitmapfd == NULL) {
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
-		rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	bzero(&header, sizeof (header));
-
-	if (krdc->bmp_kstats) {
-		mutex_enter(krdc->bmp_kstats->ks_lock);
-		kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
-		mutex_exit(krdc->bmp_kstats->ks_lock);
-	}
-
-	sts = rdc_ns_io(krdc->bitmapfd, rdc_wrflag, 0,
-	    (uchar_t *)&header, sizeof (header));
-
-	if (krdc->bmp_kstats) {
-		mutex_enter(krdc->bmp_kstats->ks_lock);
-		kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
-		mutex_exit(krdc->bmp_kstats->ks_lock);
-		KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
-		KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten +=
-		    sizeof (rdc_header_t);
-	}
-
-	if (!RDC_SUCCESS(sts)) {
-		cmn_err(CE_WARN, "!rdc_clear_state: %s write failed",
-		    urdc->primary.file);
-		rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
-	}
-
-	_rdc_rlse_devs(krdc, RDC_BMP);
-	mutex_exit(&krdc->bmapmutex);
-
-	if (!RDC_SUCCESS(sts))
-		return (-1);
-	else
-		return (0);
-}
-
-void
-rdc_write_state(rdc_u_info_t *urdc)
-{
-	rdc_k_info_t *krdc;
-	int sts;
-	rdc_header_t header;
-
-	if (urdc == NULL) {
-		return;
-	}
-
-	krdc = &rdc_k_info[urdc->index];
-
-	mutex_enter(&krdc->bmapmutex);
-
-	if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
-		mutex_exit(&krdc->bmapmutex);
-		return;
-	}
-
-	if (krdc->bitmapfd == NULL) {
-		mutex_exit(&krdc->bmapmutex);
-		return;
-	}
-
-	if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
-		rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
-		mutex_exit(&krdc->bmapmutex);
-		return;
-	}
-
-	if (krdc->bmp_kstats) {
-		mutex_enter(krdc->bmp_kstats->ks_lock);
-		kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
-		mutex_exit(krdc->bmp_kstats->ks_lock);
-	}
-
-	sts = rdc_ns_io(krdc->bitmapfd, NSC_RDBUF, 0, (uchar_t *)&header,
-	    sizeof (header));
-
-	if (krdc->bmp_kstats) {
-		mutex_enter(krdc->bmp_kstats->ks_lock);
-		kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
-		mutex_exit(krdc->bmp_kstats->ks_lock);
-		KSTAT_IO_PTR(krdc->bmp_kstats)->reads++;
-		KSTAT_IO_PTR(krdc->bmp_kstats)->nread += sizeof (header);
-	}
-
-	if (!RDC_SUCCESS(sts)) {
-		cmn_err(CE_WARN, "!rdc_write_state: %s read failed",
-		    urdc->primary.file);
-		rdc_set_flags_log(urdc, RDC_BMP_FAILED, "read failed");
-		goto done;
-	}
-
-	rdc_fill_header(urdc, &header);
-
-	if (krdc->bmp_kstats) {
-		mutex_enter(krdc->bmp_kstats->ks_lock);
-		kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
-		mutex_exit(krdc->bmp_kstats->ks_lock);
-	}
-
-	sts = rdc_ns_io(krdc->bitmapfd, rdc_wrflag, 0,
-	    (uchar_t *)&header, sizeof (header));
-
-	if (krdc->bmp_kstats) {
-		mutex_enter(krdc->bmp_kstats->ks_lock);
-		kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
-		mutex_exit(krdc->bmp_kstats->ks_lock);
-		KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
-		KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten += sizeof (header);
-	}
-
-	if (!RDC_SUCCESS(sts)) {
-		cmn_err(CE_WARN, "!rdc_write_state: %s write failed",
-		    urdc->primary.file);
-		rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
-	}
-
-done:
-	_rdc_rlse_devs(krdc, RDC_BMP);
-	mutex_exit(&krdc->bmapmutex);
-}
-
-
-struct bitmapdata {
-	uchar_t	*data;
-	size_t	len;
-};
-
-static int
-rdc_read_bitmap(rdc_k_info_t *krdc, struct bitmapdata *data)
-{
-	rdc_u_info_t *urdc;
-	int sts;
-
-	if (krdc == NULL) {
-		return (-1);
-	}
-
-	if (data != NULL) {
-		data->data = kmem_alloc(krdc->bitmap_size, KM_SLEEP);
-		data->len = krdc->bitmap_size;
-
-		if (data->data == NULL) {
-			return (-1);
-		}
-	}
-
-	mutex_enter(&krdc->bmapmutex);
-
-	urdc = &rdc_u_info[krdc->index];
-	if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	if (krdc->bitmapfd == NULL) {
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	if (data == NULL && krdc->dcio_bitmap == NULL) {
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
-		cmn_err(CE_WARN, "!rdc_read_bitmap: %s reserve failed",
-		    urdc->primary.file);
-		rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	if (krdc->bmp_kstats) {
-		mutex_enter(krdc->bmp_kstats->ks_lock);
-		kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
-		mutex_exit(krdc->bmp_kstats->ks_lock);
-	}
-
-	sts = rdc_ns_io(krdc->bitmapfd, NSC_RDBUF, RDC_BITMAP_FBA,
-	    data ? data->data : krdc->dcio_bitmap, krdc->bitmap_size);
-
-	if (krdc->bmp_kstats) {
-		mutex_enter(krdc->bmp_kstats->ks_lock);
-		kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
-		mutex_exit(krdc->bmp_kstats->ks_lock);
-		KSTAT_IO_PTR(krdc->bmp_kstats)->reads++;
-		KSTAT_IO_PTR(krdc->bmp_kstats)->nread += krdc->bitmap_size;
-	}
-
-	_rdc_rlse_devs(krdc, RDC_BMP);
-
-	if (!RDC_SUCCESS(sts)) {
-		cmn_err(CE_WARN, "!rdc_read_bitmap: %s read failed",
-		    urdc->primary.file);
-		rdc_set_flags_log(urdc, RDC_BMP_FAILED, "read failed");
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	mutex_exit(&krdc->bmapmutex);
-	return (0);
-}
-
-int
-rdc_write_bitmap(rdc_k_info_t *krdc)
-{
-	rdc_u_info_t *urdc;
-	int sts;
-
-	if (krdc == NULL) {
-		return (-1);
-	}
-
-	mutex_enter(&krdc->bmapmutex);
-
-	urdc = &rdc_u_info[krdc->index];
-	if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	if (krdc->bitmapfd == NULL) {
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	if (krdc->dcio_bitmap == NULL) {
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
-		rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	if (krdc->bmp_kstats) {
-		mutex_enter(krdc->bmp_kstats->ks_lock);
-		kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
-		mutex_exit(krdc->bmp_kstats->ks_lock);
-	}
-
-	sts = rdc_ns_io(krdc->bitmapfd, rdc_wrflag, RDC_BITMAP_FBA,
-	    krdc->dcio_bitmap, krdc->bitmap_size);
-
-	if (krdc->bmp_kstats) {
-		mutex_enter(krdc->bmp_kstats->ks_lock);
-		kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
-		mutex_exit(krdc->bmp_kstats->ks_lock);
-		KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
-		KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten += krdc->bitmap_size;
-	}
-
-	_rdc_rlse_devs(krdc, RDC_BMP);
-
-	if (!RDC_SUCCESS(sts)) {
-		cmn_err(CE_WARN, "!rdc_write_bitmap: %s write failed",
-		    urdc->primary.file);
-		rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	mutex_exit(&krdc->bmapmutex);
-	return (0);
-}
-
-int
-rdc_write_bitmap_fba(rdc_k_info_t *krdc, nsc_off_t fba)
-{
-	rdc_u_info_t *urdc;
-	int sts;
-
-	if (krdc == NULL) {
-		return (-1);
-	}
-
-	mutex_enter(&krdc->bmapmutex);
-
-	urdc = &rdc_u_info[krdc->index];
-	if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	if (krdc->bitmapfd == NULL) {
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	if (krdc->dcio_bitmap == NULL) {
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
-		cmn_err(CE_WARN, "!rdc_write_bitmap_fba: %s reserve failed",
-		    urdc->primary.file);
-		rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	if (krdc->bmp_kstats) {
-		mutex_enter(krdc->bmp_kstats->ks_lock);
-		kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
-		mutex_exit(krdc->bmp_kstats->ks_lock);
-	}
-	sts = rdc_ns_io(krdc->bitmapfd, rdc_wrflag, RDC_BITMAP_FBA + fba,
-	    krdc->dcio_bitmap + fba * 512, 512);
-
-	if (krdc->bmp_kstats) {
-		mutex_enter(krdc->bmp_kstats->ks_lock);
-		kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
-		mutex_exit(krdc->bmp_kstats->ks_lock);
-		KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
-		KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten += 512;
-	}
-
-	_rdc_rlse_devs(krdc, RDC_BMP);
-
-	if (!RDC_SUCCESS(sts)) {
-		cmn_err(CE_WARN, "!rdc_write_bitmap_fba: %s write failed",
-		    urdc->primary.file);
-		rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	mutex_exit(&krdc->bmapmutex);
-	return (0);
-}
-
-
-static int
-rdc_write_bitmap_pattern(rdc_k_info_t *krdc, const char pattern)
-{
-	rdc_u_info_t *urdc;
-	char *buffer;
-	nsc_buf_t *h;
-	nsc_vec_t *v;
-	int rc;
-	size_t i;
-	nsc_size_t len;
-	int  off;
-	size_t buffer_size;
-	size_t iolen;
-	nsc_size_t	fba_req;
-	nsc_off_t	fba_len, fba_pos;
-	nsc_size_t	maxfbas = 0;
-	nsc_size_t	tocopy;
-
-	if (krdc == NULL) {
-		return (-1);
-	}
-
-	mutex_enter(&krdc->bmapmutex);
-
-	urdc = &rdc_u_info[krdc->index];
-	if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	if (krdc->bitmapfd == NULL) {
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
-		rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	buffer_size = FBA_SIZE(1);
-	ASSERT(buffer_size < INT32_MAX);
-	buffer = kmem_alloc(buffer_size, KM_SLEEP);
-
-	for (i = 0; i < buffer_size; i++) {
-		buffer[i] = pattern;
-	}
-
-	rc = nsc_maxfbas(krdc->bitmapfd, 0, &maxfbas);
-	if (!RDC_SUCCESS(rc)) {
-#ifdef DEBUG
-		cmn_err(CE_WARN,
-		    "!rdc_write_bitmap_pattern: maxfbas failed (%d)", rc);
-#endif
-		maxfbas = 256;
-	}
-
-	fba_req = FBA_LEN(krdc->bitmap_size);	/* total FBAs left to copy */
-	fba_pos = RDC_BITMAP_FBA;		/* current FBA position */
-	tocopy = krdc->bitmap_size;		/* total bytes left to copy */
-loop:
-	h = NULL;
-	fba_len = min(fba_req, maxfbas);	/* FBAs to alloc this time */
-
-	rc = nsc_alloc_buf(krdc->bitmapfd, fba_pos, fba_len, rdc_wrflag, &h);
-	if (!RDC_SUCCESS(rc)) {
-		cmn_err(CE_WARN, "!rdc_write_bitmap_pattern: %s "
-		    "write failed %d", urdc->primary.file, rc);
-		rdc_set_flags_log(urdc, RDC_BMP_FAILED, "nsc_alloc_buf failed");
-		if (h) {
-			(void) nsc_free_handle(h);
-		}
-
-		_rdc_rlse_devs(krdc, RDC_BMP);
-		mutex_exit(&krdc->bmapmutex);
-		rc = -1;
-		goto finish;
-	}
-
-				/* bytes to copy this time */
-	len = min(tocopy, FBA_SIZE(fba_len));
-	v = h->sb_vec;
-	off = 0;
-
-	while (len) {
-		if (off >= v->sv_len) {
-			off = 0;
-			v++;
-		}
-
-		if (v->sv_addr == 0 || v->sv_len == 0) {
-#ifdef DEBUG
-			cmn_err(CE_WARN,
-			    "!rdc_write_bitmap_pattern: ran off end of handle");
-#endif
-			break;
-		}
-
-		iolen = (size_t)min(len, buffer_size);
-
-		bcopy(buffer, (char *)(v->sv_addr + off), iolen);
-		off += iolen;
-		len -= iolen;
-	}
-
-	rc = nsc_write(h, h->sb_pos, h->sb_len, 0);
-	if (!RDC_SUCCESS(rc)) {
-		cmn_err(CE_WARN, "!rdc_write_bitmap_pattern: "
-		    "%s write failed %d", urdc->primary.file, rc);
-		rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
-		(void) nsc_free_buf(h);
-		_rdc_rlse_devs(krdc, RDC_BMP);
-		mutex_exit(&krdc->bmapmutex);
-		rc = -1;
-		goto finish;
-	}
-
-	(void) nsc_free_buf(h);
-
-	fba_pos += fba_len;
-	fba_req -= fba_len;
-	tocopy -= FBA_SIZE(fba_len);    /* adjust byte length remaining */
-	if (fba_req > 0)
-		goto loop;
-
-	_rdc_rlse_devs(krdc, RDC_BMP);
-	mutex_exit(&krdc->bmapmutex);
-	rc = 0;
-finish:
-	kmem_free(buffer, buffer_size);
-	return (rc);
-}
-
-
-/*
- * rdc_write_bitmap_fill()
- *
- * Write a bitmap full of 1's out to disk without touching the
- * in-memory bitmap.
- */
-int
-rdc_write_bitmap_fill(rdc_k_info_t *krdc)
-{
-	return (rdc_write_bitmap_pattern(krdc, 0xff));
-}
-
-
-void
-rdc_merge_bitmaps(rdc_k_info_t *src, rdc_k_info_t *dst)
-{
-	if (src->dcio_bitmap == NULL || dst->dcio_bitmap == NULL)
-		return;
-
-	rdc_lor(src->dcio_bitmap, dst->dcio_bitmap,
-	    min(src->bitmap_size, dst->bitmap_size));
-	if (dst->bitmap_write > 0)
-		(void) rdc_write_bitmap(dst);
-}
-
-
-/*
- * bitmap size in bytes, vol_size fba's
- */
-
-size_t
-rdc_ref_size_possible(nsc_size_t bitmap_size, nsc_size_t vol_size)
-{
-	nsc_size_t ref_size;
-	nsc_size_t bitmap_end_fbas;
-
-	bitmap_end_fbas = RDC_BITMAP_FBA + FBA_LEN(bitmap_size);
-	ref_size = FBA_LEN(bitmap_size * BITS_IN_BYTE * sizeof (unsigned char));
-	if (bitmap_end_fbas + ref_size > vol_size)
-		return ((size_t)0);
-
-	ref_size = FBA_LEN(bitmap_size * BITS_IN_BYTE * sizeof (unsigned int));
-	if (bitmap_end_fbas + ref_size > vol_size)
-		return (sizeof (unsigned char));
-	return (sizeof (unsigned int));
-}
-
-int
-rdc_move_bitmap(rdc_k_info_t *krdc, char *newbitmap)
-{
-	rdc_u_info_t *urdc;
-	nsc_fd_t *oldfd;
-	nsc_fd_t *newfd = NULL;
-	rdc_header_t header;
-	int sts;
-	nsc_size_t vol_size;
-	nsc_size_t req_size;
-	size_t ref_size;
-
-	if (krdc == NULL) {
-		return (-1);
-	}
-
-	if (krdc->bitmapfd == NULL) {
-		return (-1);
-	}
-
-	req_size = RDC_BITMAP_FBA + FBA_LEN(krdc->bitmap_size);
-	if (RDC_IS_DISKQ(krdc->group)) {
-		/* new volume must support at least the old refcntsize */
-		req_size += FBA_LEN(krdc->bitmap_size * BITS_IN_BYTE *
-		    rdc_refcntsize(krdc));
-#ifdef DEBUG_REFCNT
-	cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
-	    (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
-#endif
-	}
-
-	mutex_enter(&krdc->bmapmutex);
-
-	if (rdc_read_header(krdc, &header) < 0) {
-#ifdef DEBUG
-		cmn_err(CE_WARN, "!rdc_move_bitmap: Read old header failed");
-#endif
-		mutex_exit(&krdc->bmapmutex);
-		return (-1);
-	}
-
-	oldfd = krdc->bitmapfd;
-
-	newfd = nsc_open(newbitmap, NSC_RDCHR_ID|NSC_FILE|NSC_RDWR, 0, 0, 0);
-	if (newfd == NULL) {
-		newfd = nsc_open(newbitmap,
-		    NSC_RDCHR_ID|NSC_CACHE|NSC_DEVICE|NSC_RDWR, 0, 0, 0);
-		if (newfd == NULL) {
-			/* Can't open new bitmap */
-			cmn_err(CE_WARN,
-			    "!rdc_move_bitmap: Cannot open new bitmap %s",
-			    newbitmap);
-			goto fail;
-		}
-	}
-
-	sts = nsc_reserve(newfd, 0);
-	if (!RDC_SUCCESS(sts)) {
-		cmn_err(CE_WARN, "!rdc_move_bitmap: Reserve failed for %s",
-		    newbitmap);
-		goto fail;
-	}
-	sts = nsc_partsize(newfd, &vol_size);
-	nsc_release(newfd);
-
-	if (!RDC_SUCCESS(sts)) {
-		cmn_err(CE_WARN,
-		    "!rdc_move_bitmap: nsc_partsize failed for %s", newbitmap);
-		goto fail;
-	}
-
-	ref_size = rdc_ref_size_possible(krdc->bitmap_size, vol_size);
-
-	if (vol_size < req_size) {
-		cmn_err(CE_WARN,
-		    "!rdc_move_bitmap: bitmap %s too small: %" NSC_SZFMT
-		    " vs %" NSC_SZFMT " blocks", newbitmap, vol_size, req_size);
-		goto fail;
-	}
-
-	mutex_enter(&krdc->devices->id_rlock);
-	krdc->bitmapfd = newfd;			/* swap under lock */
-	if (krdc->bmaprsrv > 0) {
-		sts = nsc_reserve(krdc->bitmapfd, 0);
-		if (!RDC_SUCCESS(sts)) {
-			krdc->bitmapfd = oldfd;	/* replace under lock */
-			mutex_exit(&krdc->devices->id_rlock);
-			cmn_err(CE_WARN,
-			    "!rdc_move_bitmap: Reserve failed for %s",
-			    newbitmap);
-			goto fail;
-		}
-	}
-	rdc_set_refcnt_ops(krdc, ref_size);
-#ifdef DEBUG_REFCNT
-	cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
-	    (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
-#endif
-	mutex_exit(&krdc->devices->id_rlock);
-
-	/* Forget newfd now it is krdc->bitmapfd */
-	newfd = NULL;
-
-	/* Put new bitmap name into header and user-visible data structure */
-	urdc = &rdc_u_info[krdc->index];
-	if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
-		(void) strncpy(header.primary.bitmap, newbitmap, NSC_MAXPATH);
-		(void) strncpy(urdc->primary.bitmap, newbitmap, NSC_MAXPATH);
-	} else {
-		(void) strncpy(header.secondary.bitmap, newbitmap, NSC_MAXPATH);
-		(void) strncpy(urdc->secondary.bitmap, newbitmap, NSC_MAXPATH);
-	}
-
-	if (rdc_write_header(krdc, &header) < 0) {
-		cmn_err(CE_WARN,
-		    "!rdc_move_bitmap: Write header %s failed", newbitmap);
-		goto fail;
-	}
-
-	mutex_exit(&krdc->bmapmutex);
-
-	if (rdc_write_bitmap(krdc) < 0) {
-		mutex_enter(&krdc->bmapmutex);
-		cmn_err(CE_WARN,
-		    "!rdc_move_bitmap: Write bitmap %s failed", newbitmap);
-		goto fail;
-	}
-
-	/* Unintercept the old bitmap */
-	if (krdc->b_tok) {
-		int rc;
-
-		rdc_group_exit(krdc);
-		rc = nsc_unregister_path(krdc->b_tok, 0);
-		if (rc)
-			cmn_err(CE_WARN, "!rdc_move_bitmap: "
-			    "unregister bitmap failed %d", rc);
-		else
-			krdc->b_tok = nsc_register_path(newbitmap,
-			    NSC_CACHE | NSC_DEVICE, _rdc_io_hc);
-		rdc_group_enter(krdc);
-	}
-
-	/* clear the old bitmap header */
-	bzero(&header, sizeof (header));
-
-	sts = nsc_held(oldfd) ? 0 : nsc_reserve(oldfd, 0);
-	if (sts == 0) {
-
-		if (krdc->bmp_kstats) {
-			mutex_enter(krdc->bmp_kstats->ks_lock);
-			kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
-			mutex_exit(krdc->bmp_kstats->ks_lock);
-		}
-
-		sts = rdc_ns_io(oldfd, rdc_wrflag, 0,
-		    (uchar_t *)&header, sizeof (header));
-
-		if (krdc->bmp_kstats) {
-			mutex_enter(krdc->bmp_kstats->ks_lock);
-			kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
-			mutex_exit(krdc->bmp_kstats->ks_lock);
-			KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
-			KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten +=
-			    sizeof (header);
-		}
-
-	}
-#ifdef DEBUG
-	if (sts != 0) {
-		cmn_err(CE_WARN,
-		    "!rdc_move_bitmap: unable to clear bitmap header on %s",
-		    nsc_pathname(oldfd));
-	}
-#endif
-
-	/* nsc_close will undo any reservation */
-	if (nsc_close(oldfd) != 0) {
-#ifdef DEBUG
-		cmn_err(CE_WARN, "!rdc_move_bitmap: close old bitmap failed");
-#else
-		;
-		/*EMPTY*/
-#endif
-	}
-
-	return (0);
-
-fail:
-	/* Close newfd if it was unused */
-	if (newfd && newfd != krdc->bitmapfd) {
-		(void) nsc_close(newfd);
-		newfd = NULL;
-	}
-
-	mutex_exit(&krdc->bmapmutex);
-	return (-1);
-}
-
-
-void
-rdc_close_bitmap(rdc_k_info_t *krdc)
-{
-
-	if (krdc == NULL) {
-		return;
-	}
-
-	mutex_enter(&krdc->bmapmutex);
-
-	if (krdc->bitmapfd) {
-		if (nsc_close(krdc->bitmapfd) != 0) {
-#ifdef DEBUG
-			cmn_err(CE_WARN, "!nsc_close on bitmap failed");
-#else
-			;
-			/*EMPTY*/
-#endif
-		}
-		krdc->bitmapfd = 0;
-	}
-
-	mutex_exit(&krdc->bmapmutex);
-}
-
-void
-rdc_free_bitmap(rdc_k_info_t *krdc, int cmd)
-{
-	rdc_header_t header;
-	rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
-
-	if (krdc == NULL) {
-		return;
-	}
-
-	mutex_enter(&krdc->bmapmutex);
-
-	if (cmd != RDC_CMD_SUSPEND) {
-
-		bzero((char *)&header, sizeof (rdc_header_t));
-
-		if (krdc->bitmapfd)
-			(void) rdc_write_header(krdc, &header);
-	} else {
-		mutex_exit(&krdc->bmapmutex);
-		/* gotta drop mutex, in case q needs to fail */
-		if (RDC_IS_DISKQ(krdc->group) && rdc_suspend_diskq(krdc) < 0) {
-			cmn_err(CE_WARN,
-			    "!rdc_free_bitmap: diskq suspend failed");
-		}
-
-		mutex_enter(&krdc->bmapmutex);
-		if (rdc_read_header(krdc, &header) < 0) {
-			cmn_err(CE_WARN,
-			    "!rdc_free_bitmap: Read header failed");
-		} else {
-			rdc_fill_header(urdc, &header);
-
-			(void) rdc_write_header(krdc, &header);
-		}
-	}
-
-	mutex_exit(&krdc->bmapmutex);
-
-	if (krdc->dcio_bitmap != NULL) {
-		if (cmd == RDC_CMD_SUSPEND) {
-			if (krdc->bitmapfd)
-				(void) rdc_write_bitmap(krdc);
-		}
-
-		kmem_free(krdc->dcio_bitmap, krdc->bitmap_size);
-		krdc->dcio_bitmap = NULL;
-	}
-	if (krdc->bitmap_ref != NULL) {
-		kmem_free(krdc->bitmap_ref, (krdc->bitmap_size * BITS_IN_BYTE *
-		    BMAP_REF_PREF_SIZE));
-		krdc->bitmap_ref = NULL;
-	}
-
-	krdc->bitmap_size = 0;
-}
-
-static int
-rdc_alloc_bitmap(rdc_k_info_t *krdc)
-{
-	rdc_u_info_t *urdc;
-	char *bitmapname;
-	nsc_size_t bitmap_ref_size;
-
-	if (krdc == NULL) {
-		return (-1);
-	}
-
-	urdc = &rdc_u_info[krdc->index];
-	if (rdc_get_vflags(urdc) & RDC_PRIMARY)
-		bitmapname = &urdc->primary.bitmap[0];
-	else
-		bitmapname = &urdc->secondary.bitmap[0];
-
-	if (krdc->dcio_bitmap) {
-#ifdef DEBUG
-		cmn_err(CE_WARN,
-		    "!rdc_alloc_bitmap: bitmap %s already allocated",
-		    bitmapname);
-#endif
-		return (0);
-	}
-
-	if (urdc->volume_size == 0)
-		return (-1);
-
-	krdc->bitmap_size = BMAP_LOG_BYTES(urdc->volume_size);
-	/* Round up */
-	krdc->bitmap_size = (krdc->bitmap_size + 511) / 512 * 512;
-
-	krdc->dcio_bitmap = (uchar_t *)kmem_zalloc(krdc->bitmap_size,
-	    KM_SLEEP);
-	if (krdc->dcio_bitmap == NULL) {
-		cmn_err(CE_WARN, "!rdc_alloc_bitmap: alloc %" NSC_SZFMT
-		    " failed for %s", krdc->bitmap_size, bitmapname);
-		return (-1);
-	}
-
-	/*
-	 * use largest ref count type size as we haven't opened the bitmap
-	 * volume yet to find out what has acutally be used.
-	 */
-	bitmap_ref_size = krdc->bitmap_size * BITS_IN_BYTE * BMAP_REF_PREF_SIZE;
-	if ((rdc_get_vflags(urdc) & RDC_PRIMARY) &&
-	    ((krdc->type_flag & RDC_ASYNCMODE) != 0)) {
-		krdc->bitmap_ref = (uchar_t *)kmem_zalloc(bitmap_ref_size,
-		    KM_SLEEP);
-		if (krdc->bitmap_ref == NULL) {
-			cmn_err(CE_WARN,
-			    "!rdc_alloc_bitmap: ref alloc %" NSC_SZFMT
-			    " failed for %s",
-			    bitmap_ref_size, bitmapname);
-			return (-1);
-		}
-	}
-
-	return (0);
-}
-
-
-static int
-rdc_open_bitmap(rdc_k_info_t *krdc)
-{
-	rdc_u_info_t *urdc;
-	int sts;
-	uint_t hints = 0;
-	nsc_size_t vol_size;
-	char *bitmapname;
-	nsc_size_t req_size;
-	nsc_size_t bit_size;
-
-	urdc = &rdc_u_info[krdc->index];
-	if (rdc_get_vflags(urdc) & RDC_PRIMARY)
-		bitmapname = &urdc->primary.bitmap[0];
-	else
-		bitmapname = &urdc->secondary.bitmap[0];
-
-	urdc->bits_set = 0;
-
-	bit_size = req_size = RDC_BITMAP_FBA + FBA_LEN(krdc->bitmap_size);
-	if (RDC_IS_DISKQ(krdc->group)) {
-		req_size += FBA_LEN(krdc->bitmap_size * BITS_IN_BYTE *
-		    sizeof (unsigned char));
-	}
-
-	mutex_enter(&krdc->bmapmutex);
-
-	rdc_set_refcnt_ops(krdc, sizeof (unsigned char));
-#ifdef DEBUG_REFCNT
-	cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
-	    (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
-#endif
-	if (krdc->bitmapfd == NULL)
-		krdc->bitmapfd = nsc_open(bitmapname,
-		    NSC_RDCHR_ID|NSC_FILE|NSC_RDWR, 0, 0, 0);
-	if (krdc->bitmapfd == NULL) {
-		krdc->bitmapfd = nsc_open(bitmapname,
-		    NSC_RDCHR_ID|NSC_CACHE|NSC_DEVICE|NSC_RDWR, 0, 0, 0);
-		if (krdc->bitmapfd == NULL) {
-			cmn_err(CE_WARN, "!rdc_open_bitmap: Unable to open %s",
-			    bitmapname);
-			goto fail;
-		}
-	}
-
-	sts = _rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL);
-	if (!RDC_SUCCESS(sts)) {
-		cmn_err(CE_WARN, "!rdc_open_bitmap: Reserve failed for %s",
-		    bitmapname);
-		goto fail;
-	}
-	sts = nsc_partsize(krdc->bitmapfd, &vol_size);
-	_rdc_rlse_devs(krdc, RDC_BMP);
-
-	if (!RDC_SUCCESS(sts)) {
-		cmn_err(CE_WARN,
-		    "!rdc_open_bitmap: nsc_partsize failed for %s", bitmapname);
-		goto fail;
-	}
-
-	if (vol_size < req_size) {
-		/* minimum size supports unsigned char reference counts */
-		cmn_err(CE_WARN,
-		    "!rdc_open_bitmap: bitmap %s too small: %" NSC_SZFMT " vs %"
-		    NSC_SZFMT "blocks",
-		    bitmapname, vol_size, req_size);
-		goto fail;
-	}
-
-	if (rdc_bitmap_mode == RDC_BMP_NEVER) {
-		krdc->bitmap_write = 0;		/* forced off */
-	} else if (rdc_bitmap_mode == RDC_BMP_ALWAYS ||
-	    (nsc_node_hints(&hints) == 0 && (hints & NSC_FORCED_WRTHRU) == 0)) {
-		krdc->bitmap_write = 1;		/* forced or autodetect on */
-	} else {
-		/* autodetect off */
-		krdc->bitmap_write = 0;
-	}
-
-	mutex_exit(&krdc->bmapmutex);
-	if (RDC_IS_DISKQ(krdc->group) && (rdc_refcntsize(krdc) <
-	    BMAP_REF_PREF_SIZE)) {
-		/* test for larger ref counts */
-#ifdef DEBUG_REFCNT
-	cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
-	    (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
-#endif
-		req_size = bit_size;
-		req_size += FBA_LEN(krdc->bitmap_size * BITS_IN_BYTE *
-		    sizeof (unsigned int));
-		if (vol_size >= req_size)
-			rdc_set_refcnt_ops(krdc, sizeof (unsigned int));
-	}
-#ifdef DEBUG_REFCNT
-	cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
-	    (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
-#endif
-	return (0);
-
-fail:
-	mutex_exit(&krdc->bmapmutex);
-	return (-1);
-}
-
-int
-rdc_enable_bitmap(rdc_k_info_t *krdc, int set)
-{
-	rdc_header_t header;
-	rdc_u_info_t *urdc;
-	char *bitmapname;
-
-	urdc = &rdc_u_info[krdc->index];
-
-	if (rdc_alloc_bitmap(krdc) < 0)
-		goto fail;
-
-	if (rdc_open_bitmap(krdc) < 0)
-		goto fail;
-
-	if (rdc_get_vflags(urdc) & RDC_PRIMARY)
-		bitmapname = &urdc->primary.bitmap[0];
-	else
-		bitmapname = &urdc->secondary.bitmap[0];
-
-	mutex_enter(&krdc->bmapmutex);
-
-	rdc_clr_flags(urdc, RDC_BMP_FAILED);
-	if (rdc_read_header(krdc, &header) < 0) {
-		cmn_err(CE_WARN,
-		    "!rdc_enable_bitmap: Read header %s failed", bitmapname);
-		mutex_exit(&krdc->bmapmutex);
-		goto fail;
-	}
-
-	rdc_fill_header(urdc, &header);
-	rdc_set_refcnt_ops(krdc, (size_t)header.refcntsize);
-
-	if (set)
-		(void) RDC_FILL_BITMAP(krdc, FALSE);
-
-	if (rdc_write_header(krdc, &header) < 0) {
-		cmn_err(CE_WARN,
-		    "!rdc_enable_bitmap: Write header %s failed",
-		    bitmapname);
-		mutex_exit(&krdc->bmapmutex);
-		goto fail;
-	}
-	mutex_exit(&krdc->bmapmutex);
-
-	if (rdc_write_bitmap(krdc) < 0) {
-		cmn_err(CE_WARN,
-		    "!rdc_enable_bitmap: Write bitmap %s failed",
-		    bitmapname);
-		goto fail;
-	}
-
-	return (0);
-
-fail:
-	rdc_free_bitmap(krdc, RDC_CMD_ENABLE);
-	rdc_close_bitmap(krdc);
-
-	mutex_enter(&krdc->bmapmutex);
-	rdc_set_flags_log(urdc, RDC_BMP_FAILED, "I/O failed");
-	mutex_exit(&krdc->bmapmutex);
-	return (-1);
-}
-
-static int
-_rdc_rdwr_refcnt(rdc_k_info_t *krdc, int rwflg)
-{
-	rdc_u_info_t *urdc;
-	int rc;
-	nsc_off_t offset;
-	nsc_size_t len;
-
-	urdc = &rdc_u_info[krdc->index];
-
-#ifdef DEBUG_REFCNT
-	cmn_err(CE_NOTE, "!rdc_rdwr_refcnt: %s refcount for %s",
-	    (rwflg == NSC_READ) ? "resuming" : "writing",
-	    urdc->primary.bitmap);
-#endif
-	ASSERT(MUTEX_HELD(QLOCK((&krdc->group->diskq))));
-	mutex_enter(&krdc->bmapmutex);
-
-	if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
-		cmn_err(CE_WARN, "!rdc_rdwr_refcnt: reserve failed");
-		goto fail;
-	}
-
-	if (krdc->bitmap_size == 0) {
-		cmn_err(CE_WARN, "!rdc_rdwr_refcnt: NULL bitmap!");
-		goto fail;
-	}
-
-	offset = RDC_BITREF_FBA(krdc);
-	len = krdc->bitmap_size * BITS_IN_BYTE * rdc_refcntsize(krdc);
-
-	rc = rdc_ns_io(krdc->bitmapfd, rwflg, offset,
-	    (uchar_t *)krdc->bitmap_ref, len);
-
-	if (!RDC_SUCCESS(rc)) {
-		cmn_err(CE_WARN, "!unable to %s refcount from bitmap %s",
-		    (rwflg == NSC_READ) ? "retrieve" : "write",
-		    urdc->primary.bitmap);
-		rdc_set_flags_log(urdc, RDC_BMP_FAILED, "refcount I/O failed");
-		goto fail;
-	}
-
-	_rdc_rlse_devs(krdc, RDC_BMP);
-
-	mutex_exit(&krdc->bmapmutex);
-
-#ifdef DEBUG_REFCNT
-	cmn_err(CE_NOTE, "!rdc_rdwr_refcnt: %s refcount for %s",
-	    (rwflg == NSC_READ) ? "resumed" : "wrote",
-	    urdc->primary.bitmap);
-#endif
-	return (0);
-
-	fail:
-	_rdc_rlse_devs(krdc, RDC_BMP);
-
-	mutex_exit(&krdc->bmapmutex);
-
-	return (-1);
-
-}
-
-/*
- * rdc_read_refcount
- * read the stored refcount from disk
- * queue lock is held
- */
-int
-rdc_read_refcount(rdc_k_info_t *krdc)
-{
-	int	rc;
-
-	rc = _rdc_rdwr_refcnt(krdc, NSC_READ);
-
-	return (rc);
-}
-
-/*
- * rdc_write_refcount
- * writes krdc->bitmap_ref to the diskq
- * called with qlock held
- */
-int
-rdc_write_refcount(rdc_k_info_t *krdc)
-{
-	int	rc;
-
-	rc = _rdc_rdwr_refcnt(krdc, NSC_WRBUF);
-
-	return (rc);
-}
-
-static int
-rdc_resume_state(rdc_k_info_t *krdc, const rdc_header_t *header)
-{
-	rdc_u_info_t *urdc;
-	char *bitmapname;
-
-	urdc = &rdc_u_info[krdc->index];
-	if (rdc_get_vflags(urdc) & RDC_PRIMARY)
-		bitmapname = &urdc->primary.bitmap[0];
-	else
-		bitmapname = &urdc->secondary.bitmap[0];
-
-	if (header->magic != RDC_HDR_MAGIC) {
-		cmn_err(CE_WARN, "!rdc_resume_state: Bad magic in %s",
-		    bitmapname);
-		return (-1);
-	}
-
-	if (strncmp(urdc->primary.file, header->primary.file,
-	    NSC_MAXPATH) != 0) {
-#ifdef DEBUG
-		cmn_err(CE_WARN,
-		    "!rdc_resume_state: Found %s Expected %s",
-		    header->primary.file, urdc->primary.file);
-#endif /* DEBUG */
-		return (-1);
-	}
-
-	if (strncmp(urdc->secondary.file, header->secondary.file,
-	    NSC_MAXPATH) != 0) {
-#ifdef DEBUG
-		cmn_err(CE_WARN,
-		    "!rdc_resume_state: Found %s Expected %s",
-		    header->secondary.file, urdc->secondary.file);
-#endif /* DEBUG */
-		return (-1);
-	}
-
-	if (strncmp(urdc->primary.bitmap, header->primary.bitmap,
-	    NSC_MAXPATH) != 0) {
-#ifdef DEBUG
-		cmn_err(CE_WARN,
-		    "!rdc_resume_state: Found %s Expected %s",
-		    header->primary.bitmap, urdc->primary.bitmap);
-#endif /* DEBUG */
-		return (-1);
-	}
-
-	if (strncmp(urdc->secondary.bitmap, header->secondary.bitmap,
-	    NSC_MAXPATH) != 0) {
-#ifdef DEBUG
-		cmn_err(CE_WARN,
-		    "!rdc_resume_state: Found %s Expected %s",
-		    header->secondary.bitmap, urdc->secondary.bitmap);
-#endif /* DEBUG */
-		return (-1);
-	}
-
-	if (header->maxqfbas)
-		urdc->maxqfbas = header->maxqfbas;
-
-	if (header->maxqitems)
-		urdc->maxqitems = header->maxqitems;
-
-	if (header->autosync >= 0)
-		urdc->autosync = header->autosync;
-
-	if (header->asyncthr)
-		urdc->asyncthr = header->asyncthr;
-
-	rdc_many_enter(krdc);
-	rdc_set_refcnt_ops(krdc, header->refcntsize);
-#ifdef DEBUG_REFCNT
-	cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
-	    (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
-#endif
-	if (header->flags & RDC_VOL_FAILED)
-		rdc_set_flags(urdc, RDC_VOL_FAILED);
-	if (header->flags & RDC_QUEUING)
-		rdc_set_flags(urdc, RDC_QUEUING);
-
-	rdc_clr_flags(urdc, RDC_SYNC_NEEDED | RDC_RSYNC_NEEDED);
-	rdc_set_mflags(urdc, (header->flags & RDC_RSYNC_NEEDED));
-	rdc_set_flags(urdc, (header->flags & RDC_SYNC_NEEDED));
-	rdc_many_exit(krdc);
-
-	if (urdc->flags & RDC_VOL_FAILED) {
-
-		/* Our disk was failed so set all the bits in the bitmap */
-
-		if (RDC_FILL_BITMAP(krdc, TRUE) != 0) {
-			cmn_err(CE_WARN,
-			    "!rdc_resume_state: Fill bitmap %s failed",
-			    bitmapname);
-			return (-1);
-		}
-		rdc_many_enter(krdc);
-		if (IS_STATE(urdc, RDC_QUEUING))
-			rdc_clr_flags(urdc, RDC_QUEUING);
-		rdc_many_exit(krdc);
-	} else {
-		/* Header was good, so read in the bitmap */
-
-		if (rdc_read_bitmap(krdc, NULL) < 0) {
-			cmn_err(CE_WARN,
-			    "!rdc_resume_state: Read bitmap %s failed",
-			    bitmapname);
-			return (-1);
-		}
-
-		urdc->bits_set = RDC_COUNT_BITMAP(krdc);
-
-		/*
-		 * Check if another node went down with bits set, but
-		 * without setting logging mode.
-		 */
-		if (urdc->bits_set != 0 &&
-		    (rdc_get_vflags(urdc) & RDC_ENABLED) &&
-		    !(rdc_get_vflags(urdc) & RDC_LOGGING)) {
-			rdc_group_log(krdc, RDC_NOFLUSH | RDC_NOREMOTE, NULL);
-		}
-	}
-
-	/* if we are using a disk queue, read in the reference count bits */
-	if (RDC_IS_DISKQ(krdc->group)) {
-		disk_queue *q = &krdc->group->diskq;
-		mutex_enter(QLOCK(q));
-		if ((rdc_read_refcount(krdc) < 0)) {
-			cmn_err(CE_WARN,
-			    "!rdc_resume_state: Resume bitmap %s's refcount"
-			    "failed",
-			    urdc->primary.bitmap);
-			mutex_exit(QLOCK(q));
-			rdc_many_enter(krdc);
-			if (IS_STATE(urdc, RDC_QUEUING))
-				rdc_clr_flags(urdc, RDC_QUEUING);
-			rdc_many_exit(krdc);
-			return (-1);
-		}
-		mutex_exit(QLOCK(q));
-	}
-
-	return (0);
-}
-
-
-int
-rdc_resume_bitmap(rdc_k_info_t *krdc)
-{
-	rdc_header_t header;
-	rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
-	char *bitmapname;
-
-	if (rdc_alloc_bitmap(krdc) < 0)
-		goto allocfail;
-
-	if (rdc_open_bitmap(krdc) < 0)
-		goto fail;
-
-	if (rdc_get_vflags(urdc) & RDC_PRIMARY)
-		bitmapname = &urdc->primary.bitmap[0];
-	else
-		bitmapname = &urdc->secondary.bitmap[0];
-
-	mutex_enter(&krdc->bmapmutex);
-
-	rdc_clr_flags(urdc, RDC_BMP_FAILED);
-	if (rdc_read_header(krdc, &header) < 0) {
-		cmn_err(CE_WARN,
-		    "!rdc_resume_bitmap: Read header %s failed", bitmapname);
-		mutex_exit(&krdc->bmapmutex);
-		goto fail;
-	}
-
-	mutex_exit(&krdc->bmapmutex);
-
-	/* Resuming from the bitmap, so do some checking */
-
-	/*CONSTCOND*/
-	ASSERT(FBA_LEN(sizeof (rdc_header_t)) <= RDC_BITMAP_FBA);
-	/*CONSTCOND*/
-	ASSERT(sizeof (rdc_header_t) >= sizeof (rdc_headerv2_t));
-
-	if (header.magic == RDC_HDR_V2) {
-		rdc_headerv2_t *hdr_v2 = (rdc_headerv2_t *)&header;
-		rdc_header_t new_header;
-
-#ifdef DEBUG
-		cmn_err(CE_WARN,
-		    "!rdc_resume_bitmap: Converting v2 header for bitmap %s",
-		    bitmapname);
-#endif
-		bzero((char *)&new_header, sizeof (rdc_header_t));
-
-		new_header.autosync = -1;
-		new_header.magic = RDC_HDR_MAGIC;
-		new_header.syshostid = urdc->syshostid;
-
-		if (hdr_v2->volume_failed)
-			new_header.flags |= RDC_VOL_FAILED;
-		if (hdr_v2->sync_needed == RDC_SYNC)
-			new_header.flags |= RDC_SYNC_NEEDED;
-		if (hdr_v2->sync_needed == RDC_FULL_SYNC)
-			new_header.flags |= RDC_SYNC_NEEDED;
-		if (hdr_v2->sync_needed == RDC_REV_SYNC)
-			new_header.flags |= RDC_RSYNC_NEEDED;
-		if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
-			(void) strncpy(new_header.primary.file,
-			    hdr_v2->filename, NSC_MAXPATH);
-			(void) strncpy(new_header.primary.bitmap,
-			    hdr_v2->bitmapname, NSC_MAXPATH);
-			(void) strncpy(new_header.secondary.file,
-			    urdc->secondary.file, NSC_MAXPATH);
-			(void) strncpy(new_header.secondary.bitmap,
-			    urdc->secondary.bitmap, NSC_MAXPATH);
-		} else {
-			(void) strncpy(new_header.secondary.file,
-			    hdr_v2->filename, NSC_MAXPATH);
-			(void) strncpy(new_header.secondary.bitmap,
-			    hdr_v2->bitmapname, NSC_MAXPATH);
-			(void) strncpy(new_header.primary.file,
-			    urdc->primary.file, NSC_MAXPATH);
-			(void) strncpy(new_header.primary.bitmap,
-			    urdc->primary.bitmap, NSC_MAXPATH);
-		}
-
-		bcopy(&new_header, &header, sizeof (rdc_header_t));
-
-		mutex_enter(&krdc->bmapmutex);
-		if (rdc_write_header(krdc, &header) < 0) {
-			mutex_exit(&krdc->bmapmutex);
-			cmn_err(CE_WARN,
-			    "!rdc_resume_bitmap: Write header %s failed",
-			    bitmapname);
-			goto fail;
-		}
-		mutex_exit(&krdc->bmapmutex);
-
-	} else if (header.magic == RDC_HDR_V3) {
-		/*
-		 * just update asyncthr and magic, and then we're done
-		 */
-		header.magic = RDC_HDR_MAGIC;
-		header.asyncthr = RDC_ASYNCTHR;
-		mutex_enter(&krdc->bmapmutex);
-		if (rdc_write_header(krdc, &header) < 0) {
-			mutex_exit(&krdc->bmapmutex);
-			cmn_err(CE_WARN,
-			    "!rdc_resume_bitmap: Write header %s failed",
-			    bitmapname);
-			goto fail;
-		}
-		mutex_exit(&krdc->bmapmutex);
-	}
-
-	if (rdc_resume_state(krdc, &header) == 0)
-		return (0);
-
-	rdc_close_bitmap(krdc);
-
-fail:
-	(void) RDC_FILL_BITMAP(krdc, FALSE);
-	rdc_clr_flags(urdc, RDC_QUEUING);
-	if (krdc->bitmap_ref)
-		bzero(krdc->bitmap_ref, krdc->bitmap_size * BITS_IN_BYTE *
-		    rdc_refcntsize(krdc));
-
-allocfail:
-	mutex_enter(&krdc->bmapmutex);
-	rdc_set_flags_log(urdc, RDC_BMP_FAILED, "resume bitmap failed");
-	mutex_exit(&krdc->bmapmutex);
-
-	return (-1);
-}
-
-void
-rdc_std_zero_bitref(rdc_k_info_t *krdc)
-{
-	nsc_size_t vol_size;
-	int sts;
-	size_t newrefcntsize;
-
-	if (krdc->bitmap_ref) {
-		mutex_enter(&krdc->bmapmutex);
-		bzero(krdc->bitmap_ref, krdc->bitmap_size * BITS_IN_BYTE *
-		    BMAP_REF_PREF_SIZE);
-		if (RDC_IS_DISKQ(krdc->group) && rdc_refcntsize(krdc) !=
-		    BMAP_REF_PREF_SIZE) {
-			/* see if we can upgrade the size of the ref counters */
-			sts = _rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL);
-			if (!RDC_SUCCESS(sts)) {
-				goto nochange;
-			}
-			sts = nsc_partsize(krdc->bitmapfd, &vol_size);
-
-			newrefcntsize = rdc_ref_size_possible(krdc->bitmap_size,
-			    vol_size);
-			if (newrefcntsize > rdc_refcntsize(krdc)) {
-				rdc_set_refcnt_ops(krdc, newrefcntsize);
-#ifdef DEBUG_REFCNT
-	cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
-	    (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
-#endif
-			}
-nochange:
-			_rdc_rlse_devs(krdc, RDC_BMP);
-		}
-		mutex_exit(&krdc->bmapmutex);
-	}
-}
-
-int
-rdc_reset_bitmap(rdc_k_info_t *krdc)
-{
-	rdc_u_info_t *urdc;
-	rdc_header_t header;
-	char *bitmapname;
-
-	urdc = &rdc_u_info[krdc->index];
-	if (rdc_get_vflags(urdc) & RDC_PRIMARY)
-		bitmapname = &urdc->primary.bitmap[0];
-	else
-		bitmapname = &urdc->secondary.bitmap[0];
-
-	mutex_enter(&krdc->bmapmutex);
-
-	rdc_clr_flags(urdc, RDC_BMP_FAILED);
-	if (rdc_read_header(krdc, &header) < 0) {
-		cmn_err(CE_WARN,
-		    "!rdc_reset_bitmap: Read header %s failed", bitmapname);
-		goto fail_with_mutex;
-	}
-
-	rdc_fill_header(urdc, &header);
-
-	if (rdc_write_header(krdc, &header) < 0) {
-		cmn_err(CE_WARN,
-		    "!rdc_reset_bitmap: Write header %s failed",
-		    bitmapname);
-		goto fail_with_mutex;
-	}
-	mutex_exit(&krdc->bmapmutex);
-
-	if (krdc->bitmap_write == -1)
-		krdc->bitmap_write = 0;
-
-	if (krdc->bitmap_write == 0) {
-		if (rdc_write_bitmap_fill(krdc) < 0) {
-			cmn_err(CE_WARN,
-			    "!rdc_reset_bitmap: Write bitmap %s failed",
-			    bitmapname);
-			goto fail;
-		}
-		krdc->bitmap_write = -1;
-	} else if (rdc_write_bitmap(krdc) < 0) {
-		cmn_err(CE_WARN,
-		    "!rdc_reset_bitmap: Write bitmap %s failed",
-		    bitmapname);
-		goto fail;
-	}
-
-	return (0);
-
-fail:
-	mutex_enter(&krdc->bmapmutex);
-fail_with_mutex:
-	rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reset failed");
-	mutex_exit(&krdc->bmapmutex);
-#ifdef DEBUG
-	cmn_err(CE_NOTE, "!SNDR: unable to reset bitmap for %s:%s",
-	    urdc->secondary.intf, urdc->secondary.file);
-#endif
-	return (-1);
-}
-
-
-/*
- * General bitmap operations
- */
-
-/*
- * rdc_set_bitmap_many()
- *
- * Used during reverse syncs to a 1-to-many primary to keep the 'many'
- * bitmaps up to date.
- */
-void
-rdc_set_bitmap_many(rdc_k_info_t *krdc, nsc_off_t pos, nsc_size_t len)
-{
-	uint_t dummy;
-
-#ifdef DEBUG
-	rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
-	if (!(rdc_get_vflags(urdc) & RDC_PRIMARY)) {
-		cmn_err(CE_PANIC, "rdc_set_bitmap_many: not primary, urdc %p",
-		    (void *) urdc);
-	}
-#endif
-
-	if (IS_MANY(krdc)) {
-		rdc_k_info_t *krd;
-		rdc_u_info_t *urd;
-
-		rdc_many_enter(krdc);
-
-		for (krd = krdc->many_next; krd != krdc; krd = krd->many_next) {
-			urd = &rdc_u_info[krd->index];
-			if (!IS_ENABLED(urd))
-				continue;
-			ASSERT(urd->flags & RDC_PRIMARY);
-			(void) RDC_SET_BITMAP(krd, pos, len, &dummy);
-		}
-
-		rdc_many_exit(krdc);
-	}
-}
-
-
-static int
-_rdc_net_bmap(const struct bmap6 *b6, net_bdata6 *bd6)
-{
-	rdc_k_info_t *krdc = &rdc_k_info[b6->cd];
-	struct timeval t;
-	int e, ret;
-	uint64_t left;
-	uint64_t bmap_blksize;
-
-	bmap_blksize = krdc->rpc_version < RDC_VERSION7 ?
-	    BMAP_BLKSIZE : BMAP_BLKSIZEV7;
-
-	t.tv_sec = rdc_rpc_tmout;
-	t.tv_usec = 0;
-
-	if (bd6->data.data_val == NULL) {
-		return (EINVAL);
-	}
-
-	left = b6->size;
-	bd6->endoblk = 0;
-	while (left) {
-		if (left >= bmap_blksize)
-			bd6->size = (int)bmap_blksize;
-		else
-			bd6->size = (int)left;
-
-		bd6->data.data_len = bd6->size;
-
-		if ((uint64_t)bd6->size > left) {
-			left = 0;
-		} else {
-			left -= bd6->size;
-		}
-		/*
-		 * mark the last block sent.
-		 */
-		if (left == 0) {
-			bd6->endoblk = 1;
-		}
-		ASSERT(krdc->rpc_version);
-		if (krdc->rpc_version <= RDC_VERSION5) {
-			struct net_bdata bd;
-			bd.cd = bd6->cd;
-			bd.offset = bd6->offset;
-			bd.size = bd6->size;
-			bd.data.data_len = bd6->data.data_len;
-			bd.data.data_val = bd6->data.data_val;
-			e = rdc_clnt_call(krdc->lsrv, RDCPROC_BDATA,
-			    krdc->rpc_version, xdr_net_bdata, (char *)&bd,
-			    xdr_int, (char *)&ret, &t);
-		} else {
-			e = rdc_clnt_call(krdc->lsrv, RDCPROC_BDATA6,
-			    krdc->rpc_version, xdr_net_bdata6, (char *)bd6,
-			    xdr_int, (char *)&ret, &t);
-		}
-		if (e || ret) {
-			if (e)
-				ret = e;
-			return (ret);
-		}
-		bd6->offset += bmap_blksize;
-		bd6->data.data_val += bmap_blksize;
-	}
-	return (0);
-}
-
-
-/*
- * Standard bitmap operations (combined kmem/disk bitmaps).
- */
-
-/*
- * rdc_std_set_bitmask(pos, len, &bitmask)
- * set a bitmask for this range. used to clear the correct
- * bits after flushing
- */
-static void
-rdc_std_set_bitmask(const nsc_off_t fba_pos, const nsc_size_t fba_len,
-    uint_t *bitmask)
-{
-	int first, st, en;
-	if (bitmask)
-		*bitmask = 0;
-	else
-		return;
-
-	first = st = FBA_TO_LOG_NUM(fba_pos);
-	en = FBA_TO_LOG_NUM(fba_pos + fba_len - 1);
-	while (st <= en) {
-		BMAP_BIT_SET((uchar_t *)bitmask, st - first);
-		st++;
-	}
-
-}
-/*
- * rdc_std_set_bitmap(krdc, fba_pos, fba_len, &bitmask)
- *
- * Mark modified segments in the dual copy file bitmap
- * to provide fast recovery
- * Note that bitmask allows for 32 segments, which at 32k per segment equals
- * 1 megabyte. If we ever allow more than this to be transferred in one
- * operation, or decrease the segment size, then this code will have to be
- * changed accordingly.
- */
-
-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)
-{
-	int first, st, en;
-	int fbaset = 0;
-	nsc_off_t fba = 0;
-	int printerr = 10;
-	int tries = RDC_FUTILE_ATTEMPTS;
-	int queuing = RDC_QUEUING;
-	rdc_u_info_t *urdc;
-
-	if (bitmask)
-		*bitmask = 0;
-	else
-		return (-1);
-
-	urdc = &rdc_u_info[krdc->index];
-	if (rdc_get_vflags(urdc) & RDC_BMP_FAILED)
-		return (-1);
-
-	if (krdc->bitmap_write == 0) {
-		if (rdc_write_bitmap_fill(krdc) < 0)
-			return (-1);
-		krdc->bitmap_write = -1;
-	}
-	first = st = FBA_TO_LOG_NUM(fba_pos);
-	en = FBA_TO_LOG_NUM(fba_pos + fba_len - 1);
-	ASSERT(st <= en);
-	while (st <= en) {
-		int use_ref;
-again:
-		mutex_enter(&krdc->bmapmutex);
-
-		if (krdc->dcio_bitmap == NULL) {
-#ifdef DEBUG
-			cmn_err(CE_WARN, "!rdc_std_set_bitmap: "
-			    "recovery bitmaps not allocated");
-#endif
-			mutex_exit(&krdc->bmapmutex);
-			return (-1);
-		}
-
-		use_ref = IS_PRIMARY(urdc) && IS_ASYNC(urdc) &&
-		    ((rdc_get_vflags(urdc) & RDC_QUEUING) ||
-		    !(rdc_get_vflags(urdc) & RDC_LOGGING));
-
-
-		if (!BMAP_BIT_ISSET(krdc->dcio_bitmap, st)) {
-			BMAP_BIT_SET(krdc->dcio_bitmap, st);
-			if (use_ref) {
-				ASSERT(BMAP_REF_ISSET(krdc, st) ==
-				    0);
-				BMAP_REF_FORCE(krdc, st, 1);
-			}
-			BMAP_BIT_SET((uchar_t *)bitmask, st - first);
-			urdc->bits_set++;
-			if ((!fbaset) || fba != BIT_TO_FBA(st)) {
-				if (fbaset && krdc->bitmap_write > 0) {
-					mutex_exit(&krdc->bmapmutex);
-					if (rdc_write_bitmap_fba(krdc, fba) < 0)
-						return (-1);
-					mutex_enter(&krdc->bmapmutex);
-				}
-				fba = BIT_TO_FBA(st);
-				fbaset = 1;
-			}
-		} else {
-		/*
-		 * Just bump reference count
-		 * For logging or syncing we do not care what the reference
-		 * is as it will be forced back on the state transition.
-		 */
-			if (use_ref) {
-				if (BMAP_REF_ISSET(krdc, st) ==
-				    BMAP_REF_MAXVAL(krdc)) {
-					/*
-					 * Rollover of reference count.
-					 */
-
-					if (!(rdc_get_vflags(urdc) &
-					    RDC_VOL_FAILED)) {
-						/*
-						 * Impose throttle to help dump
-						 * queue
-						 */
-						mutex_exit(&krdc->bmapmutex);
-						delay(4);
-						rdc_bitmap_delay++;
-						if (printerr--) {
-	cmn_err(CE_WARN, "!SNDR: bitmap reference count maxed out for %s:%s",
-	    urdc->secondary.intf, urdc->secondary.file);
-
-						}
-
-						if ((tries-- <= 0) &&
-						    IS_STATE(urdc, queuing)) {
-	cmn_err(CE_WARN, "!SNDR: giving up on reference count, logging set"
-	    " %s:%s", urdc->secondary.intf, urdc->secondary.file);
-							rdc_group_enter(krdc);
-							rdc_group_log(krdc,
-							    RDC_NOFLUSH |
-							    RDC_NOREMOTE|
-							    RDC_FORCE_GROUP,
-					    "ref count retry limit exceeded");
-							rdc_group_exit(krdc);
-						}
-						goto again;
-					}
-				} else {
-					BMAP_REF_SET(krdc, st);
-				}
-			}
-		}
-		mutex_exit(&krdc->bmapmutex);
-		st++;
-	}
-	if (fbaset && krdc->bitmap_write > 0) {
-		if (rdc_write_bitmap_fba(krdc, fba) < 0)
-			return (-1);
-	}
-	return (0);
-}
-
-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)
-{
-	int first, st, en;
-	nsc_off_t fba = 0;
-	int fbaset = 0;
-	uint_t bm = bitmask;
-	uchar_t *ptr = (uchar_t *)&bm;
-	rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
-
-	if (rdc_get_vflags(urdc) & RDC_BMP_FAILED)
-		return;
-
-	first = st = FBA_TO_LOG_NUM(fba_pos);
-	en = FBA_TO_LOG_NUM(fba_pos + fba_len - 1);
-	ASSERT(st <= en);
-	while (st <= en) {
-		mutex_enter(&krdc->bmapmutex);
-
-		if (krdc->dcio_bitmap == NULL) {
-#ifdef DEBUG
-			cmn_err(CE_WARN, "!rdc_std_clr_bitmap: "
-			    "recovery bitmaps not allocated");
-#endif
-			mutex_exit(&krdc->bmapmutex);
-			return;
-		}
-
-		if (((bitmask == 0xffffffff) ||
-		    (BMAP_BIT_ISSET(ptr, st - first))) &&
-		    BMAP_BIT_ISSET(krdc->dcio_bitmap, st)) {
-
-			int use_ref = IS_PRIMARY(urdc) && IS_ASYNC(urdc) &&
-			    ((rdc_get_vflags(urdc) & RDC_QUEUING) ||
-			    !(rdc_get_vflags(urdc) & RDC_LOGGING));
-
-			if (force || (use_ref == 0)) {
-				if (krdc->bitmap_ref)
-					BMAP_REF_FORCE(krdc, st, 0);
-			} else if (use_ref) {
-				if (BMAP_REF_ISSET(krdc, st) != 0)
-					BMAP_REF_CLR(krdc, st);
-
-			}
-
-			if ((use_ref == 0) || (use_ref &&
-			    !BMAP_REF_ISSET(krdc, st))) {
-				BMAP_BIT_CLR(krdc->dcio_bitmap, st);
-
-				urdc->bits_set--;
-				if (!fbaset || fba != BIT_TO_FBA(st)) {
-					if (fbaset &&
-					    krdc->bitmap_write > 0) {
-						mutex_exit(&krdc->bmapmutex);
-						if (rdc_write_bitmap_fba(krdc,
-						    fba) < 0)
-							return;
-						mutex_enter(&krdc->bmapmutex);
-					}
-					fba = BIT_TO_FBA(st);
-					fbaset = 1;
-				}
-			}
-		}
-		mutex_exit(&krdc->bmapmutex);
-		st++;
-	}
-	if (fbaset && krdc->bitmap_write > 0) {
-		if (rdc_write_bitmap_fba(krdc, fba) < 0)
-			return;
-	}
-}
-
-/*
- * make sure that this bit is set. if it isn't, set it
- * used when transitioning from async to sync while going
- * from rep to log. an overlapping sync write may unconditionally
- * clear the bit that has not been replicated. when the queue
- * is being dumped or this is called just to make sure pending stuff
- * is in the bitmap
- */
-void
-rdc_std_check_bit(rdc_k_info_t *krdc, nsc_off_t pos, nsc_size_t len)
-{
-	int st;
-	int en;
-	nsc_off_t fba;
-	rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
-	st = FBA_TO_LOG_NUM(pos);
-	en = FBA_TO_LOG_NUM(pos + len - 1);
-
-	if (rdc_get_vflags(urdc) & RDC_BMP_FAILED)
-		return;
-
-	while (st <= en) {
-		mutex_enter(&krdc->bmapmutex);
-
-		if (krdc->dcio_bitmap == NULL) {
-#ifdef DEBUG
-			cmn_err(CE_WARN, "!rdc_std_check_bit: "
-			    "recovery bitmaps not allocated");
-#endif
-			mutex_exit(&krdc->bmapmutex);
-			return;
-		}
-
-		if (!BMAP_BIT_ISSET(krdc->dcio_bitmap, st)) {
-			BMAP_BIT_SET(krdc->dcio_bitmap, st);
-			if (krdc->bitmap_write > 0) {
-				fba = BIT_TO_FBA(st);
-				mutex_exit(&krdc->bmapmutex);
-				(void) rdc_write_bitmap_fba(krdc, fba);
-				mutex_enter(&krdc->bmapmutex);
-			}
-			urdc->bits_set++;
-
-		}
-		mutex_exit(&krdc->bmapmutex);
-		st++;
-	}
-
-}
-
-/*
- * rdc_std_count_dirty(krdc):
- *
- * Determine the number of segments that need to be flushed, This should
- * agree with the number of segments logged, but since we don't lock when
- * we increment, we force these values to agree
- */
-static int
-rdc_std_count_dirty(rdc_k_info_t *krdc)
-{
-	rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
-	int i, count, size;
-
-	if (krdc->dcio_bitmap == NULL) {
-#ifdef DEBUG
-		cmn_err(CE_WARN,
-		    "!rdc_std_count_dirty: no bitmap configured for %s",
-		    urdc->primary.file);
-#endif
-		return (0);
-	}
-
-	count = 0;
-	ASSERT(urdc->volume_size != 0);
-	size = FBA_TO_LOG_LEN(urdc->volume_size);
-	for (i = 0; i < size; i++)
-		if (BMAP_BIT_ISSET(krdc->dcio_bitmap, i))
-			count++;
-
-	if (count > size)
-		count = size;
-
-	return (count);
-}
-
-
-static int
-rdc_std_bit_isset(rdc_k_info_t *krdc, const int bit)
-{
-	return (BMAP_BIT_ISSET(krdc->dcio_bitmap, bit));
-}
-
-
-/*
- * rdc_std_fill_bitmap(krdc, write)
- *
- * Called to force bitmaps to a fully dirty state
- */
-static int
-rdc_std_fill_bitmap(rdc_k_info_t *krdc, const int write)
-{
-	rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
-	int i, size;
-
-	if (krdc->dcio_bitmap == NULL) {
-#ifdef DEBUG
-		cmn_err(CE_WARN,
-		    "!rdc_std_fill_bitmap: no bitmap configured for %s",
-		    urdc->primary.file);
-#endif
-		return (-1);
-	}
-
-	ASSERT(urdc->volume_size != 0);
-	size = FBA_TO_LOG_LEN(urdc->volume_size);
-	for (i = 0; i < size; i++)
-		BMAP_BIT_SET(krdc->dcio_bitmap, i);
-
-	urdc->bits_set = size;
-
-	if (write)
-		return (rdc_write_bitmap(krdc));
-
-	return (0);
-}
-
-
-/*
- * rdc_std_zero_bitmap(krdc)
- *
- * Called on the secondary after a sync has completed to force bitmaps
- * to a fully clean state
- */
-static void
-rdc_std_zero_bitmap(rdc_k_info_t *krdc)
-{
-	rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
-	int i, size;
-
-	if (krdc->dcio_bitmap == NULL) {
-#ifdef DEBUG
-		cmn_err(CE_WARN,
-		    "!rdc_std_zero_bitmap: no bitmap configured for %s",
-		    urdc->primary.file);
-#endif
-		return;
-	}
-#ifdef DEBUG
-	cmn_err(CE_NOTE, "!Clearing bitmap for %s", urdc->secondary.file);
-#endif
-
-	ASSERT(urdc->volume_size != 0);
-	size = FBA_TO_LOG_LEN(urdc->volume_size);
-	for (i = 0; i < size; i++)
-		BMAP_BIT_CLR(krdc->dcio_bitmap, i);
-	if (krdc->bitmap_write > 0)
-		(void) rdc_write_bitmap(krdc);
-
-	urdc->bits_set = 0;
-}
-
-
-/*
- * rdc_std_net_bmap()
- *
- * WARNING acts as both client and server
- */
-static int
-rdc_std_net_bmap(const struct bmap6 *b)
-{
-	rdc_k_info_t *krdc = &rdc_k_info[b->cd];
-	struct net_bdata6 bd;
-
-	bd.data.data_val = (char *)krdc->dcio_bitmap;
-	bd.cd = b->dual;
-	bd.offset = 0;
-
-	return (_rdc_net_bmap(b, &bd));
-}
-
-
-/*
- * rdc_std_net_bdata
- */
-static int
-rdc_std_net_bdata(const struct net_bdata6 *bd)
-{
-	rdc_k_info_t *krdc = &rdc_k_info[bd->cd];
-
-	rdc_lor((uchar_t *)bd->data.data_val,
-	    (uchar_t *)(((char *)krdc->dcio_bitmap) + bd->offset), bd->size);
-
-	return (0);
-}
-
-
-static struct rdc_bitmap_ops rdc_std_bitmap_ops = {
-	rdc_std_set_bitmap,
-	rdc_std_clr_bitmap,
-	rdc_std_count_dirty,
-	rdc_std_bit_isset,
-	rdc_std_fill_bitmap,
-	rdc_std_zero_bitmap,
-	rdc_std_net_bmap,
-	rdc_std_net_bdata,
-	rdc_std_zero_bitref,
-	rdc_std_set_bitmask,
-	rdc_std_check_bit
-};
-
-
-void
-rdc_bitmap_init()
-{
-	rdc_bitmap_ops = &rdc_std_bitmap_ops;
-	rdc_wrflag = NSC_WRITE;
-}
-
-static void
-rdc_bmap_ref_byte_set(rdc_k_info_t *krdc, int ind)
-{
-	unsigned char *bmap = (unsigned char *)krdc->bitmap_ref;
-
-	ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned char));
-	bmap[ind]++;
-}
-
-static void
-rdc_bmap_ref_byte_clr(rdc_k_info_t *krdc, int ind)
-{
-	unsigned char *bmap = (unsigned char *)krdc->bitmap_ref;
-
-	ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned char));
-	bmap[ind]--;
-}
-
-static unsigned int
-rdc_bmap_ref_byte_isset(rdc_k_info_t *krdc, int ind)
-{
-	unsigned char *bmap = (unsigned char *)krdc->bitmap_ref;
-
-	ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned char));
-	return ((unsigned int)(bmap[ind]));
-}
-
-static void
-rdc_bmap_ref_byte_force(rdc_k_info_t *krdc, int ind, unsigned int val)
-{
-	unsigned char *bmap = (unsigned char *)krdc->bitmap_ref;
-
-	ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned char));
-	bmap[ind] = (unsigned char) val;
-}
-
-/* ARGSUSED */
-static unsigned int
-rdc_bmap_ref_byte_maxval(rdc_k_info_t *krdc)
-{
-	ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned char));
-	return ((unsigned int)(UINT8_MAX));
-}
-
-struct bm_ref_ops rdc_ref_byte_ops = {
-	rdc_bmap_ref_byte_set,
-	rdc_bmap_ref_byte_clr,
-	rdc_bmap_ref_byte_isset,
-	rdc_bmap_ref_byte_force,
-	rdc_bmap_ref_byte_maxval,
-	sizeof (unsigned char)
-};
-
-static void
-rdc_bmap_ref_int_set(rdc_k_info_t *krdc, int ind)
-{
-	unsigned int *bmap = (unsigned int *)krdc->bitmap_ref;
-
-	ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned int));
-	bmap[ind]++;
-}
-
-static void
-rdc_bmap_ref_int_clr(rdc_k_info_t *krdc, int ind)
-{
-	unsigned int *bmap = (unsigned int *)krdc->bitmap_ref;
-
-	ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned int));
-	bmap[ind]--;
-}
-
-static unsigned int
-rdc_bmap_ref_int_isset(rdc_k_info_t *krdc, int ind)
-{
-	unsigned int *bmap = (unsigned int *)krdc->bitmap_ref;
-
-	ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned int));
-	return ((bmap[ind]));
-}
-
-static void
-rdc_bmap_ref_int_force(rdc_k_info_t *krdc, int ind, unsigned int val)
-{
-	unsigned int *bmap = (unsigned int *)krdc->bitmap_ref;
-
-	ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned int));
-	bmap[ind] = val;
-}
-
-/* ARGSUSED */
-static unsigned int
-rdc_bmap_ref_int_maxval(rdc_k_info_t *krdc)
-{
-	ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned int));
-	return ((unsigned int)(UINT_MAX));
-}
-
-struct bm_ref_ops rdc_ref_int_ops = {
-	rdc_bmap_ref_int_set,
-	rdc_bmap_ref_int_clr,
-	rdc_bmap_ref_int_isset,
-	rdc_bmap_ref_int_force,
-	rdc_bmap_ref_int_maxval,
-	sizeof (unsigned int)
-};
