1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #include <sys/types.h>
  27 #include <sys/ksynch.h>
  28 #include <sys/cmn_err.h>
  29 #include <sys/kmem.h>
  30 #include <sys/stat.h>
  31 #include <sys/errno.h>
  32 
  33 #include "../solaris/nsc_thread.h"
  34 #ifdef DS_DDICT
  35 #include "../contract.h"
  36 #endif
  37 #include <sys/nsctl/nsctl.h>
  38 
  39 #include <sys/kmem.h>
  40 #include <sys/cmn_err.h>
  41 #include <sys/ddi.h>
  42 
  43 #include "rdc_io.h"
  44 #include "rdc_bitmap.h"
  45 #include "rdc_clnt.h"
  46 #include "rdc_diskq.h"
  47 
  48 #include <sys/unistat/spcs_s.h>
  49 #include <sys/unistat/spcs_s_k.h>
  50 #include <sys/unistat/spcs_errors.h>
  51 
  52 #ifndef UINT8_MAX
  53 #define UINT8_MAX 255
  54 #endif
  55 
  56 #ifndef UINT_MAX
  57 #define UINT_MAX 0xffffffff
  58 #endif
  59 
  60 /*
  61  * RDC bitmap functions.
  62  */
  63 
  64 /*
  65  * RDC cluster integration notes.
  66  *
  67  * 1. Configuration
  68  *
  69  * 1.1. Change 'rdc_bitmap_mode' in /usr/kernel/drv/rdc.conf to '1'.
  70  *
  71  * 2. Operation
  72  *
  73  * 2.1. SunCluster ensures that only one physical host has any rdc
  74  *      controlled device imported at any one time.  Hence rdc will
  75  *      only be active on a single node for any set at a time.
  76  *
  77  * 2.2. So operation from the kernel perspective looks just like
  78  *      operation on a single, standalone, node.
  79  *
  80  */
  81 
  82 struct rdc_bitmap_ops *rdc_bitmap_ops;          /* the bitmap ops switch */
  83 static int rdc_wrflag;                          /* write flag for io */
  84 int rdc_bitmap_delay = 0;
  85 extern nsc_io_t *_rdc_io_hc;
  86 
  87 int rdc_suspend_diskq(rdc_k_info_t *krdc);
  88 
  89 /*
  90  * rdc_ns_io
  91  *      Perform read or write on an underlying ns device
  92  *
  93  * fd           - nsc file descriptor
  94  * flag         - nsc io direction and characteristics flag
  95  * fba_pos      - offset from beginning of device in FBAs
  96  * io_addr      - pointer to data buffer
  97  * io_len       - length of io in bytes
  98  */
  99 
 100 int
 101 rdc_ns_io(nsc_fd_t *fd, int flag, nsc_off_t fba_pos, uchar_t *io_addr,
 102     nsc_size_t io_len)
 103 {
 104         nsc_buf_t *tmp;
 105         nsc_vec_t *vecp;
 106         uchar_t *vaddr;
 107         size_t  copy_len;
 108         int     vlen;
 109         int     rc;
 110         nsc_size_t      fba_req, fba_len;
 111         nsc_size_t      maxfbas = 0;
 112         nsc_size_t      tocopy;
 113         unsigned char *toaddr;
 114 
 115         rc = nsc_maxfbas(fd, 0, &maxfbas);
 116         if (!RDC_SUCCESS(rc)) {
 117 #ifdef DEBUG
 118                 cmn_err(CE_WARN, "!rdc_ns_io: maxfbas failed (%d)", rc);
 119 #endif
 120                 maxfbas = 256;
 121         }
 122         toaddr = io_addr;
 123         fba_req = FBA_LEN(io_len);
 124 loop:
 125         tmp = NULL;
 126         fba_len = min(fba_req, maxfbas);
 127         tocopy = min(io_len, FBA_SIZE(fba_len));
 128         ASSERT(tocopy < INT32_MAX);
 129 
 130         rc = nsc_alloc_buf(fd, fba_pos, fba_len, flag, &tmp);
 131         if (!RDC_SUCCESS(rc)) {
 132                 if (tmp) {
 133                         (void) nsc_free_buf(tmp);
 134                 }
 135                 return (EIO);
 136         }
 137 
 138         if ((flag & NSC_WRITE) != 0 && (flag & NSC_READ) == 0 &&
 139             FBA_OFF(io_len) != 0) {
 140                 /*
 141                  * Not overwriting all of the last FBA, so read in the
 142                  * old contents now before we overwrite it with the new
 143                  * data.
 144                  */
 145                 rc = nsc_read(tmp, fba_pos+FBA_NUM(io_len), 1, 0);
 146                 if (!RDC_SUCCESS(rc)) {
 147                         (void) nsc_free_buf(tmp);
 148                         return (EIO);
 149                 }
 150         }
 151 
 152         vecp = tmp->sb_vec;
 153         vlen = vecp->sv_len;
 154         vaddr = vecp->sv_addr;
 155 
 156         while (tocopy > 0) {
 157                 if (vecp->sv_addr == 0 || vecp->sv_len == 0) {
 158 #ifdef DEBUG
 159                         cmn_err(CE_WARN, "!rdc_ns_io: ran off end of handle");
 160 #endif
 161                         break;
 162                 }
 163 
 164                 copy_len = (size_t)min(vlen, (int)tocopy);
 165 
 166                 if (flag & NSC_WRITE)
 167                         bcopy(toaddr, vaddr, copy_len);
 168                 else
 169                         bcopy(vaddr, toaddr, copy_len);
 170 
 171                 toaddr += copy_len;
 172                 io_addr += copy_len;    /* adjust position in callers buffer */
 173                 io_len -= copy_len;     /* adjust total byte length remaining */
 174                 tocopy -= copy_len;     /* adjust chunk byte length remaining */
 175                 vaddr += copy_len;      /* adjust location in sv_vec_t */
 176                 vlen -= copy_len;       /* adjust length left in sv_vec_t */
 177 
 178                 if (vlen <= 0) {
 179                         vecp++;
 180                         vaddr = vecp->sv_addr;
 181                         vlen = vecp->sv_len;
 182                 }
 183         }
 184 
 185         if (flag & NSC_WRITE) {
 186                 rc = nsc_write(tmp, tmp->sb_pos, tmp->sb_len, 0);
 187                 if (!RDC_SUCCESS(rc)) {
 188                         (void) nsc_free_buf(tmp);
 189                         return (rc);
 190                 }
 191         }
 192 
 193         (void) nsc_free_buf(tmp);
 194 
 195         fba_pos += fba_len;
 196         fba_req -= fba_len;
 197         if (fba_req > 0)
 198                 goto loop;
 199 
 200         return (0);
 201 }
 202 
 203 /*
 204  * Must be called with krdc->bmapmutex held.
 205  */
 206 static void
 207 rdc_fill_header(rdc_u_info_t *urdc, rdc_header_t *header)
 208 {
 209         rdc_k_info_t *krdc = &rdc_k_info[urdc->index];
 210 #ifdef DEBUG
 211         ASSERT(MUTEX_HELD(&krdc->bmapmutex));
 212 #endif
 213 
 214         header->magic = RDC_HDR_MAGIC;
 215         (void) strncpy(header->primary.file, urdc->primary.file, NSC_MAXPATH);
 216         (void) strncpy(header->primary.bitmap, urdc->primary.bitmap,
 217             NSC_MAXPATH);
 218         (void) strncpy(header->secondary.file, urdc->secondary.file,
 219             NSC_MAXPATH);
 220         (void) strncpy(header->secondary.bitmap, urdc->secondary.bitmap,
 221             NSC_MAXPATH);
 222         header->flags = urdc->flags | urdc->sync_flags | urdc->bmap_flags;
 223         header->autosync = urdc->autosync;
 224         header->maxqfbas = urdc->maxqfbas;
 225         header->maxqitems = urdc->maxqitems;
 226         header->asyncthr = urdc->asyncthr;
 227         header->syshostid = urdc->syshostid;
 228         header->refcntsize = rdc_refcntsize(krdc);
 229 #ifdef DEBUG_REFCNT
 230         cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
 231             (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
 232 #endif
 233 }
 234 
 235 /*
 236  * Must be called with krdc->bmapmutex held.
 237  */
 238 static int
 239 rdc_read_header(rdc_k_info_t *krdc, rdc_header_t *header)
 240 {
 241         int sts;
 242         rdc_u_info_t *urdc;
 243         union {
 244                 rdc_header_t *current;
 245                 rdc_headerv4_t *v4;
 246         } u_hdrp;
 247 
 248         if (krdc == NULL) {
 249                 return (-1);
 250         }
 251 
 252         ASSERT(MUTEX_HELD(&krdc->bmapmutex));
 253 
 254         urdc = &rdc_u_info[krdc->index];
 255         if (rdc_get_vflags(urdc) & RDC_BMP_FAILED)
 256                 return (-1);
 257 
 258         if (krdc->bitmapfd == NULL) {
 259                 return (-1);
 260         }
 261         if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
 262                 rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
 263                 return (-1);
 264         }
 265 
 266         if (krdc->bmp_kstats) {
 267                 mutex_enter(krdc->bmp_kstats->ks_lock);
 268                 kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
 269                 mutex_exit(krdc->bmp_kstats->ks_lock);
 270         }
 271 
 272         sts = rdc_ns_io(krdc->bitmapfd, NSC_RDBUF, 0, (uchar_t *)header,
 273             sizeof (rdc_header_t));
 274 
 275         if (krdc->bmp_kstats) {
 276                 mutex_enter(krdc->bmp_kstats->ks_lock);
 277                 kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
 278                 mutex_exit(krdc->bmp_kstats->ks_lock);
 279                 KSTAT_IO_PTR(krdc->bmp_kstats)->reads++;
 280                 KSTAT_IO_PTR(krdc->bmp_kstats)->nread += sizeof (rdc_header_t);
 281         }
 282 
 283         if (!RDC_SUCCESS(sts)) {
 284                 cmn_err(CE_WARN, "!rdc_read_header: %s read failed %d",
 285                     urdc->primary.file, sts);
 286                 rdc_set_flags_log(urdc, RDC_BMP_FAILED, "read header failed");
 287         }
 288 
 289         _rdc_rlse_devs(krdc, RDC_BMP);
 290 
 291         if (!RDC_SUCCESS(sts))
 292                 return (-1);
 293         switch (header->magic) {
 294         case RDC_HDR_V4:
 295                 /*
 296                  * old header format - upgrade incore copy, disk copy will
 297                  * be changed when state is re-written.
 298                  */
 299 #ifdef DEBUG
 300                 cmn_err(CE_NOTE, "!sndr: old style (V4) bit map header");
 301 #endif
 302                 header->magic = RDC_HDR_MAGIC;
 303                 u_hdrp.current = header;
 304                 /* copy down items moved by new maxq??? sizes */
 305                 u_hdrp.current->asyncthr = u_hdrp.v4->asyncthr;
 306                 u_hdrp.current->syshostid = u_hdrp.v4->syshostid;
 307                 u_hdrp.current->maxqitems = u_hdrp.v4->maxqitems;
 308                 u_hdrp.current->maxqfbas = u_hdrp.v4->maxqfbas;
 309                 u_hdrp.current->refcntsize = 1;      /* new field */
 310 #ifdef DEBUG_REFCNT
 311         cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
 312             (int)u_hdrp.current->refcntsize, __LINE__, __FILE__);
 313 #endif
 314                 return (0);
 315         case RDC_HDR_MAGIC:
 316                 /* current header type */
 317                 return (0);
 318         default:
 319                 /* not a header we currently understand */
 320                 return (0);
 321         }
 322 }
 323 
 324 /*
 325  * Must be called with krdc->bmapmutex held.
 326  */
 327 static int
 328 rdc_write_header(rdc_k_info_t *krdc, rdc_header_t *header)
 329 {
 330         rdc_u_info_t *urdc;
 331         int sts;
 332 
 333         if (krdc == NULL) {
 334                 return (-1);
 335         }
 336 
 337         ASSERT(MUTEX_HELD(&krdc->bmapmutex));
 338 
 339         urdc = &rdc_u_info[krdc->index];
 340         if (rdc_get_vflags(urdc) & RDC_BMP_FAILED)
 341                 return (-1);
 342 
 343         if (krdc->bitmapfd == NULL) {
 344                 return (-1);
 345         }
 346 
 347         if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
 348                 rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
 349                 return (-1);
 350         }
 351 
 352         if (krdc->bmp_kstats) {
 353                 mutex_enter(krdc->bmp_kstats->ks_lock);
 354                 kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
 355                 mutex_exit(krdc->bmp_kstats->ks_lock);
 356         }
 357 
 358         sts = rdc_ns_io(krdc->bitmapfd, rdc_wrflag, 0, (uchar_t *)header,
 359             sizeof (rdc_header_t));
 360 
 361         if (krdc->bmp_kstats) {
 362                 mutex_enter(krdc->bmp_kstats->ks_lock);
 363                 kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
 364                 mutex_exit(krdc->bmp_kstats->ks_lock);
 365                 KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
 366                 KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten +=
 367                     sizeof (rdc_header_t);
 368         }
 369 
 370         if (!RDC_SUCCESS(sts)) {
 371                 cmn_err(CE_WARN, "!rdc_write_header: %s write failed %d",
 372                     urdc->primary.file, sts);
 373                 rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
 374         }
 375 
 376         _rdc_rlse_devs(krdc, RDC_BMP);
 377 
 378         if (!RDC_SUCCESS(sts))
 379                 return (-1);
 380         else
 381                 return (0);
 382 }
 383 
 384 struct bm_ref_ops rdc_ref_byte_ops;
 385 struct bm_ref_ops rdc_ref_int_ops;
 386 
 387 static void
 388 rdc_set_refcnt_ops(rdc_k_info_t *krdc, size_t refcntsize)
 389 {
 390         switch (refcntsize) {
 391         default:
 392                 /* FALLTHRU */
 393         case sizeof (unsigned char):
 394                 krdc->bm_refs = &rdc_ref_byte_ops;
 395                 break;
 396         case sizeof (unsigned int):
 397                 krdc->bm_refs = &rdc_ref_int_ops;
 398                 break;
 399         }
 400 #ifdef DEBUG_REFCNT
 401         cmn_err(CE_NOTE, "!sndr: set refcnt ops for refcntsize %d - %d:%s",
 402             (int)refcntsize, __LINE__, __FILE__);
 403 #endif
 404 }
 405 
 406 size_t
 407 rdc_refcntsize(rdc_k_info_t *krdc)
 408 {
 409         if (krdc->bm_refs == &rdc_ref_int_ops)
 410                 return (sizeof (unsigned int));
 411         return (sizeof (unsigned char));
 412 }
 413 
 414 int
 415 rdc_read_state(rdc_k_info_t *krdc, int *statep, int *hostidp)
 416 {
 417         rdc_header_t header;
 418         rdc_u_info_t *urdc;
 419         int sts;
 420 
 421         if (krdc == NULL) {
 422                 return (-1);
 423         }
 424 
 425         mutex_enter(&krdc->bmapmutex);
 426 
 427         urdc = &rdc_u_info[krdc->index];
 428         if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
 429                 mutex_exit(&krdc->bmapmutex);
 430                 return (-1);
 431         }
 432 
 433         if (krdc->bitmapfd == NULL) {
 434                 mutex_exit(&krdc->bmapmutex);
 435                 return (-1);
 436         }
 437 
 438         sts = rdc_read_header(krdc, &header);
 439         mutex_exit(&krdc->bmapmutex);
 440 
 441         if (!RDC_SUCCESS(sts)) {
 442                 return (-1);
 443         }
 444 
 445         switch (header.magic) {
 446         case RDC_HDR_MAGIC:
 447                 *statep = header.flags;
 448                 *hostidp = header.syshostid;
 449                 rdc_set_refcnt_ops(krdc, header.refcntsize);
 450 #ifdef DEBUG_REFCNT
 451         cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
 452             (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
 453 #endif
 454                 sts = 0;
 455                 break;
 456         default:
 457                 sts = -1;
 458                 break;
 459         }
 460 
 461         return (sts);
 462 }
 463 
 464 int
 465 rdc_clear_state(rdc_k_info_t *krdc)
 466 {
 467         rdc_u_info_t *urdc;
 468         int sts;
 469         rdc_header_t header;
 470 
 471         if (krdc == NULL) {
 472                 return (-1);
 473         }
 474 
 475         mutex_enter(&krdc->bmapmutex);
 476 
 477         urdc = &rdc_u_info[krdc->index];
 478         if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
 479                 mutex_exit(&krdc->bmapmutex);
 480                 return (-1);
 481         }
 482 
 483         if (krdc->bitmapfd == NULL) {
 484                 mutex_exit(&krdc->bmapmutex);
 485                 return (-1);
 486         }
 487 
 488         if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
 489                 rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
 490                 mutex_exit(&krdc->bmapmutex);
 491                 return (-1);
 492         }
 493 
 494         bzero(&header, sizeof (header));
 495 
 496         if (krdc->bmp_kstats) {
 497                 mutex_enter(krdc->bmp_kstats->ks_lock);
 498                 kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
 499                 mutex_exit(krdc->bmp_kstats->ks_lock);
 500         }
 501 
 502         sts = rdc_ns_io(krdc->bitmapfd, rdc_wrflag, 0,
 503             (uchar_t *)&header, sizeof (header));
 504 
 505         if (krdc->bmp_kstats) {
 506                 mutex_enter(krdc->bmp_kstats->ks_lock);
 507                 kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
 508                 mutex_exit(krdc->bmp_kstats->ks_lock);
 509                 KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
 510                 KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten +=
 511                     sizeof (rdc_header_t);
 512         }
 513 
 514         if (!RDC_SUCCESS(sts)) {
 515                 cmn_err(CE_WARN, "!rdc_clear_state: %s write failed",
 516                     urdc->primary.file);
 517                 rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
 518         }
 519 
 520         _rdc_rlse_devs(krdc, RDC_BMP);
 521         mutex_exit(&krdc->bmapmutex);
 522 
 523         if (!RDC_SUCCESS(sts))
 524                 return (-1);
 525         else
 526                 return (0);
 527 }
 528 
 529 void
 530 rdc_write_state(rdc_u_info_t *urdc)
 531 {
 532         rdc_k_info_t *krdc;
 533         int sts;
 534         rdc_header_t header;
 535 
 536         if (urdc == NULL) {
 537                 return;
 538         }
 539 
 540         krdc = &rdc_k_info[urdc->index];
 541 
 542         mutex_enter(&krdc->bmapmutex);
 543 
 544         if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
 545                 mutex_exit(&krdc->bmapmutex);
 546                 return;
 547         }
 548 
 549         if (krdc->bitmapfd == NULL) {
 550                 mutex_exit(&krdc->bmapmutex);
 551                 return;
 552         }
 553 
 554         if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
 555                 rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
 556                 mutex_exit(&krdc->bmapmutex);
 557                 return;
 558         }
 559 
 560         if (krdc->bmp_kstats) {
 561                 mutex_enter(krdc->bmp_kstats->ks_lock);
 562                 kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
 563                 mutex_exit(krdc->bmp_kstats->ks_lock);
 564         }
 565 
 566         sts = rdc_ns_io(krdc->bitmapfd, NSC_RDBUF, 0, (uchar_t *)&header,
 567             sizeof (header));
 568 
 569         if (krdc->bmp_kstats) {
 570                 mutex_enter(krdc->bmp_kstats->ks_lock);
 571                 kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
 572                 mutex_exit(krdc->bmp_kstats->ks_lock);
 573                 KSTAT_IO_PTR(krdc->bmp_kstats)->reads++;
 574                 KSTAT_IO_PTR(krdc->bmp_kstats)->nread += sizeof (header);
 575         }
 576 
 577         if (!RDC_SUCCESS(sts)) {
 578                 cmn_err(CE_WARN, "!rdc_write_state: %s read failed",
 579                     urdc->primary.file);
 580                 rdc_set_flags_log(urdc, RDC_BMP_FAILED, "read failed");
 581                 goto done;
 582         }
 583 
 584         rdc_fill_header(urdc, &header);
 585 
 586         if (krdc->bmp_kstats) {
 587                 mutex_enter(krdc->bmp_kstats->ks_lock);
 588                 kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
 589                 mutex_exit(krdc->bmp_kstats->ks_lock);
 590         }
 591 
 592         sts = rdc_ns_io(krdc->bitmapfd, rdc_wrflag, 0,
 593             (uchar_t *)&header, sizeof (header));
 594 
 595         if (krdc->bmp_kstats) {
 596                 mutex_enter(krdc->bmp_kstats->ks_lock);
 597                 kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
 598                 mutex_exit(krdc->bmp_kstats->ks_lock);
 599                 KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
 600                 KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten += sizeof (header);
 601         }
 602 
 603         if (!RDC_SUCCESS(sts)) {
 604                 cmn_err(CE_WARN, "!rdc_write_state: %s write failed",
 605                     urdc->primary.file);
 606                 rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
 607         }
 608 
 609 done:
 610         _rdc_rlse_devs(krdc, RDC_BMP);
 611         mutex_exit(&krdc->bmapmutex);
 612 }
 613 
 614 
 615 struct bitmapdata {
 616         uchar_t *data;
 617         size_t  len;
 618 };
 619 
 620 static int
 621 rdc_read_bitmap(rdc_k_info_t *krdc, struct bitmapdata *data)
 622 {
 623         rdc_u_info_t *urdc;
 624         int sts;
 625 
 626         if (krdc == NULL) {
 627                 return (-1);
 628         }
 629 
 630         if (data != NULL) {
 631                 data->data = kmem_alloc(krdc->bitmap_size, KM_SLEEP);
 632                 data->len = krdc->bitmap_size;
 633         }
 634 
 635         mutex_enter(&krdc->bmapmutex);
 636 
 637         urdc = &rdc_u_info[krdc->index];
 638         if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
 639                 mutex_exit(&krdc->bmapmutex);
 640                 return (-1);
 641         }
 642 
 643         if (krdc->bitmapfd == NULL) {
 644                 mutex_exit(&krdc->bmapmutex);
 645                 return (-1);
 646         }
 647 
 648         if (data == NULL && krdc->dcio_bitmap == NULL) {
 649                 mutex_exit(&krdc->bmapmutex);
 650                 return (-1);
 651         }
 652 
 653         if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
 654                 cmn_err(CE_WARN, "!rdc_read_bitmap: %s reserve failed",
 655                     urdc->primary.file);
 656                 rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
 657                 mutex_exit(&krdc->bmapmutex);
 658                 return (-1);
 659         }
 660 
 661         if (krdc->bmp_kstats) {
 662                 mutex_enter(krdc->bmp_kstats->ks_lock);
 663                 kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
 664                 mutex_exit(krdc->bmp_kstats->ks_lock);
 665         }
 666 
 667         sts = rdc_ns_io(krdc->bitmapfd, NSC_RDBUF, RDC_BITMAP_FBA,
 668             data ? data->data : krdc->dcio_bitmap, krdc->bitmap_size);
 669 
 670         if (krdc->bmp_kstats) {
 671                 mutex_enter(krdc->bmp_kstats->ks_lock);
 672                 kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
 673                 mutex_exit(krdc->bmp_kstats->ks_lock);
 674                 KSTAT_IO_PTR(krdc->bmp_kstats)->reads++;
 675                 KSTAT_IO_PTR(krdc->bmp_kstats)->nread += krdc->bitmap_size;
 676         }
 677 
 678         _rdc_rlse_devs(krdc, RDC_BMP);
 679 
 680         if (!RDC_SUCCESS(sts)) {
 681                 cmn_err(CE_WARN, "!rdc_read_bitmap: %s read failed",
 682                     urdc->primary.file);
 683                 rdc_set_flags_log(urdc, RDC_BMP_FAILED, "read failed");
 684                 mutex_exit(&krdc->bmapmutex);
 685                 return (-1);
 686         }
 687 
 688         mutex_exit(&krdc->bmapmutex);
 689         return (0);
 690 }
 691 
 692 int
 693 rdc_write_bitmap(rdc_k_info_t *krdc)
 694 {
 695         rdc_u_info_t *urdc;
 696         int sts;
 697 
 698         if (krdc == NULL) {
 699                 return (-1);
 700         }
 701 
 702         mutex_enter(&krdc->bmapmutex);
 703 
 704         urdc = &rdc_u_info[krdc->index];
 705         if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
 706                 mutex_exit(&krdc->bmapmutex);
 707                 return (-1);
 708         }
 709 
 710         if (krdc->bitmapfd == NULL) {
 711                 mutex_exit(&krdc->bmapmutex);
 712                 return (-1);
 713         }
 714 
 715         if (krdc->dcio_bitmap == NULL) {
 716                 mutex_exit(&krdc->bmapmutex);
 717                 return (-1);
 718         }
 719 
 720         if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
 721                 rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
 722                 mutex_exit(&krdc->bmapmutex);
 723                 return (-1);
 724         }
 725 
 726         if (krdc->bmp_kstats) {
 727                 mutex_enter(krdc->bmp_kstats->ks_lock);
 728                 kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
 729                 mutex_exit(krdc->bmp_kstats->ks_lock);
 730         }
 731 
 732         sts = rdc_ns_io(krdc->bitmapfd, rdc_wrflag, RDC_BITMAP_FBA,
 733             krdc->dcio_bitmap, krdc->bitmap_size);
 734 
 735         if (krdc->bmp_kstats) {
 736                 mutex_enter(krdc->bmp_kstats->ks_lock);
 737                 kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
 738                 mutex_exit(krdc->bmp_kstats->ks_lock);
 739                 KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
 740                 KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten += krdc->bitmap_size;
 741         }
 742 
 743         _rdc_rlse_devs(krdc, RDC_BMP);
 744 
 745         if (!RDC_SUCCESS(sts)) {
 746                 cmn_err(CE_WARN, "!rdc_write_bitmap: %s write failed",
 747                     urdc->primary.file);
 748                 rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
 749                 mutex_exit(&krdc->bmapmutex);
 750                 return (-1);
 751         }
 752 
 753         mutex_exit(&krdc->bmapmutex);
 754         return (0);
 755 }
 756 
 757 int
 758 rdc_write_bitmap_fba(rdc_k_info_t *krdc, nsc_off_t fba)
 759 {
 760         rdc_u_info_t *urdc;
 761         int sts;
 762 
 763         if (krdc == NULL) {
 764                 return (-1);
 765         }
 766 
 767         mutex_enter(&krdc->bmapmutex);
 768 
 769         urdc = &rdc_u_info[krdc->index];
 770         if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
 771                 mutex_exit(&krdc->bmapmutex);
 772                 return (-1);
 773         }
 774 
 775         if (krdc->bitmapfd == NULL) {
 776                 mutex_exit(&krdc->bmapmutex);
 777                 return (-1);
 778         }
 779 
 780         if (krdc->dcio_bitmap == NULL) {
 781                 mutex_exit(&krdc->bmapmutex);
 782                 return (-1);
 783         }
 784 
 785         if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
 786                 cmn_err(CE_WARN, "!rdc_write_bitmap_fba: %s reserve failed",
 787                     urdc->primary.file);
 788                 rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
 789                 mutex_exit(&krdc->bmapmutex);
 790                 return (-1);
 791         }
 792 
 793         if (krdc->bmp_kstats) {
 794                 mutex_enter(krdc->bmp_kstats->ks_lock);
 795                 kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
 796                 mutex_exit(krdc->bmp_kstats->ks_lock);
 797         }
 798         sts = rdc_ns_io(krdc->bitmapfd, rdc_wrflag, RDC_BITMAP_FBA + fba,
 799             krdc->dcio_bitmap + fba * 512, 512);
 800 
 801         if (krdc->bmp_kstats) {
 802                 mutex_enter(krdc->bmp_kstats->ks_lock);
 803                 kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
 804                 mutex_exit(krdc->bmp_kstats->ks_lock);
 805                 KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
 806                 KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten += 512;
 807         }
 808 
 809         _rdc_rlse_devs(krdc, RDC_BMP);
 810 
 811         if (!RDC_SUCCESS(sts)) {
 812                 cmn_err(CE_WARN, "!rdc_write_bitmap_fba: %s write failed",
 813                     urdc->primary.file);
 814                 rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
 815                 mutex_exit(&krdc->bmapmutex);
 816                 return (-1);
 817         }
 818 
 819         mutex_exit(&krdc->bmapmutex);
 820         return (0);
 821 }
 822 
 823 
 824 static int
 825 rdc_write_bitmap_pattern(rdc_k_info_t *krdc, const char pattern)
 826 {
 827         rdc_u_info_t *urdc;
 828         char *buffer;
 829         nsc_buf_t *h;
 830         nsc_vec_t *v;
 831         int rc;
 832         size_t i;
 833         nsc_size_t len;
 834         int  off;
 835         size_t buffer_size;
 836         size_t iolen;
 837         nsc_size_t      fba_req;
 838         nsc_off_t       fba_len, fba_pos;
 839         nsc_size_t      maxfbas = 0;
 840         nsc_size_t      tocopy;
 841 
 842         if (krdc == NULL) {
 843                 return (-1);
 844         }
 845 
 846         mutex_enter(&krdc->bmapmutex);
 847 
 848         urdc = &rdc_u_info[krdc->index];
 849         if (rdc_get_vflags(urdc) & RDC_BMP_FAILED) {
 850                 mutex_exit(&krdc->bmapmutex);
 851                 return (-1);
 852         }
 853 
 854         if (krdc->bitmapfd == NULL) {
 855                 mutex_exit(&krdc->bmapmutex);
 856                 return (-1);
 857         }
 858 
 859         if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
 860                 rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reserve failed");
 861                 mutex_exit(&krdc->bmapmutex);
 862                 return (-1);
 863         }
 864 
 865         buffer_size = FBA_SIZE(1);
 866         ASSERT(buffer_size < INT32_MAX);
 867         buffer = kmem_alloc(buffer_size, KM_SLEEP);
 868 
 869         for (i = 0; i < buffer_size; i++) {
 870                 buffer[i] = pattern;
 871         }
 872 
 873         rc = nsc_maxfbas(krdc->bitmapfd, 0, &maxfbas);
 874         if (!RDC_SUCCESS(rc)) {
 875 #ifdef DEBUG
 876                 cmn_err(CE_WARN,
 877                     "!rdc_write_bitmap_pattern: maxfbas failed (%d)", rc);
 878 #endif
 879                 maxfbas = 256;
 880         }
 881 
 882         fba_req = FBA_LEN(krdc->bitmap_size);        /* total FBAs left to copy */
 883         fba_pos = RDC_BITMAP_FBA;               /* current FBA position */
 884         tocopy = krdc->bitmap_size;          /* total bytes left to copy */
 885 loop:
 886         h = NULL;
 887         fba_len = min(fba_req, maxfbas);        /* FBAs to alloc this time */
 888 
 889         rc = nsc_alloc_buf(krdc->bitmapfd, fba_pos, fba_len, rdc_wrflag, &h);
 890         if (!RDC_SUCCESS(rc)) {
 891                 cmn_err(CE_WARN, "!rdc_write_bitmap_pattern: %s "
 892                     "write failed %d", urdc->primary.file, rc);
 893                 rdc_set_flags_log(urdc, RDC_BMP_FAILED, "nsc_alloc_buf failed");
 894                 if (h) {
 895                         (void) nsc_free_handle(h);
 896                 }
 897 
 898                 _rdc_rlse_devs(krdc, RDC_BMP);
 899                 mutex_exit(&krdc->bmapmutex);
 900                 rc = -1;
 901                 goto finish;
 902         }
 903 
 904                                 /* bytes to copy this time */
 905         len = min(tocopy, FBA_SIZE(fba_len));
 906         v = h->sb_vec;
 907         off = 0;
 908 
 909         while (len) {
 910                 if (off >= v->sv_len) {
 911                         off = 0;
 912                         v++;
 913                 }
 914 
 915                 if (v->sv_addr == 0 || v->sv_len == 0) {
 916 #ifdef DEBUG
 917                         cmn_err(CE_WARN,
 918                             "!rdc_write_bitmap_pattern: ran off end of handle");
 919 #endif
 920                         break;
 921                 }
 922 
 923                 iolen = (size_t)min(len, buffer_size);
 924 
 925                 bcopy(buffer, (char *)(v->sv_addr + off), iolen);
 926                 off += iolen;
 927                 len -= iolen;
 928         }
 929 
 930         rc = nsc_write(h, h->sb_pos, h->sb_len, 0);
 931         if (!RDC_SUCCESS(rc)) {
 932                 cmn_err(CE_WARN, "!rdc_write_bitmap_pattern: "
 933                     "%s write failed %d", urdc->primary.file, rc);
 934                 rdc_set_flags_log(urdc, RDC_BMP_FAILED, "write failed");
 935                 (void) nsc_free_buf(h);
 936                 _rdc_rlse_devs(krdc, RDC_BMP);
 937                 mutex_exit(&krdc->bmapmutex);
 938                 rc = -1;
 939                 goto finish;
 940         }
 941 
 942         (void) nsc_free_buf(h);
 943 
 944         fba_pos += fba_len;
 945         fba_req -= fba_len;
 946         tocopy -= FBA_SIZE(fba_len);    /* adjust byte length remaining */
 947         if (fba_req > 0)
 948                 goto loop;
 949 
 950         _rdc_rlse_devs(krdc, RDC_BMP);
 951         mutex_exit(&krdc->bmapmutex);
 952         rc = 0;
 953 finish:
 954         kmem_free(buffer, buffer_size);
 955         return (rc);
 956 }
 957 
 958 
 959 /*
 960  * rdc_write_bitmap_fill()
 961  *
 962  * Write a bitmap full of 1's out to disk without touching the
 963  * in-memory bitmap.
 964  */
 965 int
 966 rdc_write_bitmap_fill(rdc_k_info_t *krdc)
 967 {
 968         return (rdc_write_bitmap_pattern(krdc, 0xff));
 969 }
 970 
 971 
 972 void
 973 rdc_merge_bitmaps(rdc_k_info_t *src, rdc_k_info_t *dst)
 974 {
 975         if (src->dcio_bitmap == NULL || dst->dcio_bitmap == NULL)
 976                 return;
 977 
 978         rdc_lor(src->dcio_bitmap, dst->dcio_bitmap,
 979             min(src->bitmap_size, dst->bitmap_size));
 980         if (dst->bitmap_write > 0)
 981                 (void) rdc_write_bitmap(dst);
 982 }
 983 
 984 
 985 /*
 986  * bitmap size in bytes, vol_size fba's
 987  */
 988 
 989 size_t
 990 rdc_ref_size_possible(nsc_size_t bitmap_size, nsc_size_t vol_size)
 991 {
 992         nsc_size_t ref_size;
 993         nsc_size_t bitmap_end_fbas;
 994 
 995         bitmap_end_fbas = RDC_BITMAP_FBA + FBA_LEN(bitmap_size);
 996         ref_size = FBA_LEN(bitmap_size * BITS_IN_BYTE * sizeof (unsigned char));
 997         if (bitmap_end_fbas + ref_size > vol_size)
 998                 return ((size_t)0);
 999 
1000         ref_size = FBA_LEN(bitmap_size * BITS_IN_BYTE * sizeof (unsigned int));
1001         if (bitmap_end_fbas + ref_size > vol_size)
1002                 return (sizeof (unsigned char));
1003         return (sizeof (unsigned int));
1004 }
1005 
1006 int
1007 rdc_move_bitmap(rdc_k_info_t *krdc, char *newbitmap)
1008 {
1009         rdc_u_info_t *urdc;
1010         nsc_fd_t *oldfd;
1011         nsc_fd_t *newfd = NULL;
1012         rdc_header_t header;
1013         int sts;
1014         nsc_size_t vol_size;
1015         nsc_size_t req_size;
1016         size_t ref_size;
1017 
1018         if (krdc == NULL) {
1019                 return (-1);
1020         }
1021 
1022         if (krdc->bitmapfd == NULL) {
1023                 return (-1);
1024         }
1025 
1026         req_size = RDC_BITMAP_FBA + FBA_LEN(krdc->bitmap_size);
1027         if (RDC_IS_DISKQ(krdc->group)) {
1028                 /* new volume must support at least the old refcntsize */
1029                 req_size += FBA_LEN(krdc->bitmap_size * BITS_IN_BYTE *
1030                     rdc_refcntsize(krdc));
1031 #ifdef DEBUG_REFCNT
1032         cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
1033             (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
1034 #endif
1035         }
1036 
1037         mutex_enter(&krdc->bmapmutex);
1038 
1039         if (rdc_read_header(krdc, &header) < 0) {
1040 #ifdef DEBUG
1041                 cmn_err(CE_WARN, "!rdc_move_bitmap: Read old header failed");
1042 #endif
1043                 mutex_exit(&krdc->bmapmutex);
1044                 return (-1);
1045         }
1046 
1047         oldfd = krdc->bitmapfd;
1048 
1049         newfd = nsc_open(newbitmap, NSC_RDCHR_ID|NSC_FILE|NSC_RDWR, 0, 0, 0);
1050         if (newfd == NULL) {
1051                 newfd = nsc_open(newbitmap,
1052                     NSC_RDCHR_ID|NSC_CACHE|NSC_DEVICE|NSC_RDWR, 0, 0, 0);
1053                 if (newfd == NULL) {
1054                         /* Can't open new bitmap */
1055                         cmn_err(CE_WARN,
1056                             "!rdc_move_bitmap: Cannot open new bitmap %s",
1057                             newbitmap);
1058                         goto fail;
1059                 }
1060         }
1061 
1062         sts = nsc_reserve(newfd, 0);
1063         if (!RDC_SUCCESS(sts)) {
1064                 cmn_err(CE_WARN, "!rdc_move_bitmap: Reserve failed for %s",
1065                     newbitmap);
1066                 goto fail;
1067         }
1068         sts = nsc_partsize(newfd, &vol_size);
1069         nsc_release(newfd);
1070 
1071         if (!RDC_SUCCESS(sts)) {
1072                 cmn_err(CE_WARN,
1073                     "!rdc_move_bitmap: nsc_partsize failed for %s", newbitmap);
1074                 goto fail;
1075         }
1076 
1077         ref_size = rdc_ref_size_possible(krdc->bitmap_size, vol_size);
1078 
1079         if (vol_size < req_size) {
1080                 cmn_err(CE_WARN,
1081                     "!rdc_move_bitmap: bitmap %s too small: %" NSC_SZFMT
1082                     " vs %" NSC_SZFMT " blocks", newbitmap, vol_size, req_size);
1083                 goto fail;
1084         }
1085 
1086         mutex_enter(&krdc->devices->id_rlock);
1087         krdc->bitmapfd = newfd;                      /* swap under lock */
1088         if (krdc->bmaprsrv > 0) {
1089                 sts = nsc_reserve(krdc->bitmapfd, 0);
1090                 if (!RDC_SUCCESS(sts)) {
1091                         krdc->bitmapfd = oldfd;      /* replace under lock */
1092                         mutex_exit(&krdc->devices->id_rlock);
1093                         cmn_err(CE_WARN,
1094                             "!rdc_move_bitmap: Reserve failed for %s",
1095                             newbitmap);
1096                         goto fail;
1097                 }
1098         }
1099         rdc_set_refcnt_ops(krdc, ref_size);
1100 #ifdef DEBUG_REFCNT
1101         cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
1102             (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
1103 #endif
1104         mutex_exit(&krdc->devices->id_rlock);
1105 
1106         /* Forget newfd now it is krdc->bitmapfd */
1107         newfd = NULL;
1108 
1109         /* Put new bitmap name into header and user-visible data structure */
1110         urdc = &rdc_u_info[krdc->index];
1111         if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
1112                 (void) strncpy(header.primary.bitmap, newbitmap, NSC_MAXPATH);
1113                 (void) strncpy(urdc->primary.bitmap, newbitmap, NSC_MAXPATH);
1114         } else {
1115                 (void) strncpy(header.secondary.bitmap, newbitmap, NSC_MAXPATH);
1116                 (void) strncpy(urdc->secondary.bitmap, newbitmap, NSC_MAXPATH);
1117         }
1118 
1119         if (rdc_write_header(krdc, &header) < 0) {
1120                 cmn_err(CE_WARN,
1121                     "!rdc_move_bitmap: Write header %s failed", newbitmap);
1122                 goto fail;
1123         }
1124 
1125         mutex_exit(&krdc->bmapmutex);
1126 
1127         if (rdc_write_bitmap(krdc) < 0) {
1128                 mutex_enter(&krdc->bmapmutex);
1129                 cmn_err(CE_WARN,
1130                     "!rdc_move_bitmap: Write bitmap %s failed", newbitmap);
1131                 goto fail;
1132         }
1133 
1134         /* Unintercept the old bitmap */
1135         if (krdc->b_tok) {
1136                 int rc;
1137 
1138                 rdc_group_exit(krdc);
1139                 rc = nsc_unregister_path(krdc->b_tok, 0);
1140                 if (rc)
1141                         cmn_err(CE_WARN, "!rdc_move_bitmap: "
1142                             "unregister bitmap failed %d", rc);
1143                 else
1144                         krdc->b_tok = nsc_register_path(newbitmap,
1145                             NSC_CACHE | NSC_DEVICE, _rdc_io_hc);
1146                 rdc_group_enter(krdc);
1147         }
1148 
1149         /* clear the old bitmap header */
1150         bzero(&header, sizeof (header));
1151 
1152         sts = nsc_held(oldfd) ? 0 : nsc_reserve(oldfd, 0);
1153         if (sts == 0) {
1154 
1155                 if (krdc->bmp_kstats) {
1156                         mutex_enter(krdc->bmp_kstats->ks_lock);
1157                         kstat_runq_enter(KSTAT_IO_PTR(krdc->bmp_kstats));
1158                         mutex_exit(krdc->bmp_kstats->ks_lock);
1159                 }
1160 
1161                 sts = rdc_ns_io(oldfd, rdc_wrflag, 0,
1162                     (uchar_t *)&header, sizeof (header));
1163 
1164                 if (krdc->bmp_kstats) {
1165                         mutex_enter(krdc->bmp_kstats->ks_lock);
1166                         kstat_runq_exit(KSTAT_IO_PTR(krdc->bmp_kstats));
1167                         mutex_exit(krdc->bmp_kstats->ks_lock);
1168                         KSTAT_IO_PTR(krdc->bmp_kstats)->writes++;
1169                         KSTAT_IO_PTR(krdc->bmp_kstats)->nwritten +=
1170                             sizeof (header);
1171                 }
1172 
1173         }
1174 #ifdef DEBUG
1175         if (sts != 0) {
1176                 cmn_err(CE_WARN,
1177                     "!rdc_move_bitmap: unable to clear bitmap header on %s",
1178                     nsc_pathname(oldfd));
1179         }
1180 #endif
1181 
1182         /* nsc_close will undo any reservation */
1183         if (nsc_close(oldfd) != 0) {
1184 #ifdef DEBUG
1185                 cmn_err(CE_WARN, "!rdc_move_bitmap: close old bitmap failed");
1186 #else
1187                 ;
1188                 /*EMPTY*/
1189 #endif
1190         }
1191 
1192         return (0);
1193 
1194 fail:
1195         /* Close newfd if it was unused */
1196         if (newfd && newfd != krdc->bitmapfd) {
1197                 (void) nsc_close(newfd);
1198                 newfd = NULL;
1199         }
1200 
1201         mutex_exit(&krdc->bmapmutex);
1202         return (-1);
1203 }
1204 
1205 
1206 void
1207 rdc_close_bitmap(rdc_k_info_t *krdc)
1208 {
1209 
1210         if (krdc == NULL) {
1211                 return;
1212         }
1213 
1214         mutex_enter(&krdc->bmapmutex);
1215 
1216         if (krdc->bitmapfd) {
1217                 if (nsc_close(krdc->bitmapfd) != 0) {
1218 #ifdef DEBUG
1219                         cmn_err(CE_WARN, "!nsc_close on bitmap failed");
1220 #else
1221                         ;
1222                         /*EMPTY*/
1223 #endif
1224                 }
1225                 krdc->bitmapfd = 0;
1226         }
1227 
1228         mutex_exit(&krdc->bmapmutex);
1229 }
1230 
1231 void
1232 rdc_free_bitmap(rdc_k_info_t *krdc, int cmd)
1233 {
1234         rdc_header_t header;
1235         rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
1236 
1237         if (krdc == NULL) {
1238                 return;
1239         }
1240 
1241         mutex_enter(&krdc->bmapmutex);
1242 
1243         if (cmd != RDC_CMD_SUSPEND) {
1244 
1245                 bzero((char *)&header, sizeof (rdc_header_t));
1246 
1247                 if (krdc->bitmapfd)
1248                         (void) rdc_write_header(krdc, &header);
1249         } else {
1250                 mutex_exit(&krdc->bmapmutex);
1251                 /* gotta drop mutex, in case q needs to fail */
1252                 if (RDC_IS_DISKQ(krdc->group) && rdc_suspend_diskq(krdc) < 0) {
1253                         cmn_err(CE_WARN,
1254                             "!rdc_free_bitmap: diskq suspend failed");
1255                 }
1256 
1257                 mutex_enter(&krdc->bmapmutex);
1258                 if (rdc_read_header(krdc, &header) < 0) {
1259                         cmn_err(CE_WARN,
1260                             "!rdc_free_bitmap: Read header failed");
1261                 } else {
1262                         rdc_fill_header(urdc, &header);
1263 
1264                         (void) rdc_write_header(krdc, &header);
1265                 }
1266         }
1267 
1268         mutex_exit(&krdc->bmapmutex);
1269 
1270         if (krdc->dcio_bitmap != NULL) {
1271                 if (cmd == RDC_CMD_SUSPEND) {
1272                         if (krdc->bitmapfd)
1273                                 (void) rdc_write_bitmap(krdc);
1274                 }
1275 
1276                 kmem_free(krdc->dcio_bitmap, krdc->bitmap_size);
1277                 krdc->dcio_bitmap = NULL;
1278         }
1279         if (krdc->bitmap_ref != NULL) {
1280                 kmem_free(krdc->bitmap_ref, (krdc->bitmap_size * BITS_IN_BYTE *
1281                     BMAP_REF_PREF_SIZE));
1282                 krdc->bitmap_ref = NULL;
1283         }
1284 
1285         krdc->bitmap_size = 0;
1286 }
1287 
1288 static int
1289 rdc_alloc_bitmap(rdc_k_info_t *krdc)
1290 {
1291         rdc_u_info_t *urdc;
1292         char *bitmapname;
1293         nsc_size_t bitmap_ref_size;
1294 
1295         if (krdc == NULL) {
1296                 return (-1);
1297         }
1298 
1299         urdc = &rdc_u_info[krdc->index];
1300         if (rdc_get_vflags(urdc) & RDC_PRIMARY)
1301                 bitmapname = &urdc->primary.bitmap[0];
1302         else
1303                 bitmapname = &urdc->secondary.bitmap[0];
1304 
1305         if (krdc->dcio_bitmap) {
1306 #ifdef DEBUG
1307                 cmn_err(CE_WARN,
1308                     "!rdc_alloc_bitmap: bitmap %s already allocated",
1309                     bitmapname);
1310 #endif
1311                 return (0);
1312         }
1313 
1314         if (urdc->volume_size == 0)
1315                 return (-1);
1316 
1317         krdc->bitmap_size = BMAP_LOG_BYTES(urdc->volume_size);
1318         /* Round up */
1319         krdc->bitmap_size = (krdc->bitmap_size + 511) / 512 * 512;
1320 
1321         krdc->dcio_bitmap = (uchar_t *)kmem_zalloc(krdc->bitmap_size,
1322             KM_SLEEP);
1323         if (krdc->dcio_bitmap == NULL) {
1324                 cmn_err(CE_WARN, "!rdc_alloc_bitmap: alloc %" NSC_SZFMT
1325                     " failed for %s", krdc->bitmap_size, bitmapname);
1326                 return (-1);
1327         }
1328 
1329         /*
1330          * use largest ref count type size as we haven't opened the bitmap
1331          * volume yet to find out what has acutally be used.
1332          */
1333         bitmap_ref_size = krdc->bitmap_size * BITS_IN_BYTE * BMAP_REF_PREF_SIZE;
1334         if ((rdc_get_vflags(urdc) & RDC_PRIMARY) &&
1335             ((krdc->type_flag & RDC_ASYNCMODE) != 0)) {
1336                 krdc->bitmap_ref = (uchar_t *)kmem_zalloc(bitmap_ref_size,
1337                     KM_SLEEP);
1338                 if (krdc->bitmap_ref == NULL) {
1339                         cmn_err(CE_WARN,
1340                             "!rdc_alloc_bitmap: ref alloc %" NSC_SZFMT
1341                             " failed for %s",
1342                             bitmap_ref_size, bitmapname);
1343                         return (-1);
1344                 }
1345         }
1346 
1347         return (0);
1348 }
1349 
1350 
1351 static int
1352 rdc_open_bitmap(rdc_k_info_t *krdc)
1353 {
1354         rdc_u_info_t *urdc;
1355         int sts;
1356         uint_t hints = 0;
1357         nsc_size_t vol_size;
1358         char *bitmapname;
1359         nsc_size_t req_size;
1360         nsc_size_t bit_size;
1361 
1362         urdc = &rdc_u_info[krdc->index];
1363         if (rdc_get_vflags(urdc) & RDC_PRIMARY)
1364                 bitmapname = &urdc->primary.bitmap[0];
1365         else
1366                 bitmapname = &urdc->secondary.bitmap[0];
1367 
1368         urdc->bits_set = 0;
1369 
1370         bit_size = req_size = RDC_BITMAP_FBA + FBA_LEN(krdc->bitmap_size);
1371         if (RDC_IS_DISKQ(krdc->group)) {
1372                 req_size += FBA_LEN(krdc->bitmap_size * BITS_IN_BYTE *
1373                     sizeof (unsigned char));
1374         }
1375 
1376         mutex_enter(&krdc->bmapmutex);
1377 
1378         rdc_set_refcnt_ops(krdc, sizeof (unsigned char));
1379 #ifdef DEBUG_REFCNT
1380         cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
1381             (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
1382 #endif
1383         if (krdc->bitmapfd == NULL)
1384                 krdc->bitmapfd = nsc_open(bitmapname,
1385                     NSC_RDCHR_ID|NSC_FILE|NSC_RDWR, 0, 0, 0);
1386         if (krdc->bitmapfd == NULL) {
1387                 krdc->bitmapfd = nsc_open(bitmapname,
1388                     NSC_RDCHR_ID|NSC_CACHE|NSC_DEVICE|NSC_RDWR, 0, 0, 0);
1389                 if (krdc->bitmapfd == NULL) {
1390                         cmn_err(CE_WARN, "!rdc_open_bitmap: Unable to open %s",
1391                             bitmapname);
1392                         goto fail;
1393                 }
1394         }
1395 
1396         sts = _rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL);
1397         if (!RDC_SUCCESS(sts)) {
1398                 cmn_err(CE_WARN, "!rdc_open_bitmap: Reserve failed for %s",
1399                     bitmapname);
1400                 goto fail;
1401         }
1402         sts = nsc_partsize(krdc->bitmapfd, &vol_size);
1403         _rdc_rlse_devs(krdc, RDC_BMP);
1404 
1405         if (!RDC_SUCCESS(sts)) {
1406                 cmn_err(CE_WARN,
1407                     "!rdc_open_bitmap: nsc_partsize failed for %s", bitmapname);
1408                 goto fail;
1409         }
1410 
1411         if (vol_size < req_size) {
1412                 /* minimum size supports unsigned char reference counts */
1413                 cmn_err(CE_WARN,
1414                     "!rdc_open_bitmap: bitmap %s too small: %" NSC_SZFMT " vs %"
1415                     NSC_SZFMT "blocks",
1416                     bitmapname, vol_size, req_size);
1417                 goto fail;
1418         }
1419 
1420         if (rdc_bitmap_mode == RDC_BMP_NEVER) {
1421                 krdc->bitmap_write = 0;              /* forced off */
1422         } else if (rdc_bitmap_mode == RDC_BMP_ALWAYS ||
1423             (nsc_node_hints(&hints) == 0 && (hints & NSC_FORCED_WRTHRU) == 0)) {
1424                 krdc->bitmap_write = 1;              /* forced or autodetect on */
1425         } else {
1426                 /* autodetect off */
1427                 krdc->bitmap_write = 0;
1428         }
1429 
1430         mutex_exit(&krdc->bmapmutex);
1431         if (RDC_IS_DISKQ(krdc->group) && (rdc_refcntsize(krdc) <
1432             BMAP_REF_PREF_SIZE)) {
1433                 /* test for larger ref counts */
1434 #ifdef DEBUG_REFCNT
1435         cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
1436             (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
1437 #endif
1438                 req_size = bit_size;
1439                 req_size += FBA_LEN(krdc->bitmap_size * BITS_IN_BYTE *
1440                     sizeof (unsigned int));
1441                 if (vol_size >= req_size)
1442                         rdc_set_refcnt_ops(krdc, sizeof (unsigned int));
1443         }
1444 #ifdef DEBUG_REFCNT
1445         cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
1446             (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
1447 #endif
1448         return (0);
1449 
1450 fail:
1451         mutex_exit(&krdc->bmapmutex);
1452         return (-1);
1453 }
1454 
1455 int
1456 rdc_enable_bitmap(rdc_k_info_t *krdc, int set)
1457 {
1458         rdc_header_t header;
1459         rdc_u_info_t *urdc;
1460         char *bitmapname;
1461 
1462         urdc = &rdc_u_info[krdc->index];
1463 
1464         if (rdc_alloc_bitmap(krdc) < 0)
1465                 goto fail;
1466 
1467         if (rdc_open_bitmap(krdc) < 0)
1468                 goto fail;
1469 
1470         if (rdc_get_vflags(urdc) & RDC_PRIMARY)
1471                 bitmapname = &urdc->primary.bitmap[0];
1472         else
1473                 bitmapname = &urdc->secondary.bitmap[0];
1474 
1475         mutex_enter(&krdc->bmapmutex);
1476 
1477         rdc_clr_flags(urdc, RDC_BMP_FAILED);
1478         if (rdc_read_header(krdc, &header) < 0) {
1479                 cmn_err(CE_WARN,
1480                     "!rdc_enable_bitmap: Read header %s failed", bitmapname);
1481                 mutex_exit(&krdc->bmapmutex);
1482                 goto fail;
1483         }
1484 
1485         rdc_fill_header(urdc, &header);
1486         rdc_set_refcnt_ops(krdc, (size_t)header.refcntsize);
1487 
1488         if (set)
1489                 (void) RDC_FILL_BITMAP(krdc, FALSE);
1490 
1491         if (rdc_write_header(krdc, &header) < 0) {
1492                 cmn_err(CE_WARN,
1493                     "!rdc_enable_bitmap: Write header %s failed",
1494                     bitmapname);
1495                 mutex_exit(&krdc->bmapmutex);
1496                 goto fail;
1497         }
1498         mutex_exit(&krdc->bmapmutex);
1499 
1500         if (rdc_write_bitmap(krdc) < 0) {
1501                 cmn_err(CE_WARN,
1502                     "!rdc_enable_bitmap: Write bitmap %s failed",
1503                     bitmapname);
1504                 goto fail;
1505         }
1506 
1507         return (0);
1508 
1509 fail:
1510         rdc_free_bitmap(krdc, RDC_CMD_ENABLE);
1511         rdc_close_bitmap(krdc);
1512 
1513         mutex_enter(&krdc->bmapmutex);
1514         rdc_set_flags_log(urdc, RDC_BMP_FAILED, "I/O failed");
1515         mutex_exit(&krdc->bmapmutex);
1516         return (-1);
1517 }
1518 
1519 static int
1520 _rdc_rdwr_refcnt(rdc_k_info_t *krdc, int rwflg)
1521 {
1522         rdc_u_info_t *urdc;
1523         int rc;
1524         nsc_off_t offset;
1525         nsc_size_t len;
1526 
1527         urdc = &rdc_u_info[krdc->index];
1528 
1529 #ifdef DEBUG_REFCNT
1530         cmn_err(CE_NOTE, "!rdc_rdwr_refcnt: %s refcount for %s",
1531             (rwflg == NSC_READ) ? "resuming" : "writing",
1532             urdc->primary.bitmap);
1533 #endif
1534         ASSERT(MUTEX_HELD(QLOCK((&krdc->group->diskq))));
1535         mutex_enter(&krdc->bmapmutex);
1536 
1537         if (_rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL)) {
1538                 cmn_err(CE_WARN, "!rdc_rdwr_refcnt: reserve failed");
1539                 goto fail;
1540         }
1541 
1542         if (krdc->bitmap_size == 0) {
1543                 cmn_err(CE_WARN, "!rdc_rdwr_refcnt: NULL bitmap!");
1544                 goto fail;
1545         }
1546 
1547         offset = RDC_BITREF_FBA(krdc);
1548         len = krdc->bitmap_size * BITS_IN_BYTE * rdc_refcntsize(krdc);
1549 
1550         rc = rdc_ns_io(krdc->bitmapfd, rwflg, offset,
1551             (uchar_t *)krdc->bitmap_ref, len);
1552 
1553         if (!RDC_SUCCESS(rc)) {
1554                 cmn_err(CE_WARN, "!unable to %s refcount from bitmap %s",
1555                     (rwflg == NSC_READ) ? "retrieve" : "write",
1556                     urdc->primary.bitmap);
1557                 rdc_set_flags_log(urdc, RDC_BMP_FAILED, "refcount I/O failed");
1558                 goto fail;
1559         }
1560 
1561         _rdc_rlse_devs(krdc, RDC_BMP);
1562 
1563         mutex_exit(&krdc->bmapmutex);
1564 
1565 #ifdef DEBUG_REFCNT
1566         cmn_err(CE_NOTE, "!rdc_rdwr_refcnt: %s refcount for %s",
1567             (rwflg == NSC_READ) ? "resumed" : "wrote",
1568             urdc->primary.bitmap);
1569 #endif
1570         return (0);
1571 
1572         fail:
1573         _rdc_rlse_devs(krdc, RDC_BMP);
1574 
1575         mutex_exit(&krdc->bmapmutex);
1576 
1577         return (-1);
1578 
1579 }
1580 
1581 /*
1582  * rdc_read_refcount
1583  * read the stored refcount from disk
1584  * queue lock is held
1585  */
1586 int
1587 rdc_read_refcount(rdc_k_info_t *krdc)
1588 {
1589         int     rc;
1590 
1591         rc = _rdc_rdwr_refcnt(krdc, NSC_READ);
1592 
1593         return (rc);
1594 }
1595 
1596 /*
1597  * rdc_write_refcount
1598  * writes krdc->bitmap_ref to the diskq
1599  * called with qlock held
1600  */
1601 int
1602 rdc_write_refcount(rdc_k_info_t *krdc)
1603 {
1604         int     rc;
1605 
1606         rc = _rdc_rdwr_refcnt(krdc, NSC_WRBUF);
1607 
1608         return (rc);
1609 }
1610 
1611 static int
1612 rdc_resume_state(rdc_k_info_t *krdc, const rdc_header_t *header)
1613 {
1614         rdc_u_info_t *urdc;
1615         char *bitmapname;
1616 
1617         urdc = &rdc_u_info[krdc->index];
1618         if (rdc_get_vflags(urdc) & RDC_PRIMARY)
1619                 bitmapname = &urdc->primary.bitmap[0];
1620         else
1621                 bitmapname = &urdc->secondary.bitmap[0];
1622 
1623         if (header->magic != RDC_HDR_MAGIC) {
1624                 cmn_err(CE_WARN, "!rdc_resume_state: Bad magic in %s",
1625                     bitmapname);
1626                 return (-1);
1627         }
1628 
1629         if (strncmp(urdc->primary.file, header->primary.file,
1630             NSC_MAXPATH) != 0) {
1631 #ifdef DEBUG
1632                 cmn_err(CE_WARN,
1633                     "!rdc_resume_state: Found %s Expected %s",
1634                     header->primary.file, urdc->primary.file);
1635 #endif /* DEBUG */
1636                 return (-1);
1637         }
1638 
1639         if (strncmp(urdc->secondary.file, header->secondary.file,
1640             NSC_MAXPATH) != 0) {
1641 #ifdef DEBUG
1642                 cmn_err(CE_WARN,
1643                     "!rdc_resume_state: Found %s Expected %s",
1644                     header->secondary.file, urdc->secondary.file);
1645 #endif /* DEBUG */
1646                 return (-1);
1647         }
1648 
1649         if (strncmp(urdc->primary.bitmap, header->primary.bitmap,
1650             NSC_MAXPATH) != 0) {
1651 #ifdef DEBUG
1652                 cmn_err(CE_WARN,
1653                     "!rdc_resume_state: Found %s Expected %s",
1654                     header->primary.bitmap, urdc->primary.bitmap);
1655 #endif /* DEBUG */
1656                 return (-1);
1657         }
1658 
1659         if (strncmp(urdc->secondary.bitmap, header->secondary.bitmap,
1660             NSC_MAXPATH) != 0) {
1661 #ifdef DEBUG
1662                 cmn_err(CE_WARN,
1663                     "!rdc_resume_state: Found %s Expected %s",
1664                     header->secondary.bitmap, urdc->secondary.bitmap);
1665 #endif /* DEBUG */
1666                 return (-1);
1667         }
1668 
1669         if (header->maxqfbas)
1670                 urdc->maxqfbas = header->maxqfbas;
1671 
1672         if (header->maxqitems)
1673                 urdc->maxqitems = header->maxqitems;
1674 
1675         if (header->autosync >= 0)
1676                 urdc->autosync = header->autosync;
1677 
1678         if (header->asyncthr)
1679                 urdc->asyncthr = header->asyncthr;
1680 
1681         rdc_many_enter(krdc);
1682         rdc_set_refcnt_ops(krdc, header->refcntsize);
1683 #ifdef DEBUG_REFCNT
1684         cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
1685             (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
1686 #endif
1687         if (header->flags & RDC_VOL_FAILED)
1688                 rdc_set_flags(urdc, RDC_VOL_FAILED);
1689         if (header->flags & RDC_QUEUING)
1690                 rdc_set_flags(urdc, RDC_QUEUING);
1691 
1692         rdc_clr_flags(urdc, RDC_SYNC_NEEDED | RDC_RSYNC_NEEDED);
1693         rdc_set_mflags(urdc, (header->flags & RDC_RSYNC_NEEDED));
1694         rdc_set_flags(urdc, (header->flags & RDC_SYNC_NEEDED));
1695         rdc_many_exit(krdc);
1696 
1697         if (urdc->flags & RDC_VOL_FAILED) {
1698 
1699                 /* Our disk was failed so set all the bits in the bitmap */
1700 
1701                 if (RDC_FILL_BITMAP(krdc, TRUE) != 0) {
1702                         cmn_err(CE_WARN,
1703                             "!rdc_resume_state: Fill bitmap %s failed",
1704                             bitmapname);
1705                         return (-1);
1706                 }
1707                 rdc_many_enter(krdc);
1708                 if (IS_STATE(urdc, RDC_QUEUING))
1709                         rdc_clr_flags(urdc, RDC_QUEUING);
1710                 rdc_many_exit(krdc);
1711         } else {
1712                 /* Header was good, so read in the bitmap */
1713 
1714                 if (rdc_read_bitmap(krdc, NULL) < 0) {
1715                         cmn_err(CE_WARN,
1716                             "!rdc_resume_state: Read bitmap %s failed",
1717                             bitmapname);
1718                         return (-1);
1719                 }
1720 
1721                 urdc->bits_set = RDC_COUNT_BITMAP(krdc);
1722 
1723                 /*
1724                  * Check if another node went down with bits set, but
1725                  * without setting logging mode.
1726                  */
1727                 if (urdc->bits_set != 0 &&
1728                     (rdc_get_vflags(urdc) & RDC_ENABLED) &&
1729                     !(rdc_get_vflags(urdc) & RDC_LOGGING)) {
1730                         rdc_group_log(krdc, RDC_NOFLUSH | RDC_NOREMOTE, NULL);
1731                 }
1732         }
1733 
1734         /* if we are using a disk queue, read in the reference count bits */
1735         if (RDC_IS_DISKQ(krdc->group)) {
1736                 disk_queue *q = &krdc->group->diskq;
1737                 mutex_enter(QLOCK(q));
1738                 if ((rdc_read_refcount(krdc) < 0)) {
1739                         cmn_err(CE_WARN,
1740                             "!rdc_resume_state: Resume bitmap %s's refcount"
1741                             "failed",
1742                             urdc->primary.bitmap);
1743                         mutex_exit(QLOCK(q));
1744                         rdc_many_enter(krdc);
1745                         if (IS_STATE(urdc, RDC_QUEUING))
1746                                 rdc_clr_flags(urdc, RDC_QUEUING);
1747                         rdc_many_exit(krdc);
1748                         return (-1);
1749                 }
1750                 mutex_exit(QLOCK(q));
1751         }
1752 
1753         return (0);
1754 }
1755 
1756 
1757 int
1758 rdc_resume_bitmap(rdc_k_info_t *krdc)
1759 {
1760         rdc_header_t header;
1761         rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
1762         char *bitmapname;
1763 
1764         if (rdc_alloc_bitmap(krdc) < 0)
1765                 goto allocfail;
1766 
1767         if (rdc_open_bitmap(krdc) < 0)
1768                 goto fail;
1769 
1770         if (rdc_get_vflags(urdc) & RDC_PRIMARY)
1771                 bitmapname = &urdc->primary.bitmap[0];
1772         else
1773                 bitmapname = &urdc->secondary.bitmap[0];
1774 
1775         mutex_enter(&krdc->bmapmutex);
1776 
1777         rdc_clr_flags(urdc, RDC_BMP_FAILED);
1778         if (rdc_read_header(krdc, &header) < 0) {
1779                 cmn_err(CE_WARN,
1780                     "!rdc_resume_bitmap: Read header %s failed", bitmapname);
1781                 mutex_exit(&krdc->bmapmutex);
1782                 goto fail;
1783         }
1784 
1785         mutex_exit(&krdc->bmapmutex);
1786 
1787         /* Resuming from the bitmap, so do some checking */
1788 
1789         /*CONSTCOND*/
1790         ASSERT(FBA_LEN(sizeof (rdc_header_t)) <= RDC_BITMAP_FBA);
1791         /*CONSTCOND*/
1792         ASSERT(sizeof (rdc_header_t) >= sizeof (rdc_headerv2_t));
1793 
1794         if (header.magic == RDC_HDR_V2) {
1795                 rdc_headerv2_t *hdr_v2 = (rdc_headerv2_t *)&header;
1796                 rdc_header_t new_header;
1797 
1798 #ifdef DEBUG
1799                 cmn_err(CE_WARN,
1800                     "!rdc_resume_bitmap: Converting v2 header for bitmap %s",
1801                     bitmapname);
1802 #endif
1803                 bzero((char *)&new_header, sizeof (rdc_header_t));
1804 
1805                 new_header.autosync = -1;
1806                 new_header.magic = RDC_HDR_MAGIC;
1807                 new_header.syshostid = urdc->syshostid;
1808 
1809                 if (hdr_v2->volume_failed)
1810                         new_header.flags |= RDC_VOL_FAILED;
1811                 if (hdr_v2->sync_needed == RDC_SYNC)
1812                         new_header.flags |= RDC_SYNC_NEEDED;
1813                 if (hdr_v2->sync_needed == RDC_FULL_SYNC)
1814                         new_header.flags |= RDC_SYNC_NEEDED;
1815                 if (hdr_v2->sync_needed == RDC_REV_SYNC)
1816                         new_header.flags |= RDC_RSYNC_NEEDED;
1817                 if (rdc_get_vflags(urdc) & RDC_PRIMARY) {
1818                         (void) strncpy(new_header.primary.file,
1819                             hdr_v2->filename, NSC_MAXPATH);
1820                         (void) strncpy(new_header.primary.bitmap,
1821                             hdr_v2->bitmapname, NSC_MAXPATH);
1822                         (void) strncpy(new_header.secondary.file,
1823                             urdc->secondary.file, NSC_MAXPATH);
1824                         (void) strncpy(new_header.secondary.bitmap,
1825                             urdc->secondary.bitmap, NSC_MAXPATH);
1826                 } else {
1827                         (void) strncpy(new_header.secondary.file,
1828                             hdr_v2->filename, NSC_MAXPATH);
1829                         (void) strncpy(new_header.secondary.bitmap,
1830                             hdr_v2->bitmapname, NSC_MAXPATH);
1831                         (void) strncpy(new_header.primary.file,
1832                             urdc->primary.file, NSC_MAXPATH);
1833                         (void) strncpy(new_header.primary.bitmap,
1834                             urdc->primary.bitmap, NSC_MAXPATH);
1835                 }
1836 
1837                 bcopy(&new_header, &header, sizeof (rdc_header_t));
1838 
1839                 mutex_enter(&krdc->bmapmutex);
1840                 if (rdc_write_header(krdc, &header) < 0) {
1841                         mutex_exit(&krdc->bmapmutex);
1842                         cmn_err(CE_WARN,
1843                             "!rdc_resume_bitmap: Write header %s failed",
1844                             bitmapname);
1845                         goto fail;
1846                 }
1847                 mutex_exit(&krdc->bmapmutex);
1848 
1849         } else if (header.magic == RDC_HDR_V3) {
1850                 /*
1851                  * just update asyncthr and magic, and then we're done
1852                  */
1853                 header.magic = RDC_HDR_MAGIC;
1854                 header.asyncthr = RDC_ASYNCTHR;
1855                 mutex_enter(&krdc->bmapmutex);
1856                 if (rdc_write_header(krdc, &header) < 0) {
1857                         mutex_exit(&krdc->bmapmutex);
1858                         cmn_err(CE_WARN,
1859                             "!rdc_resume_bitmap: Write header %s failed",
1860                             bitmapname);
1861                         goto fail;
1862                 }
1863                 mutex_exit(&krdc->bmapmutex);
1864         }
1865 
1866         if (rdc_resume_state(krdc, &header) == 0)
1867                 return (0);
1868 
1869         rdc_close_bitmap(krdc);
1870 
1871 fail:
1872         (void) RDC_FILL_BITMAP(krdc, FALSE);
1873         rdc_clr_flags(urdc, RDC_QUEUING);
1874         if (krdc->bitmap_ref)
1875                 bzero(krdc->bitmap_ref, krdc->bitmap_size * BITS_IN_BYTE *
1876                     rdc_refcntsize(krdc));
1877 
1878 allocfail:
1879         mutex_enter(&krdc->bmapmutex);
1880         rdc_set_flags_log(urdc, RDC_BMP_FAILED, "resume bitmap failed");
1881         mutex_exit(&krdc->bmapmutex);
1882 
1883         return (-1);
1884 }
1885 
1886 void
1887 rdc_std_zero_bitref(rdc_k_info_t *krdc)
1888 {
1889         nsc_size_t vol_size;
1890         int sts;
1891         size_t newrefcntsize;
1892 
1893         if (krdc->bitmap_ref) {
1894                 mutex_enter(&krdc->bmapmutex);
1895                 bzero(krdc->bitmap_ref, krdc->bitmap_size * BITS_IN_BYTE *
1896                     BMAP_REF_PREF_SIZE);
1897                 if (RDC_IS_DISKQ(krdc->group) && rdc_refcntsize(krdc) !=
1898                     BMAP_REF_PREF_SIZE) {
1899                         /* see if we can upgrade the size of the ref counters */
1900                         sts = _rdc_rsrv_devs(krdc, RDC_BMP, RDC_INTERNAL);
1901                         if (!RDC_SUCCESS(sts)) {
1902                                 goto nochange;
1903                         }
1904                         sts = nsc_partsize(krdc->bitmapfd, &vol_size);
1905 
1906                         newrefcntsize = rdc_ref_size_possible(krdc->bitmap_size,
1907                             vol_size);
1908                         if (newrefcntsize > rdc_refcntsize(krdc)) {
1909                                 rdc_set_refcnt_ops(krdc, newrefcntsize);
1910 #ifdef DEBUG_REFCNT
1911         cmn_err(CE_NOTE, "!sndr: refcntsize %d - %d:%s",
1912             (int)rdc_refcntsize(krdc), __LINE__, __FILE__);
1913 #endif
1914                         }
1915 nochange:
1916                         _rdc_rlse_devs(krdc, RDC_BMP);
1917                 }
1918                 mutex_exit(&krdc->bmapmutex);
1919         }
1920 }
1921 
1922 int
1923 rdc_reset_bitmap(rdc_k_info_t *krdc)
1924 {
1925         rdc_u_info_t *urdc;
1926         rdc_header_t header;
1927         char *bitmapname;
1928 
1929         urdc = &rdc_u_info[krdc->index];
1930         if (rdc_get_vflags(urdc) & RDC_PRIMARY)
1931                 bitmapname = &urdc->primary.bitmap[0];
1932         else
1933                 bitmapname = &urdc->secondary.bitmap[0];
1934 
1935         mutex_enter(&krdc->bmapmutex);
1936 
1937         rdc_clr_flags(urdc, RDC_BMP_FAILED);
1938         if (rdc_read_header(krdc, &header) < 0) {
1939                 cmn_err(CE_WARN,
1940                     "!rdc_reset_bitmap: Read header %s failed", bitmapname);
1941                 goto fail_with_mutex;
1942         }
1943 
1944         rdc_fill_header(urdc, &header);
1945 
1946         if (rdc_write_header(krdc, &header) < 0) {
1947                 cmn_err(CE_WARN,
1948                     "!rdc_reset_bitmap: Write header %s failed",
1949                     bitmapname);
1950                 goto fail_with_mutex;
1951         }
1952         mutex_exit(&krdc->bmapmutex);
1953 
1954         if (krdc->bitmap_write == -1)
1955                 krdc->bitmap_write = 0;
1956 
1957         if (krdc->bitmap_write == 0) {
1958                 if (rdc_write_bitmap_fill(krdc) < 0) {
1959                         cmn_err(CE_WARN,
1960                             "!rdc_reset_bitmap: Write bitmap %s failed",
1961                             bitmapname);
1962                         goto fail;
1963                 }
1964                 krdc->bitmap_write = -1;
1965         } else if (rdc_write_bitmap(krdc) < 0) {
1966                 cmn_err(CE_WARN,
1967                     "!rdc_reset_bitmap: Write bitmap %s failed",
1968                     bitmapname);
1969                 goto fail;
1970         }
1971 
1972         return (0);
1973 
1974 fail:
1975         mutex_enter(&krdc->bmapmutex);
1976 fail_with_mutex:
1977         rdc_set_flags_log(urdc, RDC_BMP_FAILED, "reset failed");
1978         mutex_exit(&krdc->bmapmutex);
1979 #ifdef DEBUG
1980         cmn_err(CE_NOTE, "!SNDR: unable to reset bitmap for %s:%s",
1981             urdc->secondary.intf, urdc->secondary.file);
1982 #endif
1983         return (-1);
1984 }
1985 
1986 
1987 /*
1988  * General bitmap operations
1989  */
1990 
1991 /*
1992  * rdc_set_bitmap_many()
1993  *
1994  * Used during reverse syncs to a 1-to-many primary to keep the 'many'
1995  * bitmaps up to date.
1996  */
1997 void
1998 rdc_set_bitmap_many(rdc_k_info_t *krdc, nsc_off_t pos, nsc_size_t len)
1999 {
2000         uint_t dummy;
2001 
2002 #ifdef DEBUG
2003         rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
2004         if (!(rdc_get_vflags(urdc) & RDC_PRIMARY)) {
2005                 cmn_err(CE_PANIC, "rdc_set_bitmap_many: not primary, urdc %p",
2006                     (void *) urdc);
2007         }
2008 #endif
2009 
2010         if (IS_MANY(krdc)) {
2011                 rdc_k_info_t *krd;
2012                 rdc_u_info_t *urd;
2013 
2014                 rdc_many_enter(krdc);
2015 
2016                 for (krd = krdc->many_next; krd != krdc; krd = krd->many_next) {
2017                         urd = &rdc_u_info[krd->index];
2018                         if (!IS_ENABLED(urd))
2019                                 continue;
2020                         ASSERT(urd->flags & RDC_PRIMARY);
2021                         (void) RDC_SET_BITMAP(krd, pos, len, &dummy);
2022                 }
2023 
2024                 rdc_many_exit(krdc);
2025         }
2026 }
2027 
2028 
2029 static int
2030 _rdc_net_bmap(const struct bmap6 *b6, net_bdata6 *bd6)
2031 {
2032         rdc_k_info_t *krdc = &rdc_k_info[b6->cd];
2033         struct timeval t;
2034         int e, ret;
2035         uint64_t left;
2036         uint64_t bmap_blksize;
2037 
2038         bmap_blksize = krdc->rpc_version < RDC_VERSION7 ?
2039             BMAP_BLKSIZE : BMAP_BLKSIZEV7;
2040 
2041         t.tv_sec = rdc_rpc_tmout;
2042         t.tv_usec = 0;
2043 
2044         if (bd6->data.data_val == NULL) {
2045                 return (EINVAL);
2046         }
2047 
2048         left = b6->size;
2049         bd6->endoblk = 0;
2050         while (left) {
2051                 if (left >= bmap_blksize)
2052                         bd6->size = (int)bmap_blksize;
2053                 else
2054                         bd6->size = (int)left;
2055 
2056                 bd6->data.data_len = bd6->size;
2057 
2058                 if ((uint64_t)bd6->size > left) {
2059                         left = 0;
2060                 } else {
2061                         left -= bd6->size;
2062                 }
2063                 /*
2064                  * mark the last block sent.
2065                  */
2066                 if (left == 0) {
2067                         bd6->endoblk = 1;
2068                 }
2069                 ASSERT(krdc->rpc_version);
2070                 if (krdc->rpc_version <= RDC_VERSION5) {
2071                         struct net_bdata bd;
2072                         bd.cd = bd6->cd;
2073                         bd.offset = bd6->offset;
2074                         bd.size = bd6->size;
2075                         bd.data.data_len = bd6->data.data_len;
2076                         bd.data.data_val = bd6->data.data_val;
2077                         e = rdc_clnt_call(krdc->lsrv, RDCPROC_BDATA,
2078                             krdc->rpc_version, xdr_net_bdata, (char *)&bd,
2079                             xdr_int, (char *)&ret, &t);
2080                 } else {
2081                         e = rdc_clnt_call(krdc->lsrv, RDCPROC_BDATA6,
2082                             krdc->rpc_version, xdr_net_bdata6, (char *)bd6,
2083                             xdr_int, (char *)&ret, &t);
2084                 }
2085                 if (e || ret) {
2086                         if (e)
2087                                 ret = e;
2088                         return (ret);
2089                 }
2090                 bd6->offset += bmap_blksize;
2091                 bd6->data.data_val += bmap_blksize;
2092         }
2093         return (0);
2094 }
2095 
2096 
2097 /*
2098  * Standard bitmap operations (combined kmem/disk bitmaps).
2099  */
2100 
2101 /*
2102  * rdc_std_set_bitmask(pos, len, &bitmask)
2103  * set a bitmask for this range. used to clear the correct
2104  * bits after flushing
2105  */
2106 static void
2107 rdc_std_set_bitmask(const nsc_off_t fba_pos, const nsc_size_t fba_len,
2108     uint_t *bitmask)
2109 {
2110         int first, st, en;
2111         if (bitmask)
2112                 *bitmask = 0;
2113         else
2114                 return;
2115 
2116         first = st = FBA_TO_LOG_NUM(fba_pos);
2117         en = FBA_TO_LOG_NUM(fba_pos + fba_len - 1);
2118         while (st <= en) {
2119                 BMAP_BIT_SET((uchar_t *)bitmask, st - first);
2120                 st++;
2121         }
2122 
2123 }
2124 /*
2125  * rdc_std_set_bitmap(krdc, fba_pos, fba_len, &bitmask)
2126  *
2127  * Mark modified segments in the dual copy file bitmap
2128  * to provide fast recovery
2129  * Note that bitmask allows for 32 segments, which at 32k per segment equals
2130  * 1 megabyte. If we ever allow more than this to be transferred in one
2131  * operation, or decrease the segment size, then this code will have to be
2132  * changed accordingly.
2133  */
2134 
2135 static int
2136 rdc_std_set_bitmap(rdc_k_info_t *krdc, const nsc_off_t fba_pos,
2137     const nsc_size_t fba_len, uint_t *bitmask)
2138 {
2139         int first, st, en;
2140         int fbaset = 0;
2141         nsc_off_t fba = 0;
2142         int printerr = 10;
2143         int tries = RDC_FUTILE_ATTEMPTS;
2144         int queuing = RDC_QUEUING;
2145         rdc_u_info_t *urdc;
2146 
2147         if (bitmask)
2148                 *bitmask = 0;
2149         else
2150                 return (-1);
2151 
2152         urdc = &rdc_u_info[krdc->index];
2153         if (rdc_get_vflags(urdc) & RDC_BMP_FAILED)
2154                 return (-1);
2155 
2156         if (krdc->bitmap_write == 0) {
2157                 if (rdc_write_bitmap_fill(krdc) < 0)
2158                         return (-1);
2159                 krdc->bitmap_write = -1;
2160         }
2161         first = st = FBA_TO_LOG_NUM(fba_pos);
2162         en = FBA_TO_LOG_NUM(fba_pos + fba_len - 1);
2163         ASSERT(st <= en);
2164         while (st <= en) {
2165                 int use_ref;
2166 again:
2167                 mutex_enter(&krdc->bmapmutex);
2168 
2169                 if (krdc->dcio_bitmap == NULL) {
2170 #ifdef DEBUG
2171                         cmn_err(CE_WARN, "!rdc_std_set_bitmap: "
2172                             "recovery bitmaps not allocated");
2173 #endif
2174                         mutex_exit(&krdc->bmapmutex);
2175                         return (-1);
2176                 }
2177 
2178                 use_ref = IS_PRIMARY(urdc) && IS_ASYNC(urdc) &&
2179                     ((rdc_get_vflags(urdc) & RDC_QUEUING) ||
2180                     !(rdc_get_vflags(urdc) & RDC_LOGGING));
2181 
2182 
2183                 if (!BMAP_BIT_ISSET(krdc->dcio_bitmap, st)) {
2184                         BMAP_BIT_SET(krdc->dcio_bitmap, st);
2185                         if (use_ref) {
2186                                 ASSERT(BMAP_REF_ISSET(krdc, st) ==
2187                                     0);
2188                                 BMAP_REF_FORCE(krdc, st, 1);
2189                         }
2190                         BMAP_BIT_SET((uchar_t *)bitmask, st - first);
2191                         urdc->bits_set++;
2192                         if ((!fbaset) || fba != BIT_TO_FBA(st)) {
2193                                 if (fbaset && krdc->bitmap_write > 0) {
2194                                         mutex_exit(&krdc->bmapmutex);
2195                                         if (rdc_write_bitmap_fba(krdc, fba) < 0)
2196                                                 return (-1);
2197                                         mutex_enter(&krdc->bmapmutex);
2198                                 }
2199                                 fba = BIT_TO_FBA(st);
2200                                 fbaset = 1;
2201                         }
2202                 } else {
2203                 /*
2204                  * Just bump reference count
2205                  * For logging or syncing we do not care what the reference
2206                  * is as it will be forced back on the state transition.
2207                  */
2208                         if (use_ref) {
2209                                 if (BMAP_REF_ISSET(krdc, st) ==
2210                                     BMAP_REF_MAXVAL(krdc)) {
2211                                         /*
2212                                          * Rollover of reference count.
2213                                          */
2214 
2215                                         if (!(rdc_get_vflags(urdc) &
2216                                             RDC_VOL_FAILED)) {
2217                                                 /*
2218                                                  * Impose throttle to help dump
2219                                                  * queue
2220                                                  */
2221                                                 mutex_exit(&krdc->bmapmutex);
2222                                                 delay(4);
2223                                                 rdc_bitmap_delay++;
2224                                                 if (printerr--) {
2225         cmn_err(CE_WARN, "!SNDR: bitmap reference count maxed out for %s:%s",
2226             urdc->secondary.intf, urdc->secondary.file);
2227 
2228                                                 }
2229 
2230                                                 if ((tries-- <= 0) &&
2231                                                     IS_STATE(urdc, queuing)) {
2232         cmn_err(CE_WARN, "!SNDR: giving up on reference count, logging set"
2233             " %s:%s", urdc->secondary.intf, urdc->secondary.file);
2234                                                         rdc_group_enter(krdc);
2235                                                         rdc_group_log(krdc,
2236                                                             RDC_NOFLUSH |
2237                                                             RDC_NOREMOTE|
2238                                                             RDC_FORCE_GROUP,
2239                                             "ref count retry limit exceeded");
2240                                                         rdc_group_exit(krdc);
2241                                                 }
2242                                                 goto again;
2243                                         }
2244                                 } else {
2245                                         BMAP_REF_SET(krdc, st);
2246                                 }
2247                         }
2248                 }
2249                 mutex_exit(&krdc->bmapmutex);
2250                 st++;
2251         }
2252         if (fbaset && krdc->bitmap_write > 0) {
2253                 if (rdc_write_bitmap_fba(krdc, fba) < 0)
2254                         return (-1);
2255         }
2256         return (0);
2257 }
2258 
2259 static void
2260 rdc_std_clr_bitmap(rdc_k_info_t *krdc, const nsc_off_t fba_pos,
2261     const nsc_size_t fba_len, const uint_t bitmask, const int force)
2262 {
2263         int first, st, en;
2264         nsc_off_t fba = 0;
2265         int fbaset = 0;
2266         uint_t bm = bitmask;
2267         uchar_t *ptr = (uchar_t *)&bm;
2268         rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
2269 
2270         if (rdc_get_vflags(urdc) & RDC_BMP_FAILED)
2271                 return;
2272 
2273         first = st = FBA_TO_LOG_NUM(fba_pos);
2274         en = FBA_TO_LOG_NUM(fba_pos + fba_len - 1);
2275         ASSERT(st <= en);
2276         while (st <= en) {
2277                 mutex_enter(&krdc->bmapmutex);
2278 
2279                 if (krdc->dcio_bitmap == NULL) {
2280 #ifdef DEBUG
2281                         cmn_err(CE_WARN, "!rdc_std_clr_bitmap: "
2282                             "recovery bitmaps not allocated");
2283 #endif
2284                         mutex_exit(&krdc->bmapmutex);
2285                         return;
2286                 }
2287 
2288                 if (((bitmask == 0xffffffff) ||
2289                     (BMAP_BIT_ISSET(ptr, st - first))) &&
2290                     BMAP_BIT_ISSET(krdc->dcio_bitmap, st)) {
2291 
2292                         int use_ref = IS_PRIMARY(urdc) && IS_ASYNC(urdc) &&
2293                             ((rdc_get_vflags(urdc) & RDC_QUEUING) ||
2294                             !(rdc_get_vflags(urdc) & RDC_LOGGING));
2295 
2296                         if (force || (use_ref == 0)) {
2297                                 if (krdc->bitmap_ref)
2298                                         BMAP_REF_FORCE(krdc, st, 0);
2299                         } else if (use_ref) {
2300                                 if (BMAP_REF_ISSET(krdc, st) != 0)
2301                                         BMAP_REF_CLR(krdc, st);
2302 
2303                         }
2304 
2305                         if ((use_ref == 0) || (use_ref &&
2306                             !BMAP_REF_ISSET(krdc, st))) {
2307                                 BMAP_BIT_CLR(krdc->dcio_bitmap, st);
2308 
2309                                 urdc->bits_set--;
2310                                 if (!fbaset || fba != BIT_TO_FBA(st)) {
2311                                         if (fbaset &&
2312                                             krdc->bitmap_write > 0) {
2313                                                 mutex_exit(&krdc->bmapmutex);
2314                                                 if (rdc_write_bitmap_fba(krdc,
2315                                                     fba) < 0)
2316                                                         return;
2317                                                 mutex_enter(&krdc->bmapmutex);
2318                                         }
2319                                         fba = BIT_TO_FBA(st);
2320                                         fbaset = 1;
2321                                 }
2322                         }
2323                 }
2324                 mutex_exit(&krdc->bmapmutex);
2325                 st++;
2326         }
2327         if (fbaset && krdc->bitmap_write > 0) {
2328                 if (rdc_write_bitmap_fba(krdc, fba) < 0)
2329                         return;
2330         }
2331 }
2332 
2333 /*
2334  * make sure that this bit is set. if it isn't, set it
2335  * used when transitioning from async to sync while going
2336  * from rep to log. an overlapping sync write may unconditionally
2337  * clear the bit that has not been replicated. when the queue
2338  * is being dumped or this is called just to make sure pending stuff
2339  * is in the bitmap
2340  */
2341 void
2342 rdc_std_check_bit(rdc_k_info_t *krdc, nsc_off_t pos, nsc_size_t len)
2343 {
2344         int st;
2345         int en;
2346         nsc_off_t fba;
2347         rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
2348         st = FBA_TO_LOG_NUM(pos);
2349         en = FBA_TO_LOG_NUM(pos + len - 1);
2350 
2351         if (rdc_get_vflags(urdc) & RDC_BMP_FAILED)
2352                 return;
2353 
2354         while (st <= en) {
2355                 mutex_enter(&krdc->bmapmutex);
2356 
2357                 if (krdc->dcio_bitmap == NULL) {
2358 #ifdef DEBUG
2359                         cmn_err(CE_WARN, "!rdc_std_check_bit: "
2360                             "recovery bitmaps not allocated");
2361 #endif
2362                         mutex_exit(&krdc->bmapmutex);
2363                         return;
2364                 }
2365 
2366                 if (!BMAP_BIT_ISSET(krdc->dcio_bitmap, st)) {
2367                         BMAP_BIT_SET(krdc->dcio_bitmap, st);
2368                         if (krdc->bitmap_write > 0) {
2369                                 fba = BIT_TO_FBA(st);
2370                                 mutex_exit(&krdc->bmapmutex);
2371                                 (void) rdc_write_bitmap_fba(krdc, fba);
2372                                 mutex_enter(&krdc->bmapmutex);
2373                         }
2374                         urdc->bits_set++;
2375 
2376                 }
2377                 mutex_exit(&krdc->bmapmutex);
2378                 st++;
2379         }
2380 
2381 }
2382 
2383 /*
2384  * rdc_std_count_dirty(krdc):
2385  *
2386  * Determine the number of segments that need to be flushed, This should
2387  * agree with the number of segments logged, but since we don't lock when
2388  * we increment, we force these values to agree
2389  */
2390 static int
2391 rdc_std_count_dirty(rdc_k_info_t *krdc)
2392 {
2393         rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
2394         int i, count, size;
2395 
2396         if (krdc->dcio_bitmap == NULL) {
2397 #ifdef DEBUG
2398                 cmn_err(CE_WARN,
2399                     "!rdc_std_count_dirty: no bitmap configured for %s",
2400                     urdc->primary.file);
2401 #endif
2402                 return (0);
2403         }
2404 
2405         count = 0;
2406         ASSERT(urdc->volume_size != 0);
2407         size = FBA_TO_LOG_LEN(urdc->volume_size);
2408         for (i = 0; i < size; i++)
2409                 if (BMAP_BIT_ISSET(krdc->dcio_bitmap, i))
2410                         count++;
2411 
2412         if (count > size)
2413                 count = size;
2414 
2415         return (count);
2416 }
2417 
2418 
2419 static int
2420 rdc_std_bit_isset(rdc_k_info_t *krdc, const int bit)
2421 {
2422         return (BMAP_BIT_ISSET(krdc->dcio_bitmap, bit));
2423 }
2424 
2425 
2426 /*
2427  * rdc_std_fill_bitmap(krdc, write)
2428  *
2429  * Called to force bitmaps to a fully dirty state
2430  */
2431 static int
2432 rdc_std_fill_bitmap(rdc_k_info_t *krdc, const int write)
2433 {
2434         rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
2435         int i, size;
2436 
2437         if (krdc->dcio_bitmap == NULL) {
2438 #ifdef DEBUG
2439                 cmn_err(CE_WARN,
2440                     "!rdc_std_fill_bitmap: no bitmap configured for %s",
2441                     urdc->primary.file);
2442 #endif
2443                 return (-1);
2444         }
2445 
2446         ASSERT(urdc->volume_size != 0);
2447         size = FBA_TO_LOG_LEN(urdc->volume_size);
2448         for (i = 0; i < size; i++)
2449                 BMAP_BIT_SET(krdc->dcio_bitmap, i);
2450 
2451         urdc->bits_set = size;
2452 
2453         if (write)
2454                 return (rdc_write_bitmap(krdc));
2455 
2456         return (0);
2457 }
2458 
2459 
2460 /*
2461  * rdc_std_zero_bitmap(krdc)
2462  *
2463  * Called on the secondary after a sync has completed to force bitmaps
2464  * to a fully clean state
2465  */
2466 static void
2467 rdc_std_zero_bitmap(rdc_k_info_t *krdc)
2468 {
2469         rdc_u_info_t *urdc = &rdc_u_info[krdc->index];
2470         int i, size;
2471 
2472         if (krdc->dcio_bitmap == NULL) {
2473 #ifdef DEBUG
2474                 cmn_err(CE_WARN,
2475                     "!rdc_std_zero_bitmap: no bitmap configured for %s",
2476                     urdc->primary.file);
2477 #endif
2478                 return;
2479         }
2480 #ifdef DEBUG
2481         cmn_err(CE_NOTE, "!Clearing bitmap for %s", urdc->secondary.file);
2482 #endif
2483 
2484         ASSERT(urdc->volume_size != 0);
2485         size = FBA_TO_LOG_LEN(urdc->volume_size);
2486         for (i = 0; i < size; i++)
2487                 BMAP_BIT_CLR(krdc->dcio_bitmap, i);
2488         if (krdc->bitmap_write > 0)
2489                 (void) rdc_write_bitmap(krdc);
2490 
2491         urdc->bits_set = 0;
2492 }
2493 
2494 
2495 /*
2496  * rdc_std_net_bmap()
2497  *
2498  * WARNING acts as both client and server
2499  */
2500 static int
2501 rdc_std_net_bmap(const struct bmap6 *b)
2502 {
2503         rdc_k_info_t *krdc = &rdc_k_info[b->cd];
2504         struct net_bdata6 bd;
2505 
2506         bd.data.data_val = (char *)krdc->dcio_bitmap;
2507         bd.cd = b->dual;
2508         bd.offset = 0;
2509 
2510         return (_rdc_net_bmap(b, &bd));
2511 }
2512 
2513 
2514 /*
2515  * rdc_std_net_bdata
2516  */
2517 static int
2518 rdc_std_net_bdata(const struct net_bdata6 *bd)
2519 {
2520         rdc_k_info_t *krdc = &rdc_k_info[bd->cd];
2521 
2522         rdc_lor((uchar_t *)bd->data.data_val,
2523             (uchar_t *)(((char *)krdc->dcio_bitmap) + bd->offset), bd->size);
2524 
2525         return (0);
2526 }
2527 
2528 
2529 static struct rdc_bitmap_ops rdc_std_bitmap_ops = {
2530         rdc_std_set_bitmap,
2531         rdc_std_clr_bitmap,
2532         rdc_std_count_dirty,
2533         rdc_std_bit_isset,
2534         rdc_std_fill_bitmap,
2535         rdc_std_zero_bitmap,
2536         rdc_std_net_bmap,
2537         rdc_std_net_bdata,
2538         rdc_std_zero_bitref,
2539         rdc_std_set_bitmask,
2540         rdc_std_check_bit
2541 };
2542 
2543 
2544 void
2545 rdc_bitmap_init()
2546 {
2547         rdc_bitmap_ops = &rdc_std_bitmap_ops;
2548         rdc_wrflag = NSC_WRITE;
2549 }
2550 
2551 static void
2552 rdc_bmap_ref_byte_set(rdc_k_info_t *krdc, int ind)
2553 {
2554         unsigned char *bmap = (unsigned char *)krdc->bitmap_ref;
2555 
2556         ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned char));
2557         bmap[ind]++;
2558 }
2559 
2560 static void
2561 rdc_bmap_ref_byte_clr(rdc_k_info_t *krdc, int ind)
2562 {
2563         unsigned char *bmap = (unsigned char *)krdc->bitmap_ref;
2564 
2565         ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned char));
2566         bmap[ind]--;
2567 }
2568 
2569 static unsigned int
2570 rdc_bmap_ref_byte_isset(rdc_k_info_t *krdc, int ind)
2571 {
2572         unsigned char *bmap = (unsigned char *)krdc->bitmap_ref;
2573 
2574         ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned char));
2575         return ((unsigned int)(bmap[ind]));
2576 }
2577 
2578 static void
2579 rdc_bmap_ref_byte_force(rdc_k_info_t *krdc, int ind, unsigned int val)
2580 {
2581         unsigned char *bmap = (unsigned char *)krdc->bitmap_ref;
2582 
2583         ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned char));
2584         bmap[ind] = (unsigned char) val;
2585 }
2586 
2587 /* ARGSUSED */
2588 static unsigned int
2589 rdc_bmap_ref_byte_maxval(rdc_k_info_t *krdc)
2590 {
2591         ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned char));
2592         return ((unsigned int)(UINT8_MAX));
2593 }
2594 
2595 struct bm_ref_ops rdc_ref_byte_ops = {
2596         rdc_bmap_ref_byte_set,
2597         rdc_bmap_ref_byte_clr,
2598         rdc_bmap_ref_byte_isset,
2599         rdc_bmap_ref_byte_force,
2600         rdc_bmap_ref_byte_maxval,
2601         sizeof (unsigned char)
2602 };
2603 
2604 static void
2605 rdc_bmap_ref_int_set(rdc_k_info_t *krdc, int ind)
2606 {
2607         unsigned int *bmap = (unsigned int *)krdc->bitmap_ref;
2608 
2609         ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned int));
2610         bmap[ind]++;
2611 }
2612 
2613 static void
2614 rdc_bmap_ref_int_clr(rdc_k_info_t *krdc, int ind)
2615 {
2616         unsigned int *bmap = (unsigned int *)krdc->bitmap_ref;
2617 
2618         ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned int));
2619         bmap[ind]--;
2620 }
2621 
2622 static unsigned int
2623 rdc_bmap_ref_int_isset(rdc_k_info_t *krdc, int ind)
2624 {
2625         unsigned int *bmap = (unsigned int *)krdc->bitmap_ref;
2626 
2627         ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned int));
2628         return ((bmap[ind]));
2629 }
2630 
2631 static void
2632 rdc_bmap_ref_int_force(rdc_k_info_t *krdc, int ind, unsigned int val)
2633 {
2634         unsigned int *bmap = (unsigned int *)krdc->bitmap_ref;
2635 
2636         ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned int));
2637         bmap[ind] = val;
2638 }
2639 
2640 /* ARGSUSED */
2641 static unsigned int
2642 rdc_bmap_ref_int_maxval(rdc_k_info_t *krdc)
2643 {
2644         ASSERT(BMAP_REF_SIZE(krdc) == sizeof (unsigned int));
2645         return ((unsigned int)(UINT_MAX));
2646 }
2647 
2648 struct bm_ref_ops rdc_ref_int_ops = {
2649         rdc_bmap_ref_int_set,
2650         rdc_bmap_ref_int_clr,
2651         rdc_bmap_ref_int_isset,
2652         rdc_bmap_ref_int_force,
2653         rdc_bmap_ref_int_maxval,
2654         sizeof (unsigned int)
2655 };