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/conf.h> 27 #include <sys/file.h> 28 #include <sys/ddi.h> 29 #include <sys/sunddi.h> 30 #include <sys/modctl.h> 31 #include <sys/scsi/scsi.h> 32 #include <sys/scsi/impl/scsi_reset_notify.h> 33 #include <sys/disp.h> 34 #include <sys/byteorder.h> 35 #include <sys/pathname.h> 36 #include <sys/atomic.h> 37 #include <sys/nvpair.h> 38 #include <sys/fs/zfs.h> 39 #include <sys/sdt.h> 40 #include <sys/dkio.h> 41 #include <sys/zfs_ioctl.h> 42 43 #include <stmf.h> 44 #include <lpif.h> 45 #include <stmf_ioctl.h> 46 #include <stmf_sbd.h> 47 #include <sbd_impl.h> 48 #include <stmf_sbd_ioctl.h> 49 50 #define SBD_IS_ZVOL(zvol) (strncmp("/dev/zvol", zvol, 9)) 51 52 extern sbd_status_t sbd_pgr_meta_init(sbd_lu_t *sl); 53 extern sbd_status_t sbd_pgr_meta_load(sbd_lu_t *sl); 54 extern void sbd_pgr_reset(sbd_lu_t *sl); 55 56 static int sbd_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, 57 void **result); 58 static int sbd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 59 static int sbd_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); 60 static int sbd_open(dev_t *devp, int flag, int otype, cred_t *credp); 61 static int sbd_close(dev_t dev, int flag, int otype, cred_t *credp); 62 static int stmf_sbd_ioctl(dev_t dev, int cmd, intptr_t data, int mode, 63 cred_t *credp, int *rval); 64 void sbd_lp_cb(stmf_lu_provider_t *lp, int cmd, void *arg, uint32_t flags); 65 stmf_status_t sbd_proxy_reg_lu(uint8_t *luid, void *proxy_reg_arg, 66 uint32_t proxy_reg_arg_len); 67 stmf_status_t sbd_proxy_dereg_lu(uint8_t *luid, void *proxy_reg_arg, 68 uint32_t proxy_reg_arg_len); 69 stmf_status_t sbd_proxy_msg(uint8_t *luid, void *proxy_arg, 70 uint32_t proxy_arg_len, uint32_t type); 71 int sbd_create_register_lu(sbd_create_and_reg_lu_t *slu, int struct_sz, 72 uint32_t *err_ret); 73 int sbd_create_standby_lu(sbd_create_standby_lu_t *slu, uint32_t *err_ret); 74 int sbd_set_lu_standby(sbd_set_lu_standby_t *stlu, uint32_t *err_ret); 75 int sbd_import_lu(sbd_import_lu_t *ilu, int struct_sz, uint32_t *err_ret, 76 int no_register, sbd_lu_t **slr); 77 int sbd_import_active_lu(sbd_import_lu_t *ilu, sbd_lu_t *sl, uint32_t *err_ret); 78 int sbd_delete_lu(sbd_delete_lu_t *dlu, int struct_sz, uint32_t *err_ret); 79 int sbd_modify_lu(sbd_modify_lu_t *mlu, int struct_sz, uint32_t *err_ret); 80 int sbd_get_lu_props(sbd_lu_props_t *islp, uint32_t islp_sz, 81 sbd_lu_props_t *oslp, uint32_t oslp_sz, uint32_t *err_ret); 82 char *sbd_get_zvol_name(sbd_lu_t *sl); 83 sbd_status_t sbd_create_zfs_meta_object(sbd_lu_t *sl); 84 sbd_status_t sbd_open_zfs_meta(sbd_lu_t *sl); 85 sbd_status_t sbd_read_zfs_meta(sbd_lu_t *sl, uint8_t *buf, uint64_t sz, 86 uint64_t off); 87 sbd_status_t sbd_write_zfs_meta(sbd_lu_t *sl, uint8_t *buf, uint64_t sz, 88 uint64_t off); 89 int sbd_is_zvol(char *path); 90 int sbd_zvolget(char *zvol_name, char **comstarprop); 91 int sbd_zvolset(char *zvol_name, char *comstarprop); 92 char sbd_ctoi(char c); 93 void sbd_close_lu(sbd_lu_t *sl); 94 95 static ldi_ident_t sbd_zfs_ident; 96 static stmf_lu_provider_t *sbd_lp; 97 static sbd_lu_t *sbd_lu_list = NULL; 98 static kmutex_t sbd_lock; 99 static dev_info_t *sbd_dip; 100 static uint32_t sbd_lu_count = 0; 101 char sbd_vendor_id[] = "SUN "; 102 char sbd_product_id[] = "COMSTAR "; 103 char sbd_revision[] = "1.0 "; 104 static char sbd_name[] = "sbd"; 105 106 static struct cb_ops sbd_cb_ops = { 107 sbd_open, /* open */ 108 sbd_close, /* close */ 109 nodev, /* strategy */ 110 nodev, /* print */ 111 nodev, /* dump */ 112 nodev, /* read */ 113 nodev, /* write */ 114 stmf_sbd_ioctl, /* ioctl */ 115 nodev, /* devmap */ 116 nodev, /* mmap */ 117 nodev, /* segmap */ 118 nochpoll, /* chpoll */ 119 ddi_prop_op, /* cb_prop_op */ 120 0, /* streamtab */ 121 D_NEW | D_MP, /* cb_flag */ 122 CB_REV, /* rev */ 123 nodev, /* aread */ 124 nodev /* awrite */ 125 }; 126 127 static struct dev_ops sbd_ops = { 128 DEVO_REV, 129 0, 130 sbd_getinfo, 131 nulldev, /* identify */ 132 nulldev, /* probe */ 133 sbd_attach, 134 sbd_detach, 135 nodev, /* reset */ 136 &sbd_cb_ops, 137 NULL, /* bus_ops */ 138 NULL /* power */ 139 }; 140 141 #define SBD_NAME "COMSTAR SBD" 142 143 static struct modldrv modldrv = { 144 &mod_driverops, 145 SBD_NAME, 146 &sbd_ops 147 }; 148 149 static struct modlinkage modlinkage = { 150 MODREV_1, 151 &modldrv, 152 NULL 153 }; 154 155 int 156 _init(void) 157 { 158 int ret; 159 160 ret = mod_install(&modlinkage); 161 if (ret) 162 return (ret); 163 sbd_lp = (stmf_lu_provider_t *)stmf_alloc(STMF_STRUCT_LU_PROVIDER, 164 0, 0); 165 sbd_lp->lp_lpif_rev = LPIF_REV_2; 166 sbd_lp->lp_instance = 0; 167 sbd_lp->lp_name = sbd_name; 168 sbd_lp->lp_cb = sbd_lp_cb; 169 sbd_lp->lp_alua_support = 1; 170 sbd_lp->lp_proxy_msg = sbd_proxy_msg; 171 sbd_zfs_ident = ldi_ident_from_anon(); 172 173 if (stmf_register_lu_provider(sbd_lp) != STMF_SUCCESS) { 174 (void) mod_remove(&modlinkage); 175 stmf_free(sbd_lp); 176 return (EINVAL); 177 } 178 mutex_init(&sbd_lock, NULL, MUTEX_DRIVER, NULL); 179 return (0); 180 } 181 182 int 183 _fini(void) 184 { 185 int ret; 186 187 /* 188 * If we have registered lus, then make sure they are all offline 189 * if so then deregister them. This should drop the sbd_lu_count 190 * to zero. 191 */ 192 if (sbd_lu_count) { 193 sbd_lu_t *slu; 194 195 /* See if all of them are offline */ 196 mutex_enter(&sbd_lock); 197 for (slu = sbd_lu_list; slu != NULL; slu = slu->sl_next) { 198 if ((slu->sl_state != STMF_STATE_OFFLINE) || 199 slu->sl_state_not_acked) { 200 mutex_exit(&sbd_lock); 201 return (EBUSY); 202 } 203 } 204 mutex_exit(&sbd_lock); 205 206 #if 0 207 /* ok start deregistering them */ 208 while (sbd_lu_list) { 209 sbd_store_t *sst = sbd_lu_list->sl_sst; 210 if (sst->sst_deregister_lu(sst) != STMF_SUCCESS) 211 return (EBUSY); 212 } 213 #endif 214 return (EBUSY); 215 } 216 if (stmf_deregister_lu_provider(sbd_lp) != STMF_SUCCESS) 217 return (EBUSY); 218 ret = mod_remove(&modlinkage); 219 if (ret != 0) { 220 (void) stmf_register_lu_provider(sbd_lp); 221 return (ret); 222 } 223 stmf_free(sbd_lp); 224 mutex_destroy(&sbd_lock); 225 ldi_ident_release(sbd_zfs_ident); 226 return (0); 227 } 228 229 int 230 _info(struct modinfo *modinfop) 231 { 232 return (mod_info(&modlinkage, modinfop)); 233 } 234 235 /* ARGSUSED */ 236 static int 237 sbd_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) 238 { 239 switch (cmd) { 240 case DDI_INFO_DEVT2DEVINFO: 241 *result = sbd_dip; 242 break; 243 case DDI_INFO_DEVT2INSTANCE: 244 *result = (void *)(uintptr_t)ddi_get_instance(sbd_dip); 245 break; 246 default: 247 return (DDI_FAILURE); 248 } 249 250 return (DDI_SUCCESS); 251 } 252 253 static int 254 sbd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 255 { 256 switch (cmd) { 257 case DDI_ATTACH: 258 sbd_dip = dip; 259 260 if (ddi_create_minor_node(dip, "admin", S_IFCHR, 0, 261 DDI_NT_STMF_LP, 0) != DDI_SUCCESS) { 262 break; 263 } 264 ddi_report_dev(dip); 265 return (DDI_SUCCESS); 266 } 267 268 return (DDI_FAILURE); 269 } 270 271 static int 272 sbd_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 273 { 274 switch (cmd) { 275 case DDI_DETACH: 276 ddi_remove_minor_node(dip, 0); 277 return (DDI_SUCCESS); 278 } 279 280 return (DDI_FAILURE); 281 } 282 283 /* ARGSUSED */ 284 static int 285 sbd_open(dev_t *devp, int flag, int otype, cred_t *credp) 286 { 287 if (otype != OTYP_CHR) 288 return (EINVAL); 289 return (0); 290 } 291 292 /* ARGSUSED */ 293 static int 294 sbd_close(dev_t dev, int flag, int otype, cred_t *credp) 295 { 296 return (0); 297 } 298 299 /* ARGSUSED */ 300 static int 301 stmf_sbd_ioctl(dev_t dev, int cmd, intptr_t data, int mode, 302 cred_t *credp, int *rval) 303 { 304 stmf_iocdata_t *iocd; 305 void *ibuf = NULL; 306 void *obuf = NULL; 307 sbd_lu_t *nsl; 308 int i; 309 int ret; 310 311 if (drv_priv(credp) != 0) { 312 return (EPERM); 313 } 314 315 ret = stmf_copyin_iocdata(data, mode, &iocd, &ibuf, &obuf); 316 if (ret) 317 return (ret); 318 iocd->stmf_error = 0; 319 320 switch (cmd) { 321 case SBD_IOCTL_CREATE_AND_REGISTER_LU: 322 if (iocd->stmf_ibuf_size < 323 (sizeof (sbd_create_and_reg_lu_t) - 8)) { 324 ret = EFAULT; 325 break; 326 } 327 if ((iocd->stmf_obuf_size == 0) || 328 (iocd->stmf_obuf_size > iocd->stmf_ibuf_size)) { 329 ret = EINVAL; 330 break; 331 } 332 ret = sbd_create_register_lu((sbd_create_and_reg_lu_t *) 333 ibuf, iocd->stmf_ibuf_size, &iocd->stmf_error); 334 bcopy(ibuf, obuf, iocd->stmf_obuf_size); 335 break; 336 case SBD_IOCTL_SET_LU_STANDBY: 337 if (iocd->stmf_ibuf_size < sizeof (sbd_set_lu_standby_t)) { 338 ret = EFAULT; 339 break; 340 } 341 if (iocd->stmf_obuf_size) { 342 ret = EINVAL; 343 break; 344 } 345 ret = sbd_set_lu_standby((sbd_set_lu_standby_t *)ibuf, 346 &iocd->stmf_error); 347 break; 348 case SBD_IOCTL_IMPORT_LU: 349 if (iocd->stmf_ibuf_size < 350 (sizeof (sbd_import_lu_t) - 8)) { 351 ret = EFAULT; 352 break; 353 } 354 if ((iocd->stmf_obuf_size == 0) || 355 (iocd->stmf_obuf_size > iocd->stmf_ibuf_size)) { 356 ret = EINVAL; 357 break; 358 } 359 ret = sbd_import_lu((sbd_import_lu_t *)ibuf, 360 iocd->stmf_ibuf_size, &iocd->stmf_error, 0, NULL); 361 bcopy(ibuf, obuf, iocd->stmf_obuf_size); 362 break; 363 case SBD_IOCTL_DELETE_LU: 364 if (iocd->stmf_ibuf_size < (sizeof (sbd_delete_lu_t) - 8)) { 365 ret = EFAULT; 366 break; 367 } 368 if (iocd->stmf_obuf_size) { 369 ret = EINVAL; 370 break; 371 } 372 ret = sbd_delete_lu((sbd_delete_lu_t *)ibuf, 373 iocd->stmf_ibuf_size, &iocd->stmf_error); 374 break; 375 case SBD_IOCTL_MODIFY_LU: 376 if (iocd->stmf_ibuf_size < (sizeof (sbd_modify_lu_t) - 8)) { 377 ret = EFAULT; 378 break; 379 } 380 if (iocd->stmf_obuf_size) { 381 ret = EINVAL; 382 break; 383 } 384 ret = sbd_modify_lu((sbd_modify_lu_t *)ibuf, 385 iocd->stmf_ibuf_size, &iocd->stmf_error); 386 break; 387 case SBD_IOCTL_GET_LU_PROPS: 388 if (iocd->stmf_ibuf_size < (sizeof (sbd_lu_props_t) - 8)) { 389 ret = EFAULT; 390 break; 391 } 392 if (iocd->stmf_obuf_size < sizeof (sbd_lu_props_t)) { 393 ret = EINVAL; 394 break; 395 } 396 ret = sbd_get_lu_props((sbd_lu_props_t *)ibuf, 397 iocd->stmf_ibuf_size, (sbd_lu_props_t *)obuf, 398 iocd->stmf_obuf_size, &iocd->stmf_error); 399 break; 400 case SBD_IOCTL_GET_LU_LIST: 401 mutex_enter(&sbd_lock); 402 iocd->stmf_obuf_max_nentries = sbd_lu_count; 403 iocd->stmf_obuf_nentries = min((iocd->stmf_obuf_size >> 4), 404 sbd_lu_count); 405 for (nsl = sbd_lu_list, i = 0; nsl && 406 (i < iocd->stmf_obuf_nentries); i++, nsl = nsl->sl_next) { 407 bcopy(nsl->sl_device_id + 4, 408 &(((uint8_t *)obuf)[i << 4]), 16); 409 } 410 mutex_exit(&sbd_lock); 411 ret = 0; 412 iocd->stmf_error = 0; 413 break; 414 default: 415 ret = ENOTTY; 416 } 417 418 if (ret == 0) { 419 ret = stmf_copyout_iocdata(data, mode, iocd, obuf); 420 } else if (iocd->stmf_error) { 421 (void) stmf_copyout_iocdata(data, mode, iocd, obuf); 422 } 423 if (obuf) { 424 kmem_free(obuf, iocd->stmf_obuf_size); 425 obuf = NULL; 426 } 427 if (ibuf) { 428 kmem_free(ibuf, iocd->stmf_ibuf_size); 429 ibuf = NULL; 430 } 431 kmem_free(iocd, sizeof (stmf_iocdata_t)); 432 return (ret); 433 } 434 435 /* ARGSUSED */ 436 void 437 sbd_lp_cb(stmf_lu_provider_t *lp, int cmd, void *arg, uint32_t flags) 438 { 439 nvpair_t *np; 440 char *s; 441 sbd_import_lu_t *ilu; 442 uint32_t ilu_sz; 443 uint32_t struct_sz; 444 uint32_t err_ret; 445 int iret; 446 447 if ((cmd != STMF_PROVIDER_DATA_UPDATED) || (arg == NULL)) { 448 return; 449 } 450 451 if ((flags & (STMF_PCB_STMF_ONLINING | STMF_PCB_PREG_COMPLETE)) == 0) { 452 return; 453 } 454 455 np = NULL; 456 ilu_sz = 1024; 457 ilu = (sbd_import_lu_t *)kmem_zalloc(ilu_sz, KM_SLEEP); 458 while ((np = nvlist_next_nvpair((nvlist_t *)arg, np)) != NULL) { 459 if (nvpair_type(np) != DATA_TYPE_STRING) { 460 continue; 461 } 462 if (nvpair_value_string(np, &s) != 0) { 463 continue; 464 } 465 struct_sz = max(8, strlen(s) + 1); 466 struct_sz += sizeof (sbd_import_lu_t) - 8; 467 if (struct_sz > ilu_sz) { 468 kmem_free(ilu, ilu_sz); 469 ilu_sz = struct_sz + 32; 470 ilu = (sbd_import_lu_t *)kmem_zalloc(ilu_sz, KM_SLEEP); 471 } 472 ilu->ilu_struct_size = struct_sz; 473 (void) strcpy(ilu->ilu_meta_fname, s); 474 iret = sbd_import_lu(ilu, struct_sz, &err_ret, 0, NULL); 475 if (iret) { 476 stmf_trace(0, "sbd_lp_cb: import_lu failed, ret = %d, " 477 "err_ret = %d", iret, err_ret); 478 } else { 479 stmf_trace(0, "Imported the LU %s", nvpair_name(np)); 480 } 481 } 482 483 if (ilu) { 484 kmem_free(ilu, ilu_sz); 485 ilu = NULL; 486 } 487 } 488 489 sbd_status_t 490 sbd_link_lu(sbd_lu_t *sl) 491 { 492 sbd_lu_t *nsl; 493 494 mutex_enter(&sbd_lock); 495 mutex_enter(&sl->sl_lock); 496 ASSERT(sl->sl_trans_op != SL_OP_NONE); 497 498 if (sl->sl_flags & SL_LINKED) { 499 mutex_exit(&sbd_lock); 500 mutex_exit(&sl->sl_lock); 501 return (SBD_ALREADY); 502 } 503 for (nsl = sbd_lu_list; nsl; nsl = nsl->sl_next) { 504 if (strcmp(nsl->sl_name, sl->sl_name) == 0) 505 break; 506 } 507 if (nsl) { 508 mutex_exit(&sbd_lock); 509 mutex_exit(&sl->sl_lock); 510 return (SBD_ALREADY); 511 } 512 sl->sl_next = sbd_lu_list; 513 sbd_lu_list = sl; 514 sl->sl_flags |= SL_LINKED; 515 mutex_exit(&sbd_lock); 516 mutex_exit(&sl->sl_lock); 517 return (SBD_SUCCESS); 518 } 519 520 void 521 sbd_unlink_lu(sbd_lu_t *sl) 522 { 523 sbd_lu_t **ppnsl; 524 525 mutex_enter(&sbd_lock); 526 mutex_enter(&sl->sl_lock); 527 ASSERT(sl->sl_trans_op != SL_OP_NONE); 528 529 ASSERT(sl->sl_flags & SL_LINKED); 530 for (ppnsl = &sbd_lu_list; *ppnsl; ppnsl = &((*ppnsl)->sl_next)) { 531 if (*ppnsl == sl) 532 break; 533 } 534 ASSERT(*ppnsl); 535 *ppnsl = (*ppnsl)->sl_next; 536 sl->sl_flags &= ~SL_LINKED; 537 mutex_exit(&sbd_lock); 538 mutex_exit(&sl->sl_lock); 539 } 540 541 sbd_status_t 542 sbd_find_and_lock_lu(uint8_t *guid, uint8_t *meta_name, uint8_t op, 543 sbd_lu_t **ppsl) 544 { 545 sbd_lu_t *sl; 546 int found = 0; 547 sbd_status_t sret; 548 549 mutex_enter(&sbd_lock); 550 for (sl = sbd_lu_list; sl; sl = sl->sl_next) { 551 if (guid) { 552 found = bcmp(sl->sl_device_id + 4, guid, 16) == 0; 553 } else { 554 found = strcmp(sl->sl_name, (char *)meta_name) == 0; 555 } 556 if (found) 557 break; 558 } 559 if (!found) { 560 mutex_exit(&sbd_lock); 561 return (SBD_NOT_FOUND); 562 } 563 mutex_enter(&sl->sl_lock); 564 if (sl->sl_trans_op == SL_OP_NONE) { 565 sl->sl_trans_op = op; 566 *ppsl = sl; 567 sret = SBD_SUCCESS; 568 } else { 569 sret = SBD_BUSY; 570 } 571 mutex_exit(&sl->sl_lock); 572 mutex_exit(&sbd_lock); 573 return (sret); 574 } 575 576 sbd_status_t 577 sbd_read_meta(sbd_lu_t *sl, uint64_t offset, uint64_t size, uint8_t *buf) 578 { 579 uint64_t meta_align; 580 uint64_t starting_off; 581 uint64_t data_off; 582 uint64_t ending_off; 583 uint64_t io_size; 584 uint8_t *io_buf; 585 vnode_t *vp; 586 sbd_status_t ret; 587 ssize_t resid; 588 int vret; 589 590 ASSERT(sl->sl_flags & SL_META_OPENED); 591 if (sl->sl_flags & SL_SHARED_META) { 592 meta_align = (((uint64_t)1) << sl->sl_data_blocksize_shift) - 1; 593 vp = sl->sl_data_vp; 594 ASSERT(vp); 595 } else { 596 meta_align = (((uint64_t)1) << sl->sl_meta_blocksize_shift) - 1; 597 if ((sl->sl_flags & SL_ZFS_META) == 0) { 598 vp = sl->sl_meta_vp; 599 ASSERT(vp); 600 } 601 } 602 starting_off = offset & ~(meta_align); 603 data_off = offset & meta_align; 604 ending_off = (offset + size + meta_align) & (~meta_align); 605 if (ending_off > sl->sl_meta_size_used) { 606 bzero(buf, size); 607 if (starting_off >= sl->sl_meta_size_used) { 608 return (SBD_SUCCESS); 609 } 610 ending_off = (sl->sl_meta_size_used + meta_align) & 611 (~meta_align); 612 if (size > (ending_off - (starting_off + data_off))) { 613 size = ending_off - (starting_off + data_off); 614 } 615 } 616 io_size = ending_off - starting_off; 617 io_buf = (uint8_t *)kmem_zalloc(io_size, KM_SLEEP); 618 ASSERT((starting_off + io_size) <= sl->sl_total_meta_size); 619 620 /* 621 * Don't proceed if the device has been closed 622 * This can occur on an access state change to standby or 623 * a delete. The writer lock is acquired before closing the 624 * lu. If importing, reading the metadata is valid, hence 625 * the check on SL_OP_IMPORT_LU. 626 */ 627 rw_enter(&sl->sl_access_state_lock, RW_READER); 628 if ((sl->sl_flags & SL_MEDIA_LOADED) == 0 && 629 sl->sl_trans_op != SL_OP_IMPORT_LU) { 630 rw_exit(&sl->sl_access_state_lock); 631 ret = SBD_FILEIO_FAILURE; 632 goto sbd_read_meta_failure; 633 } 634 if (sl->sl_flags & SL_ZFS_META) { 635 if ((ret = sbd_read_zfs_meta(sl, io_buf, io_size, 636 starting_off)) != SBD_SUCCESS) { 637 rw_exit(&sl->sl_access_state_lock); 638 goto sbd_read_meta_failure; 639 } 640 } else { 641 vret = vn_rdwr(UIO_READ, vp, (caddr_t)io_buf, (ssize_t)io_size, 642 (offset_t)starting_off, UIO_SYSSPACE, FRSYNC, 643 RLIM64_INFINITY, CRED(), &resid); 644 645 if (vret || resid) { 646 ret = SBD_FILEIO_FAILURE | vret; 647 rw_exit(&sl->sl_access_state_lock); 648 goto sbd_read_meta_failure; 649 } 650 } 651 rw_exit(&sl->sl_access_state_lock); 652 653 bcopy(io_buf + data_off, buf, size); 654 ret = SBD_SUCCESS; 655 656 sbd_read_meta_failure: 657 kmem_free(io_buf, io_size); 658 return (ret); 659 } 660 661 sbd_status_t 662 sbd_write_meta(sbd_lu_t *sl, uint64_t offset, uint64_t size, uint8_t *buf) 663 { 664 uint64_t meta_align; 665 uint64_t starting_off; 666 uint64_t data_off; 667 uint64_t ending_off; 668 uint64_t io_size; 669 uint8_t *io_buf; 670 vnode_t *vp; 671 sbd_status_t ret; 672 ssize_t resid; 673 int vret; 674 675 ASSERT(sl->sl_flags & SL_META_OPENED); 676 if (sl->sl_flags & SL_SHARED_META) { 677 meta_align = (((uint64_t)1) << sl->sl_data_blocksize_shift) - 1; 678 vp = sl->sl_data_vp; 679 ASSERT(vp); 680 } else { 681 meta_align = (((uint64_t)1) << sl->sl_meta_blocksize_shift) - 1; 682 if ((sl->sl_flags & SL_ZFS_META) == 0) { 683 vp = sl->sl_meta_vp; 684 ASSERT(vp); 685 } 686 } 687 starting_off = offset & ~(meta_align); 688 data_off = offset & meta_align; 689 ending_off = (offset + size + meta_align) & (~meta_align); 690 io_size = ending_off - starting_off; 691 io_buf = (uint8_t *)kmem_zalloc(io_size, KM_SLEEP); 692 ret = sbd_read_meta(sl, starting_off, io_size, io_buf); 693 if (ret != SBD_SUCCESS) { 694 goto sbd_write_meta_failure; 695 } 696 bcopy(buf, io_buf + data_off, size); 697 /* 698 * Don't proceed if the device has been closed 699 * This can occur on an access state change to standby or 700 * a delete. The writer lock is acquired before closing the 701 * lu. If importing, reading the metadata is valid, hence 702 * the check on SL_OP_IMPORT_LU. 703 */ 704 rw_enter(&sl->sl_access_state_lock, RW_READER); 705 if ((sl->sl_flags & SL_MEDIA_LOADED) == 0 && 706 sl->sl_trans_op != SL_OP_IMPORT_LU) { 707 rw_exit(&sl->sl_access_state_lock); 708 ret = SBD_FILEIO_FAILURE; 709 goto sbd_write_meta_failure; 710 } 711 if (sl->sl_flags & SL_ZFS_META) { 712 if ((ret = sbd_write_zfs_meta(sl, io_buf, io_size, 713 starting_off)) != SBD_SUCCESS) { 714 rw_exit(&sl->sl_access_state_lock); 715 goto sbd_write_meta_failure; 716 } 717 } else { 718 vret = vn_rdwr(UIO_WRITE, vp, (caddr_t)io_buf, (ssize_t)io_size, 719 (offset_t)starting_off, UIO_SYSSPACE, FDSYNC, 720 RLIM64_INFINITY, CRED(), &resid); 721 722 if (vret || resid) { 723 ret = SBD_FILEIO_FAILURE | vret; 724 rw_exit(&sl->sl_access_state_lock); 725 goto sbd_write_meta_failure; 726 } 727 } 728 rw_exit(&sl->sl_access_state_lock); 729 730 ret = SBD_SUCCESS; 731 732 sbd_write_meta_failure: 733 kmem_free(io_buf, io_size); 734 return (ret); 735 } 736 737 uint8_t 738 sbd_calc_sum(uint8_t *buf, int size) 739 { 740 uint8_t s = 0; 741 742 while (size > 0) 743 s += buf[--size]; 744 745 return (s); 746 } 747 748 uint8_t 749 sbd_calc_section_sum(sm_section_hdr_t *sm, uint32_t sz) 750 { 751 uint8_t s, o; 752 753 o = sm->sms_chksum; 754 sm->sms_chksum = 0; 755 s = sbd_calc_sum((uint8_t *)sm, sz); 756 sm->sms_chksum = o; 757 758 return (s); 759 } 760 761 uint32_t 762 sbd_strlen(char *str, uint32_t maxlen) 763 { 764 uint32_t i; 765 766 for (i = 0; i < maxlen; i++) { 767 if (str[i] == 0) 768 return (i); 769 } 770 return (i); 771 } 772 773 void 774 sbd_swap_meta_start(sbd_meta_start_t *sm) 775 { 776 if (sm->sm_magic == SBD_MAGIC) 777 return; 778 sm->sm_magic = BSWAP_64(sm->sm_magic); 779 sm->sm_meta_size = BSWAP_64(sm->sm_meta_size); 780 sm->sm_meta_size_used = BSWAP_64(sm->sm_meta_size_used); 781 sm->sm_ver_major = BSWAP_16(sm->sm_ver_major); 782 sm->sm_ver_minor = BSWAP_16(sm->sm_ver_minor); 783 sm->sm_ver_subminor = BSWAP_16(sm->sm_ver_subminor); 784 } 785 786 void 787 sbd_swap_section_hdr(sm_section_hdr_t *sm) 788 { 789 if (sm->sms_data_order == SMS_DATA_ORDER) 790 return; 791 sm->sms_offset = BSWAP_64(sm->sms_offset); 792 sm->sms_size = BSWAP_32(sm->sms_size); 793 sm->sms_id = BSWAP_16(sm->sms_id); 794 sm->sms_chksum += SMS_DATA_ORDER - sm->sms_data_order; 795 sm->sms_data_order = SMS_DATA_ORDER; 796 } 797 798 void 799 sbd_swap_lu_info_1_0(sbd_lu_info_1_0_t *sli) 800 { 801 sbd_swap_section_hdr(&sli->sli_sms_header); 802 if (sli->sli_data_order == SMS_DATA_ORDER) 803 return; 804 sli->sli_sms_header.sms_chksum += SMS_DATA_ORDER - sli->sli_data_order; 805 sli->sli_data_order = SMS_DATA_ORDER; 806 sli->sli_total_store_size = BSWAP_64(sli->sli_total_store_size); 807 sli->sli_total_meta_size = BSWAP_64(sli->sli_total_meta_size); 808 sli->sli_lu_data_offset = BSWAP_64(sli->sli_lu_data_offset); 809 sli->sli_lu_data_size = BSWAP_64(sli->sli_lu_data_size); 810 sli->sli_flags = BSWAP_32(sli->sli_flags); 811 sli->sli_blocksize = BSWAP_16(sli->sli_blocksize); 812 } 813 814 void 815 sbd_swap_lu_info_1_1(sbd_lu_info_1_1_t *sli) 816 { 817 sbd_swap_section_hdr(&sli->sli_sms_header); 818 if (sli->sli_data_order == SMS_DATA_ORDER) 819 return; 820 sli->sli_sms_header.sms_chksum += SMS_DATA_ORDER - sli->sli_data_order; 821 sli->sli_data_order = SMS_DATA_ORDER; 822 sli->sli_flags = BSWAP_32(sli->sli_flags); 823 sli->sli_lu_size = BSWAP_64(sli->sli_lu_size); 824 sli->sli_meta_fname_offset = BSWAP_64(sli->sli_meta_fname_offset); 825 sli->sli_data_fname_offset = BSWAP_64(sli->sli_data_fname_offset); 826 sli->sli_serial_offset = BSWAP_64(sli->sli_serial_offset); 827 sli->sli_alias_offset = BSWAP_64(sli->sli_alias_offset); 828 } 829 830 sbd_status_t 831 sbd_load_section_hdr(sbd_lu_t *sl, sm_section_hdr_t *sms) 832 { 833 sm_section_hdr_t h; 834 uint64_t st; 835 sbd_status_t ret; 836 837 for (st = sl->sl_meta_offset + sizeof (sbd_meta_start_t); 838 st < sl->sl_meta_size_used; st += h.sms_size) { 839 if ((ret = sbd_read_meta(sl, st, sizeof (sm_section_hdr_t), 840 (uint8_t *)&h)) != SBD_SUCCESS) { 841 return (ret); 842 } 843 if (h.sms_data_order != SMS_DATA_ORDER) { 844 sbd_swap_section_hdr(&h); 845 } 846 if ((h.sms_data_order != SMS_DATA_ORDER) || 847 (h.sms_offset != st) || (h.sms_size < sizeof (h)) || 848 ((st + h.sms_size) > sl->sl_meta_size_used)) { 849 return (SBD_META_CORRUPTED); 850 } 851 if (h.sms_id == sms->sms_id) { 852 bcopy(&h, sms, sizeof (h)); 853 return (SBD_SUCCESS); 854 } 855 } 856 857 return (SBD_NOT_FOUND); 858 } 859 860 sbd_status_t 861 sbd_load_meta_start(sbd_lu_t *sl) 862 { 863 sbd_meta_start_t *sm; 864 sbd_status_t ret; 865 866 /* Fake meta params initially */ 867 sl->sl_total_meta_size = (uint64_t)-1; 868 sl->sl_meta_size_used = sl->sl_meta_offset + sizeof (sbd_meta_start_t); 869 870 sm = kmem_zalloc(sizeof (*sm), KM_SLEEP); 871 ret = sbd_read_meta(sl, sl->sl_meta_offset, sizeof (*sm), 872 (uint8_t *)sm); 873 if (ret != SBD_SUCCESS) { 874 goto load_meta_start_failed; 875 } 876 877 if (sm->sm_magic != SBD_MAGIC) { 878 sbd_swap_meta_start(sm); 879 } 880 881 if ((sm->sm_magic != SBD_MAGIC) || (sbd_calc_sum((uint8_t *)sm, 882 sizeof (*sm) - 1) != sm->sm_chksum)) { 883 ret = SBD_META_CORRUPTED; 884 goto load_meta_start_failed; 885 } 886 887 if (sm->sm_ver_major != SBD_VER_MAJOR) { 888 ret = SBD_NOT_SUPPORTED; 889 goto load_meta_start_failed; 890 } 891 892 sl->sl_total_meta_size = sm->sm_meta_size; 893 sl->sl_meta_size_used = sm->sm_meta_size_used; 894 ret = SBD_SUCCESS; 895 896 load_meta_start_failed: 897 kmem_free(sm, sizeof (*sm)); 898 return (ret); 899 } 900 901 sbd_status_t 902 sbd_write_meta_start(sbd_lu_t *sl, uint64_t meta_size, uint64_t meta_size_used) 903 { 904 sbd_meta_start_t *sm; 905 sbd_status_t ret; 906 907 sm = (sbd_meta_start_t *)kmem_zalloc(sizeof (sbd_meta_start_t), 908 KM_SLEEP); 909 910 sm->sm_magic = SBD_MAGIC; 911 sm->sm_meta_size = meta_size; 912 sm->sm_meta_size_used = meta_size_used; 913 sm->sm_ver_major = SBD_VER_MAJOR; 914 sm->sm_ver_minor = SBD_VER_MINOR; 915 sm->sm_ver_subminor = SBD_VER_SUBMINOR; 916 sm->sm_chksum = sbd_calc_sum((uint8_t *)sm, sizeof (*sm) - 1); 917 918 ret = sbd_write_meta(sl, sl->sl_meta_offset, sizeof (*sm), 919 (uint8_t *)sm); 920 kmem_free(sm, sizeof (*sm)); 921 922 return (ret); 923 } 924 925 sbd_status_t 926 sbd_read_meta_section(sbd_lu_t *sl, sm_section_hdr_t **ppsms, uint16_t sms_id) 927 { 928 sbd_status_t ret; 929 sm_section_hdr_t sms; 930 int alloced = 0; 931 932 mutex_enter(&sl->sl_metadata_lock); 933 if (((*ppsms) == NULL) || ((*ppsms)->sms_offset == 0)) { 934 bzero(&sms, sizeof (sm_section_hdr_t)); 935 sms.sms_id = sms_id; 936 if ((ret = sbd_load_section_hdr(sl, &sms)) != SBD_SUCCESS) { 937 mutex_exit(&sl->sl_metadata_lock); 938 return (ret); 939 } else { 940 if ((*ppsms) == NULL) { 941 *ppsms = (sm_section_hdr_t *)kmem_zalloc( 942 sms.sms_size, KM_SLEEP); 943 alloced = 1; 944 } 945 bcopy(&sms, *ppsms, sizeof (sm_section_hdr_t)); 946 } 947 } 948 949 ret = sbd_read_meta(sl, (*ppsms)->sms_offset, (*ppsms)->sms_size, 950 (uint8_t *)(*ppsms)); 951 if (ret == SBD_SUCCESS) { 952 uint8_t s; 953 if ((*ppsms)->sms_data_order != SMS_DATA_ORDER) 954 sbd_swap_section_hdr(*ppsms); 955 if ((*ppsms)->sms_id != SMS_ID_UNUSED) { 956 s = sbd_calc_section_sum(*ppsms, (*ppsms)->sms_size); 957 if (s != (*ppsms)->sms_chksum) 958 ret = SBD_META_CORRUPTED; 959 } 960 } 961 mutex_exit(&sl->sl_metadata_lock); 962 963 if ((ret != SBD_SUCCESS) && alloced) 964 kmem_free(*ppsms, sms.sms_size); 965 return (ret); 966 } 967 968 sbd_status_t 969 sbd_load_section_hdr_unbuffered(sbd_lu_t *sl, sm_section_hdr_t *sms) 970 { 971 sbd_status_t ret; 972 973 /* 974 * Bypass buffering and re-read the meta data from permanent storage. 975 */ 976 if (sl->sl_flags & SL_ZFS_META) { 977 if ((ret = sbd_open_zfs_meta(sl)) != SBD_SUCCESS) { 978 return (ret); 979 } 980 } 981 /* Re-get the meta sizes into sl */ 982 if ((ret = sbd_load_meta_start(sl)) != SBD_SUCCESS) { 983 return (ret); 984 } 985 return (sbd_load_section_hdr(sl, sms)); 986 } 987 988 sbd_status_t 989 sbd_write_meta_section(sbd_lu_t *sl, sm_section_hdr_t *sms) 990 { 991 sm_section_hdr_t t; 992 uint64_t off, s; 993 uint64_t unused_start; 994 sbd_status_t ret; 995 sbd_status_t write_meta_ret = SBD_SUCCESS; 996 uint8_t *cb; 997 int meta_size_changed = 0; 998 sm_section_hdr_t sms_before_unused = {0}; 999 1000 mutex_enter(&sl->sl_metadata_lock); 1001 write_meta_section_again: 1002 if (sms->sms_offset) { 1003 /* 1004 * If the section already exists and the size is the 1005 * same as this new data then overwrite in place. If 1006 * the sizes are different then mark the existing as 1007 * unused and look for free space. 1008 */ 1009 ret = sbd_read_meta(sl, sms->sms_offset, sizeof (t), 1010 (uint8_t *)&t); 1011 if (ret != SBD_SUCCESS) { 1012 mutex_exit(&sl->sl_metadata_lock); 1013 return (ret); 1014 } 1015 if (t.sms_data_order != SMS_DATA_ORDER) { 1016 sbd_swap_section_hdr(&t); 1017 } 1018 if (t.sms_id != sms->sms_id) { 1019 mutex_exit(&sl->sl_metadata_lock); 1020 return (SBD_INVALID_ARG); 1021 } 1022 if (t.sms_size == sms->sms_size) { 1023 ret = sbd_write_meta(sl, sms->sms_offset, 1024 sms->sms_size, (uint8_t *)sms); 1025 mutex_exit(&sl->sl_metadata_lock); 1026 return (ret); 1027 } 1028 sms_before_unused = t; 1029 1030 t.sms_id = SMS_ID_UNUSED; 1031 /* 1032 * For unused sections we only use chksum of the header. for 1033 * all other sections, the chksum is for the entire section. 1034 */ 1035 t.sms_chksum = sbd_calc_section_sum(&t, sizeof (t)); 1036 ret = sbd_write_meta(sl, t.sms_offset, sizeof (t), 1037 (uint8_t *)&t); 1038 if (ret != SBD_SUCCESS) { 1039 mutex_exit(&sl->sl_metadata_lock); 1040 return (ret); 1041 } 1042 sms->sms_offset = 0; 1043 } else { 1044 /* Section location is unknown, search for it. */ 1045 t.sms_id = sms->sms_id; 1046 t.sms_data_order = SMS_DATA_ORDER; 1047 ret = sbd_load_section_hdr(sl, &t); 1048 if (ret == SBD_SUCCESS) { 1049 sms->sms_offset = t.sms_offset; 1050 sms->sms_chksum = 1051 sbd_calc_section_sum(sms, sms->sms_size); 1052 goto write_meta_section_again; 1053 } else if (ret != SBD_NOT_FOUND) { 1054 mutex_exit(&sl->sl_metadata_lock); 1055 return (ret); 1056 } 1057 } 1058 1059 /* 1060 * At this point we know that section does not already exist. 1061 * Find space large enough to hold the section or grow meta if 1062 * possible. 1063 */ 1064 unused_start = 0; 1065 s = 0; /* size of space found */ 1066 1067 /* 1068 * Search all sections for unused space of sufficient size. 1069 * The first one found is taken. Contiguous unused sections 1070 * will be combined. 1071 */ 1072 for (off = sl->sl_meta_offset + sizeof (sbd_meta_start_t); 1073 off < sl->sl_meta_size_used; off += t.sms_size) { 1074 ret = sbd_read_meta(sl, off, sizeof (t), (uint8_t *)&t); 1075 if (ret != SBD_SUCCESS) { 1076 mutex_exit(&sl->sl_metadata_lock); 1077 return (ret); 1078 } 1079 if (t.sms_data_order != SMS_DATA_ORDER) 1080 sbd_swap_section_hdr(&t); 1081 if (t.sms_size == 0) { 1082 mutex_exit(&sl->sl_metadata_lock); 1083 return (SBD_META_CORRUPTED); 1084 } 1085 if (t.sms_id == SMS_ID_UNUSED) { 1086 if (unused_start == 0) 1087 unused_start = off; 1088 /* 1089 * Calculate size of the unused space, break out 1090 * if it satisfies the requirement. 1091 */ 1092 s = t.sms_size - unused_start + off; 1093 if ((s == sms->sms_size) || (s >= (sms->sms_size + 1094 sizeof (t)))) { 1095 break; 1096 } else { 1097 s = 0; 1098 } 1099 } else { 1100 unused_start = 0; 1101 } 1102 } 1103 1104 off = (unused_start == 0) ? sl->sl_meta_size_used : unused_start; 1105 /* 1106 * If none found, how much room is at the end? 1107 * See if the data can be expanded. 1108 */ 1109 if (s == 0) { 1110 s = sl->sl_total_meta_size - off; 1111 if (s >= sms->sms_size || !(sl->sl_flags & SL_SHARED_META)) { 1112 s = sms->sms_size; 1113 meta_size_changed = 1; 1114 } else { 1115 s = 0; 1116 } 1117 } 1118 1119 if (s == 0) { 1120 mutex_exit(&sl->sl_metadata_lock); 1121 return (SBD_ALLOC_FAILURE); 1122 } 1123 1124 sms->sms_offset = off; 1125 sms->sms_chksum = sbd_calc_section_sum(sms, sms->sms_size); 1126 /* 1127 * Since we may have to write more than one section (current + 1128 * any unused), use a combined buffer. 1129 */ 1130 cb = kmem_zalloc(s, KM_SLEEP); 1131 bcopy(sms, cb, sms->sms_size); 1132 if (s > sms->sms_size) { 1133 t.sms_offset = off + sms->sms_size; 1134 t.sms_size = s - sms->sms_size; 1135 t.sms_id = SMS_ID_UNUSED; 1136 t.sms_data_order = SMS_DATA_ORDER; 1137 t.sms_chksum = sbd_calc_section_sum(&t, sizeof (t)); 1138 bcopy(&t, cb + sms->sms_size, sizeof (t)); 1139 } 1140 /* 1141 * Two write events & statuses take place. Failure writing the 1142 * meta section takes precedence, can possibly be rolled back, 1143 * & gets reported. Else return status from writing the meta start. 1144 */ 1145 ret = SBD_SUCCESS; /* Set a default, it's not always loaded below. */ 1146 if (meta_size_changed) { 1147 uint64_t old_meta_size; 1148 uint64_t old_sz_used = sl->sl_meta_size_used; /* save a copy */ 1149 old_meta_size = sl->sl_total_meta_size; /* save a copy */ 1150 1151 write_meta_ret = sbd_write_meta(sl, off, s, cb); 1152 if (write_meta_ret == SBD_SUCCESS) { 1153 sl->sl_meta_size_used = off + s; 1154 if (sl->sl_total_meta_size < sl->sl_meta_size_used) { 1155 uint64_t meta_align = 1156 (((uint64_t)1) << 1157 sl->sl_meta_blocksize_shift) - 1; 1158 sl->sl_total_meta_size = 1159 (sl->sl_meta_size_used + meta_align) & 1160 (~meta_align); 1161 } 1162 ret = sbd_write_meta_start(sl, sl->sl_total_meta_size, 1163 sl->sl_meta_size_used); 1164 if (ret != SBD_SUCCESS) { 1165 sl->sl_meta_size_used = old_sz_used; 1166 sl->sl_total_meta_size = old_meta_size; 1167 } 1168 } else { 1169 sl->sl_meta_size_used = old_sz_used; 1170 sl->sl_total_meta_size = old_meta_size; 1171 } 1172 } else { 1173 write_meta_ret = sbd_write_meta(sl, off, s, cb); 1174 } 1175 if ((write_meta_ret != SBD_SUCCESS) && 1176 (sms_before_unused.sms_offset != 0)) { 1177 sm_section_hdr_t new_sms; 1178 sm_section_hdr_t *unused_sms; 1179 /* 1180 * On failure writing the meta section attempt to undo 1181 * the change to unused. 1182 * Re-read the meta data from permanent storage. 1183 * The section id can't exist for undo to be possible. 1184 * Read what should be the entire old section data and 1185 * insure the old data's still present by validating 1186 * against it's old checksum. 1187 */ 1188 new_sms.sms_id = sms->sms_id; 1189 new_sms.sms_data_order = SMS_DATA_ORDER; 1190 if (sbd_load_section_hdr_unbuffered(sl, &new_sms) != 1191 SBD_NOT_FOUND) { 1192 goto done; 1193 } 1194 unused_sms = kmem_zalloc(sms_before_unused.sms_size, KM_SLEEP); 1195 if (sbd_read_meta(sl, sms_before_unused.sms_offset, 1196 sms_before_unused.sms_size, 1197 (uint8_t *)unused_sms) != SBD_SUCCESS) { 1198 goto done; 1199 } 1200 if (unused_sms->sms_data_order != SMS_DATA_ORDER) { 1201 sbd_swap_section_hdr(unused_sms); 1202 } 1203 if (unused_sms->sms_id != SMS_ID_UNUSED) { 1204 goto done; 1205 } 1206 if (unused_sms->sms_offset != sms_before_unused.sms_offset) { 1207 goto done; 1208 } 1209 if (unused_sms->sms_size != sms_before_unused.sms_size) { 1210 goto done; 1211 } 1212 unused_sms->sms_id = sms_before_unused.sms_id; 1213 if (sbd_calc_section_sum(unused_sms, 1214 sizeof (sm_section_hdr_t)) != 1215 sbd_calc_section_sum(&sms_before_unused, 1216 sizeof (sm_section_hdr_t))) { 1217 goto done; 1218 } 1219 unused_sms->sms_chksum = 1220 sbd_calc_section_sum(unused_sms, unused_sms->sms_size); 1221 if (unused_sms->sms_chksum != sms_before_unused.sms_chksum) { 1222 goto done; 1223 } 1224 (void) sbd_write_meta(sl, unused_sms->sms_offset, 1225 sizeof (sm_section_hdr_t), (uint8_t *)unused_sms); 1226 } 1227 done: 1228 mutex_exit(&sl->sl_metadata_lock); 1229 kmem_free(cb, s); 1230 if (write_meta_ret != SBD_SUCCESS) { 1231 return (write_meta_ret); 1232 } 1233 return (ret); 1234 } 1235 1236 sbd_status_t 1237 sbd_write_lu_info(sbd_lu_t *sl) 1238 { 1239 sbd_lu_info_1_1_t *sli; 1240 int s; 1241 uint8_t *p; 1242 char *zvol_name = NULL; 1243 sbd_status_t ret; 1244 1245 mutex_enter(&sl->sl_lock); 1246 1247 s = sl->sl_serial_no_size; 1248 if ((sl->sl_flags & (SL_SHARED_META | SL_ZFS_META)) == 0) { 1249 if (sl->sl_data_filename) { 1250 s += strlen(sl->sl_data_filename) + 1; 1251 } 1252 } 1253 if (sl->sl_flags & SL_ZFS_META) { 1254 zvol_name = sbd_get_zvol_name(sl); 1255 s += strlen(zvol_name) + 1; 1256 } 1257 if (sl->sl_alias) { 1258 s += strlen(sl->sl_alias) + 1; 1259 } 1260 if (sl->sl_mgmt_url) { 1261 s += strlen(sl->sl_mgmt_url) + 1; 1262 } 1263 sli = (sbd_lu_info_1_1_t *)kmem_zalloc(sizeof (*sli) + s, KM_SLEEP); 1264 p = sli->sli_buf; 1265 if ((sl->sl_flags & (SL_SHARED_META | SL_ZFS_META)) == 0) { 1266 sli->sli_flags |= SLI_SEPARATE_META; 1267 (void) strcpy((char *)p, sl->sl_data_filename); 1268 sli->sli_data_fname_offset = 1269 (uintptr_t)p - (uintptr_t)sli->sli_buf; 1270 sli->sli_flags |= SLI_DATA_FNAME_VALID; 1271 p += strlen(sl->sl_data_filename) + 1; 1272 } 1273 if (sl->sl_flags & SL_ZFS_META) { 1274 (void) strcpy((char *)p, zvol_name); 1275 sli->sli_meta_fname_offset = 1276 (uintptr_t)p - (uintptr_t)sli->sli_buf; 1277 sli->sli_flags |= SLI_META_FNAME_VALID | SLI_ZFS_META; 1278 p += strlen(zvol_name) + 1; 1279 kmem_free(zvol_name, strlen(zvol_name) + 1); 1280 zvol_name = NULL; 1281 } 1282 if (sl->sl_alias) { 1283 (void) strcpy((char *)p, sl->sl_alias); 1284 sli->sli_alias_offset = 1285 (uintptr_t)p - (uintptr_t)sli->sli_buf; 1286 sli->sli_flags |= SLI_ALIAS_VALID; 1287 p += strlen(sl->sl_alias) + 1; 1288 } 1289 if (sl->sl_mgmt_url) { 1290 (void) strcpy((char *)p, sl->sl_mgmt_url); 1291 sli->sli_mgmt_url_offset = 1292 (uintptr_t)p - (uintptr_t)sli->sli_buf; 1293 sli->sli_flags |= SLI_MGMT_URL_VALID; 1294 p += strlen(sl->sl_mgmt_url) + 1; 1295 } 1296 if (sl->sl_flags & SL_WRITE_PROTECTED) { 1297 sli->sli_flags |= SLI_WRITE_PROTECTED; 1298 } 1299 if (sl->sl_flags & SL_SAVED_WRITE_CACHE_DISABLE) { 1300 sli->sli_flags |= SLI_WRITEBACK_CACHE_DISABLE; 1301 } 1302 if (sl->sl_flags & SL_VID_VALID) { 1303 bcopy(sl->sl_vendor_id, sli->sli_vid, 8); 1304 sli->sli_flags |= SLI_VID_VALID; 1305 } 1306 if (sl->sl_flags & SL_PID_VALID) { 1307 bcopy(sl->sl_product_id, sli->sli_pid, 16); 1308 sli->sli_flags |= SLI_PID_VALID; 1309 } 1310 if (sl->sl_flags & SL_REV_VALID) { 1311 bcopy(sl->sl_revision, sli->sli_rev, 4); 1312 sli->sli_flags |= SLI_REV_VALID; 1313 } 1314 if (sl->sl_serial_no_size) { 1315 bcopy(sl->sl_serial_no, p, sl->sl_serial_no_size); 1316 sli->sli_serial_size = sl->sl_serial_no_size; 1317 sli->sli_serial_offset = 1318 (uintptr_t)p - (uintptr_t)sli->sli_buf; 1319 sli->sli_flags |= SLI_SERIAL_VALID; 1320 p += sli->sli_serial_size; 1321 } 1322 sli->sli_lu_size = sl->sl_lu_size; 1323 sli->sli_data_blocksize_shift = sl->sl_data_blocksize_shift; 1324 sli->sli_data_order = SMS_DATA_ORDER; 1325 bcopy(sl->sl_device_id, sli->sli_device_id, 20); 1326 1327 sli->sli_sms_header.sms_size = sizeof (*sli) + s; 1328 sli->sli_sms_header.sms_id = SMS_ID_LU_INFO_1_1; 1329 sli->sli_sms_header.sms_data_order = SMS_DATA_ORDER; 1330 1331 mutex_exit(&sl->sl_lock); 1332 ret = sbd_write_meta_section(sl, (sm_section_hdr_t *)sli); 1333 kmem_free(sli, sizeof (*sli) + s); 1334 return (ret); 1335 } 1336 1337 int 1338 sbd_populate_and_register_lu(sbd_lu_t *sl, uint32_t *err_ret) 1339 { 1340 stmf_lu_t *lu = sl->sl_lu; 1341 stmf_status_t ret; 1342 1343 lu->lu_id = (scsi_devid_desc_t *)sl->sl_device_id; 1344 if (sl->sl_alias) { 1345 lu->lu_alias = sl->sl_alias; 1346 } else { 1347 lu->lu_alias = sl->sl_name; 1348 } 1349 if (sl->sl_access_state == SBD_LU_STANDBY) { 1350 /* call set access state */ 1351 ret = stmf_set_lu_access(lu, STMF_LU_STANDBY); 1352 if (ret != STMF_SUCCESS) { 1353 *err_ret = SBD_RET_ACCESS_STATE_FAILED; 1354 return (EIO); 1355 } 1356 } 1357 /* set proxy_reg_cb_arg to meta filename */ 1358 if (sl->sl_meta_filename) { 1359 lu->lu_proxy_reg_arg = sl->sl_meta_filename; 1360 lu->lu_proxy_reg_arg_len = strlen(sl->sl_meta_filename) + 1; 1361 } else { 1362 lu->lu_proxy_reg_arg = sl->sl_data_filename; 1363 lu->lu_proxy_reg_arg_len = strlen(sl->sl_data_filename) + 1; 1364 } 1365 lu->lu_lp = sbd_lp; 1366 lu->lu_task_alloc = sbd_task_alloc; 1367 lu->lu_new_task = sbd_new_task; 1368 lu->lu_dbuf_xfer_done = sbd_dbuf_xfer_done; 1369 lu->lu_send_status_done = sbd_send_status_done; 1370 lu->lu_task_free = sbd_task_free; 1371 lu->lu_abort = sbd_abort; 1372 lu->lu_ctl = sbd_ctl; 1373 lu->lu_info = sbd_info; 1374 sl->sl_state = STMF_STATE_OFFLINE; 1375 1376 if ((ret = stmf_register_lu(lu)) != STMF_SUCCESS) { 1377 stmf_trace(0, "Failed to register with framework, ret=%llx", 1378 ret); 1379 if (ret == STMF_ALREADY) { 1380 *err_ret = SBD_RET_GUID_ALREADY_REGISTERED; 1381 } 1382 return (EIO); 1383 } 1384 1385 *err_ret = 0; 1386 return (0); 1387 } 1388 1389 int 1390 sbd_open_data_file(sbd_lu_t *sl, uint32_t *err_ret, int lu_size_valid, 1391 int vp_valid, int keep_open) 1392 { 1393 int ret; 1394 int flag; 1395 ulong_t nbits; 1396 uint64_t supported_size; 1397 vattr_t vattr; 1398 enum vtype vt; 1399 1400 mutex_enter(&sl->sl_lock); 1401 if (vp_valid) { 1402 goto odf_over_open; 1403 } 1404 if (sl->sl_data_filename[0] != '/') { 1405 *err_ret = SBD_RET_DATA_PATH_NOT_ABSOLUTE; 1406 mutex_exit(&sl->sl_lock); 1407 return (EINVAL); 1408 } 1409 if ((ret = lookupname(sl->sl_data_filename, UIO_SYSSPACE, FOLLOW, 1410 NULLVPP, &sl->sl_data_vp)) != 0) { 1411 *err_ret = SBD_RET_DATA_FILE_LOOKUP_FAILED; 1412 mutex_exit(&sl->sl_lock); 1413 return (ret); 1414 } 1415 sl->sl_data_vtype = vt = sl->sl_data_vp->v_type; 1416 VN_RELE(sl->sl_data_vp); 1417 if ((vt != VREG) && (vt != VCHR) && (vt != VBLK)) { 1418 *err_ret = SBD_RET_WRONG_DATA_FILE_TYPE; 1419 mutex_exit(&sl->sl_lock); 1420 return (EINVAL); 1421 } 1422 if (sl->sl_flags & SL_WRITE_PROTECTED) { 1423 flag = FREAD | FOFFMAX; 1424 } else { 1425 flag = FREAD | FWRITE | FOFFMAX | FEXCL; 1426 } 1427 if ((ret = vn_open(sl->sl_data_filename, UIO_SYSSPACE, flag, 0, 1428 &sl->sl_data_vp, 0, 0)) != 0) { 1429 *err_ret = SBD_RET_DATA_FILE_OPEN_FAILED; 1430 mutex_exit(&sl->sl_lock); 1431 return (ret); 1432 } 1433 odf_over_open: 1434 vattr.va_mask = AT_SIZE; 1435 if ((ret = VOP_GETATTR(sl->sl_data_vp, &vattr, 0, CRED(), NULL)) != 0) { 1436 *err_ret = SBD_RET_DATA_FILE_GETATTR_FAILED; 1437 goto odf_close_data_and_exit; 1438 } 1439 if ((vt != VREG) && (vattr.va_size == 0)) { 1440 /* 1441 * Its a zero byte block or char device. This cannot be 1442 * a raw disk. 1443 */ 1444 *err_ret = SBD_RET_WRONG_DATA_FILE_TYPE; 1445 ret = EINVAL; 1446 goto odf_close_data_and_exit; 1447 } 1448 /* sl_data_readable size includes any metadata. */ 1449 sl->sl_data_readable_size = vattr.va_size; 1450 if (VOP_PATHCONF(sl->sl_data_vp, _PC_FILESIZEBITS, &nbits, 1451 CRED(), NULL) != 0) { 1452 nbits = 0; 1453 } 1454 /* nbits cannot be greater than 64 */ 1455 sl->sl_data_fs_nbits = (uint8_t)nbits; 1456 if (lu_size_valid) { 1457 sl->sl_total_data_size = sl->sl_lu_size; 1458 if (sl->sl_flags & SL_SHARED_META) { 1459 sl->sl_total_data_size += SHARED_META_DATA_SIZE; 1460 } 1461 if ((nbits > 0) && (nbits < 64)) { 1462 /* 1463 * The expression below is correct only if nbits is 1464 * positive and less than 64. 1465 */ 1466 supported_size = (((uint64_t)1) << nbits) - 1; 1467 if (sl->sl_total_data_size > supported_size) { 1468 *err_ret = SBD_RET_SIZE_NOT_SUPPORTED_BY_FS; 1469 ret = EINVAL; 1470 goto odf_close_data_and_exit; 1471 } 1472 } 1473 } else { 1474 sl->sl_total_data_size = vattr.va_size; 1475 if (sl->sl_flags & SL_SHARED_META) { 1476 if (vattr.va_size > SHARED_META_DATA_SIZE) { 1477 sl->sl_lu_size = vattr.va_size - 1478 SHARED_META_DATA_SIZE; 1479 } else { 1480 *err_ret = SBD_RET_FILE_SIZE_ERROR; 1481 ret = EINVAL; 1482 goto odf_close_data_and_exit; 1483 } 1484 } else { 1485 sl->sl_lu_size = vattr.va_size; 1486 } 1487 } 1488 if (sl->sl_lu_size < SBD_MIN_LU_SIZE) { 1489 *err_ret = SBD_RET_FILE_SIZE_ERROR; 1490 ret = EINVAL; 1491 goto odf_close_data_and_exit; 1492 } 1493 if (sl->sl_lu_size & 1494 ((((uint64_t)1) << sl->sl_data_blocksize_shift) - 1)) { 1495 *err_ret = SBD_RET_FILE_ALIGN_ERROR; 1496 ret = EINVAL; 1497 goto odf_close_data_and_exit; 1498 } 1499 sl->sl_flags |= SL_MEDIA_LOADED; 1500 mutex_exit(&sl->sl_lock); 1501 return (0); 1502 1503 odf_close_data_and_exit: 1504 if (!keep_open) { 1505 (void) VOP_CLOSE(sl->sl_data_vp, flag, 1, 0, CRED(), NULL); 1506 VN_RELE(sl->sl_data_vp); 1507 } 1508 mutex_exit(&sl->sl_lock); 1509 return (ret); 1510 } 1511 1512 void 1513 sbd_close_lu(sbd_lu_t *sl) 1514 { 1515 int flag; 1516 1517 if (((sl->sl_flags & SL_SHARED_META) == 0) && 1518 (sl->sl_flags & SL_META_OPENED)) { 1519 if (sl->sl_flags & SL_ZFS_META) { 1520 rw_destroy(&sl->sl_zfs_meta_lock); 1521 if (sl->sl_zfs_meta) { 1522 kmem_free(sl->sl_zfs_meta, ZAP_MAXVALUELEN / 2); 1523 sl->sl_zfs_meta = NULL; 1524 } 1525 } else { 1526 flag = FREAD | FWRITE | FOFFMAX | FEXCL; 1527 (void) VOP_CLOSE(sl->sl_meta_vp, flag, 1, 0, 1528 CRED(), NULL); 1529 VN_RELE(sl->sl_meta_vp); 1530 } 1531 sl->sl_flags &= ~SL_META_OPENED; 1532 } 1533 if (sl->sl_flags & SL_MEDIA_LOADED) { 1534 if (sl->sl_flags & SL_WRITE_PROTECTED) { 1535 flag = FREAD | FOFFMAX; 1536 } else { 1537 flag = FREAD | FWRITE | FOFFMAX | FEXCL; 1538 } 1539 (void) VOP_CLOSE(sl->sl_data_vp, flag, 1, 0, CRED(), NULL); 1540 VN_RELE(sl->sl_data_vp); 1541 sl->sl_flags &= ~SL_MEDIA_LOADED; 1542 if (sl->sl_flags & SL_SHARED_META) { 1543 sl->sl_flags &= ~SL_META_OPENED; 1544 } 1545 } 1546 } 1547 1548 int 1549 sbd_set_lu_standby(sbd_set_lu_standby_t *stlu, uint32_t *err_ret) 1550 { 1551 sbd_lu_t *sl; 1552 sbd_status_t sret; 1553 stmf_status_t stret; 1554 1555 sret = sbd_find_and_lock_lu(stlu->stlu_guid, NULL, 1556 SL_OP_MODIFY_LU, &sl); 1557 if (sret != SBD_SUCCESS) { 1558 if (sret == SBD_BUSY) { 1559 *err_ret = SBD_RET_LU_BUSY; 1560 return (EBUSY); 1561 } else if (sret == SBD_NOT_FOUND) { 1562 *err_ret = SBD_RET_NOT_FOUND; 1563 return (ENOENT); 1564 } 1565 *err_ret = SBD_RET_ACCESS_STATE_FAILED; 1566 return (EIO); 1567 } 1568 1569 sl->sl_access_state = SBD_LU_TRANSITION_TO_STANDBY; 1570 stret = stmf_set_lu_access((stmf_lu_t *)sl->sl_lu, STMF_LU_STANDBY); 1571 if (stret != STMF_SUCCESS) { 1572 sl->sl_trans_op = SL_OP_NONE; 1573 *err_ret = SBD_RET_ACCESS_STATE_FAILED; 1574 sl->sl_access_state = SBD_LU_TRANSITION_TO_STANDBY; 1575 return (EIO); 1576 } 1577 1578 /* 1579 * acquire the writer lock here to ensure we're not pulling 1580 * the rug from the vn_rdwr to the backing store 1581 */ 1582 rw_enter(&sl->sl_access_state_lock, RW_WRITER); 1583 sbd_close_lu(sl); 1584 rw_exit(&sl->sl_access_state_lock); 1585 1586 sl->sl_trans_op = SL_OP_NONE; 1587 return (0); 1588 } 1589 1590 int 1591 sbd_close_delete_lu(sbd_lu_t *sl, int ret) 1592 { 1593 1594 /* 1595 * acquire the writer lock here to ensure we're not pulling 1596 * the rug from the vn_rdwr to the backing store 1597 */ 1598 rw_enter(&sl->sl_access_state_lock, RW_WRITER); 1599 sbd_close_lu(sl); 1600 rw_exit(&sl->sl_access_state_lock); 1601 1602 if (sl->sl_flags & SL_LINKED) 1603 sbd_unlink_lu(sl); 1604 mutex_destroy(&sl->sl_metadata_lock); 1605 mutex_destroy(&sl->sl_lock); 1606 rw_destroy(&sl->sl_pgr->pgr_lock); 1607 rw_destroy(&sl->sl_access_state_lock); 1608 if (sl->sl_serial_no_alloc_size) { 1609 kmem_free(sl->sl_serial_no, sl->sl_serial_no_alloc_size); 1610 } 1611 if (sl->sl_data_fname_alloc_size) { 1612 kmem_free(sl->sl_data_filename, sl->sl_data_fname_alloc_size); 1613 } 1614 if (sl->sl_alias_alloc_size) { 1615 kmem_free(sl->sl_alias, sl->sl_alias_alloc_size); 1616 } 1617 if (sl->sl_mgmt_url_alloc_size) { 1618 kmem_free(sl->sl_mgmt_url, sl->sl_mgmt_url_alloc_size); 1619 } 1620 stmf_free(sl->sl_lu); 1621 return (ret); 1622 } 1623 1624 int 1625 sbd_create_register_lu(sbd_create_and_reg_lu_t *slu, int struct_sz, 1626 uint32_t *err_ret) 1627 { 1628 char *namebuf; 1629 sbd_lu_t *sl; 1630 stmf_lu_t *lu; 1631 sbd_status_t sret; 1632 char *p; 1633 int sz; 1634 int alloc_sz; 1635 int ret = EIO; 1636 int flag; 1637 int wcd = 0; 1638 uint32_t hid = 0; 1639 enum vtype vt; 1640 1641 sz = struct_sz - sizeof (sbd_create_and_reg_lu_t) + 8 + 1; 1642 1643 *err_ret = 0; 1644 1645 /* Lets validate various offsets */ 1646 if (((slu->slu_meta_fname_valid) && 1647 (slu->slu_meta_fname_off >= sz)) || 1648 (slu->slu_data_fname_off >= sz) || 1649 ((slu->slu_alias_valid) && 1650 (slu->slu_alias_off >= sz)) || 1651 ((slu->slu_mgmt_url_valid) && 1652 (slu->slu_mgmt_url_off >= sz)) || 1653 ((slu->slu_serial_valid) && 1654 ((slu->slu_serial_off + slu->slu_serial_size) >= sz))) { 1655 return (EINVAL); 1656 } 1657 1658 namebuf = kmem_zalloc(sz, KM_SLEEP); 1659 bcopy(slu->slu_buf, namebuf, sz - 1); 1660 namebuf[sz - 1] = 0; 1661 1662 alloc_sz = sizeof (sbd_lu_t) + sizeof (sbd_pgr_t); 1663 if (slu->slu_meta_fname_valid) { 1664 alloc_sz += strlen(namebuf + slu->slu_meta_fname_off) + 1; 1665 } 1666 alloc_sz += strlen(namebuf + slu->slu_data_fname_off) + 1; 1667 if (slu->slu_alias_valid) { 1668 alloc_sz += strlen(namebuf + slu->slu_alias_off) + 1; 1669 } 1670 if (slu->slu_mgmt_url_valid) { 1671 alloc_sz += strlen(namebuf + slu->slu_mgmt_url_off) + 1; 1672 } 1673 if (slu->slu_serial_valid) { 1674 alloc_sz += slu->slu_serial_size; 1675 } 1676 1677 lu = (stmf_lu_t *)stmf_alloc(STMF_STRUCT_STMF_LU, alloc_sz, 0); 1678 if (lu == NULL) { 1679 kmem_free(namebuf, sz); 1680 return (ENOMEM); 1681 } 1682 sl = (sbd_lu_t *)lu->lu_provider_private; 1683 bzero(sl, alloc_sz); 1684 sl->sl_lu = lu; 1685 sl->sl_alloc_size = alloc_sz; 1686 sl->sl_pgr = (sbd_pgr_t *)(sl + 1); 1687 rw_init(&sl->sl_pgr->pgr_lock, NULL, RW_DRIVER, NULL); 1688 mutex_init(&sl->sl_lock, NULL, MUTEX_DRIVER, NULL); 1689 mutex_init(&sl->sl_metadata_lock, NULL, MUTEX_DRIVER, NULL); 1690 rw_init(&sl->sl_access_state_lock, NULL, RW_DRIVER, NULL); 1691 p = ((char *)sl) + sizeof (sbd_lu_t) + sizeof (sbd_pgr_t); 1692 sl->sl_data_filename = p; 1693 (void) strcpy(sl->sl_data_filename, namebuf + slu->slu_data_fname_off); 1694 p += strlen(sl->sl_data_filename) + 1; 1695 sl->sl_meta_offset = SBD_META_OFFSET; 1696 sl->sl_access_state = SBD_LU_ACTIVE; 1697 if (slu->slu_meta_fname_valid) { 1698 sl->sl_alias = sl->sl_name = sl->sl_meta_filename = p; 1699 (void) strcpy(sl->sl_meta_filename, namebuf + 1700 slu->slu_meta_fname_off); 1701 p += strlen(sl->sl_meta_filename) + 1; 1702 } else { 1703 sl->sl_alias = sl->sl_name = sl->sl_data_filename; 1704 if (sbd_is_zvol(sl->sl_data_filename)) { 1705 sl->sl_flags |= SL_ZFS_META; 1706 sl->sl_meta_offset = 0; 1707 } else { 1708 sl->sl_flags |= SL_SHARED_META; 1709 sl->sl_data_offset = SHARED_META_DATA_SIZE; 1710 sl->sl_total_meta_size = SHARED_META_DATA_SIZE; 1711 sl->sl_meta_size_used = 0; 1712 } 1713 } 1714 if (slu->slu_alias_valid) { 1715 sl->sl_alias = p; 1716 (void) strcpy(p, namebuf + slu->slu_alias_off); 1717 p += strlen(sl->sl_alias) + 1; 1718 } 1719 if (slu->slu_mgmt_url_valid) { 1720 sl->sl_mgmt_url = p; 1721 (void) strcpy(p, namebuf + slu->slu_mgmt_url_off); 1722 p += strlen(sl->sl_mgmt_url) + 1; 1723 } 1724 if (slu->slu_serial_valid) { 1725 sl->sl_serial_no = (uint8_t *)p; 1726 bcopy(namebuf + slu->slu_serial_off, sl->sl_serial_no, 1727 slu->slu_serial_size); 1728 sl->sl_serial_no_size = slu->slu_serial_size; 1729 p += slu->slu_serial_size; 1730 } 1731 kmem_free(namebuf, sz); 1732 if (slu->slu_vid_valid) { 1733 bcopy(slu->slu_vid, sl->sl_vendor_id, 8); 1734 sl->sl_flags |= SL_VID_VALID; 1735 } 1736 if (slu->slu_pid_valid) { 1737 bcopy(slu->slu_pid, sl->sl_product_id, 16); 1738 sl->sl_flags |= SL_PID_VALID; 1739 } 1740 if (slu->slu_rev_valid) { 1741 bcopy(slu->slu_rev, sl->sl_revision, 4); 1742 sl->sl_flags |= SL_REV_VALID; 1743 } 1744 if (slu->slu_write_protected) { 1745 sl->sl_flags |= SL_WRITE_PROTECTED; 1746 } 1747 if (slu->slu_writeback_cache_disable) { 1748 sl->sl_flags |= SL_WRITEBACK_CACHE_DISABLE | 1749 SL_SAVED_WRITE_CACHE_DISABLE; 1750 } 1751 1752 if (slu->slu_blksize_valid) { 1753 if ((slu->slu_blksize & (slu->slu_blksize - 1)) || 1754 (slu->slu_blksize > (32 * 1024)) || 1755 (slu->slu_blksize == 0)) { 1756 *err_ret = SBD_RET_INVALID_BLKSIZE; 1757 ret = EINVAL; 1758 goto scm_err_out; 1759 } 1760 while ((1 << sl->sl_data_blocksize_shift) != slu->slu_blksize) { 1761 sl->sl_data_blocksize_shift++; 1762 } 1763 } else { 1764 sl->sl_data_blocksize_shift = 9; /* 512 by default */ 1765 slu->slu_blksize = 512; 1766 } 1767 1768 /* Now lets start creating meta */ 1769 sl->sl_trans_op = SL_OP_CREATE_REGISTER_LU; 1770 if (sbd_link_lu(sl) != SBD_SUCCESS) { 1771 *err_ret = SBD_RET_FILE_ALREADY_REGISTERED; 1772 ret = EALREADY; 1773 goto scm_err_out; 1774 } 1775 1776 /* 1st focus on the data store */ 1777 if (slu->slu_lu_size_valid) { 1778 sl->sl_lu_size = slu->slu_lu_size; 1779 } 1780 ret = sbd_open_data_file(sl, err_ret, slu->slu_lu_size_valid, 0, 0); 1781 slu->slu_ret_filesize_nbits = sl->sl_data_fs_nbits; 1782 slu->slu_lu_size = sl->sl_lu_size; 1783 if (ret) { 1784 goto scm_err_out; 1785 } 1786 1787 /* 1788 * set write cache disable on the device 1789 * if it fails, we'll support it using sync/flush 1790 */ 1791 if (slu->slu_writeback_cache_disable) { 1792 (void) sbd_wcd_set(1, sl); 1793 wcd = 1; 1794 /* 1795 * Attempt to set it to enable, if that fails and it was explicitly set 1796 * return an error, otherwise get the current setting and use that 1797 */ 1798 } else { 1799 sret = sbd_wcd_set(0, sl); 1800 if (slu->slu_writeback_cache_disable_valid && 1801 sret != SBD_SUCCESS) { 1802 *err_ret = SBD_RET_WRITE_CACHE_SET_FAILED; 1803 ret = EFAULT; 1804 goto scm_err_out; 1805 } 1806 if (sret != SBD_SUCCESS) { 1807 sbd_wcd_get(&wcd, sl); 1808 } 1809 } 1810 1811 if (wcd) { 1812 sl->sl_flags |= SL_WRITEBACK_CACHE_DISABLE | 1813 SL_SAVED_WRITE_CACHE_DISABLE; 1814 } 1815 1816 if (sl->sl_flags & SL_SHARED_META) { 1817 goto over_meta_open; 1818 } 1819 if (sl->sl_flags & SL_ZFS_META) { 1820 if (sbd_create_zfs_meta_object(sl) != SBD_SUCCESS) { 1821 *err_ret = SBD_RET_ZFS_META_CREATE_FAILED; 1822 ret = ENOMEM; 1823 goto scm_err_out; 1824 } 1825 sl->sl_meta_blocksize_shift = 0; 1826 goto over_meta_create; 1827 } 1828 if ((ret = lookupname(sl->sl_meta_filename, UIO_SYSSPACE, FOLLOW, 1829 NULLVPP, &sl->sl_meta_vp)) != 0) { 1830 *err_ret = SBD_RET_META_FILE_LOOKUP_FAILED; 1831 goto scm_err_out; 1832 } 1833 sl->sl_meta_vtype = vt = sl->sl_meta_vp->v_type; 1834 VN_RELE(sl->sl_meta_vp); 1835 if ((vt != VREG) && (vt != VCHR) && (vt != VBLK)) { 1836 *err_ret = SBD_RET_WRONG_META_FILE_TYPE; 1837 ret = EINVAL; 1838 goto scm_err_out; 1839 } 1840 if (vt == VREG) { 1841 sl->sl_meta_blocksize_shift = 0; 1842 } else { 1843 sl->sl_meta_blocksize_shift = 9; 1844 } 1845 flag = FREAD | FWRITE | FOFFMAX | FEXCL; 1846 if ((ret = vn_open(sl->sl_meta_filename, UIO_SYSSPACE, flag, 0, 1847 &sl->sl_meta_vp, 0, 0)) != 0) { 1848 *err_ret = SBD_RET_META_FILE_OPEN_FAILED; 1849 goto scm_err_out; 1850 } 1851 over_meta_create: 1852 sl->sl_total_meta_size = sl->sl_meta_offset + sizeof (sbd_meta_start_t); 1853 sl->sl_total_meta_size += 1854 (((uint64_t)1) << sl->sl_meta_blocksize_shift) - 1; 1855 sl->sl_total_meta_size &= 1856 ~((((uint64_t)1) << sl->sl_meta_blocksize_shift) - 1); 1857 sl->sl_meta_size_used = 0; 1858 over_meta_open: 1859 sl->sl_flags |= SL_META_OPENED; 1860 1861 sl->sl_device_id[3] = 16; 1862 if (slu->slu_guid_valid) { 1863 sl->sl_device_id[0] = 0xf1; 1864 sl->sl_device_id[1] = 3; 1865 sl->sl_device_id[2] = 0; 1866 bcopy(slu->slu_guid, sl->sl_device_id + 4, 16); 1867 } else { 1868 if (slu->slu_host_id_valid) 1869 hid = slu->slu_host_id; 1870 if (!slu->slu_company_id_valid) 1871 slu->slu_company_id = COMPANY_ID_SUN; 1872 if (stmf_scsilib_uniq_lu_id2(slu->slu_company_id, hid, 1873 (scsi_devid_desc_t *)&sl->sl_device_id[0]) != 1874 STMF_SUCCESS) { 1875 *err_ret = SBD_RET_META_CREATION_FAILED; 1876 ret = EIO; 1877 goto scm_err_out; 1878 } 1879 bcopy(sl->sl_device_id + 4, slu->slu_guid, 16); 1880 } 1881 1882 /* Lets create the meta now */ 1883 mutex_enter(&sl->sl_metadata_lock); 1884 if (sbd_write_meta_start(sl, sl->sl_total_meta_size, 1885 sizeof (sbd_meta_start_t)) != SBD_SUCCESS) { 1886 mutex_exit(&sl->sl_metadata_lock); 1887 *err_ret = SBD_RET_META_CREATION_FAILED; 1888 ret = EIO; 1889 goto scm_err_out; 1890 } 1891 mutex_exit(&sl->sl_metadata_lock); 1892 sl->sl_meta_size_used = sl->sl_meta_offset + sizeof (sbd_meta_start_t); 1893 1894 if (sbd_write_lu_info(sl) != SBD_SUCCESS) { 1895 *err_ret = SBD_RET_META_CREATION_FAILED; 1896 ret = EIO; 1897 goto scm_err_out; 1898 } 1899 1900 if (sbd_pgr_meta_init(sl) != SBD_SUCCESS) { 1901 *err_ret = SBD_RET_META_CREATION_FAILED; 1902 ret = EIO; 1903 goto scm_err_out; 1904 } 1905 1906 ret = sbd_populate_and_register_lu(sl, err_ret); 1907 if (ret) { 1908 goto scm_err_out; 1909 } 1910 1911 sl->sl_trans_op = SL_OP_NONE; 1912 atomic_add_32(&sbd_lu_count, 1); 1913 return (0); 1914 1915 scm_err_out: 1916 return (sbd_close_delete_lu(sl, ret)); 1917 } 1918 1919 stmf_status_t 1920 sbd_proxy_msg(uint8_t *luid, void *proxy_arg, uint32_t proxy_arg_len, 1921 uint32_t type) 1922 { 1923 switch (type) { 1924 case STMF_MSG_LU_ACTIVE: 1925 return (sbd_proxy_reg_lu(luid, proxy_arg, 1926 proxy_arg_len)); 1927 case STMF_MSG_LU_REGISTER: 1928 return (sbd_proxy_reg_lu(luid, proxy_arg, 1929 proxy_arg_len)); 1930 case STMF_MSG_LU_DEREGISTER: 1931 return (sbd_proxy_dereg_lu(luid, proxy_arg, 1932 proxy_arg_len)); 1933 default: 1934 return (STMF_INVALID_ARG); 1935 } 1936 } 1937 1938 1939 /* 1940 * register a standby logical unit 1941 * proxy_reg_arg contains the meta filename 1942 */ 1943 stmf_status_t 1944 sbd_proxy_reg_lu(uint8_t *luid, void *proxy_reg_arg, uint32_t proxy_reg_arg_len) 1945 { 1946 sbd_lu_t *sl; 1947 sbd_status_t sret; 1948 sbd_create_standby_lu_t *stlu; 1949 int alloc_sz; 1950 uint32_t err_ret = 0; 1951 stmf_status_t stret = STMF_SUCCESS; 1952 1953 if (luid == NULL) { 1954 return (STMF_INVALID_ARG); 1955 } 1956 1957 do { 1958 sret = sbd_find_and_lock_lu(luid, NULL, SL_OP_MODIFY_LU, &sl); 1959 } while (sret == SBD_BUSY); 1960 1961 if (sret == SBD_NOT_FOUND) { 1962 alloc_sz = sizeof (*stlu) + proxy_reg_arg_len - 8; 1963 stlu = (sbd_create_standby_lu_t *)kmem_zalloc(alloc_sz, 1964 KM_SLEEP); 1965 bcopy(luid, stlu->stlu_guid, 16); 1966 if (proxy_reg_arg_len) { 1967 bcopy(proxy_reg_arg, stlu->stlu_meta_fname, 1968 proxy_reg_arg_len); 1969 stlu->stlu_meta_fname_size = proxy_reg_arg_len; 1970 } 1971 if (sbd_create_standby_lu(stlu, &err_ret) != 0) { 1972 cmn_err(CE_WARN, 1973 "Unable to create standby logical unit for %s", 1974 stlu->stlu_meta_fname); 1975 stret = STMF_FAILURE; 1976 } 1977 kmem_free(stlu, alloc_sz); 1978 return (stret); 1979 } else if (sret == SBD_SUCCESS) { 1980 /* 1981 * if the lu is already registered, then the lu should now 1982 * be in standby mode 1983 */ 1984 sbd_it_data_t *it; 1985 if (sl->sl_access_state != SBD_LU_STANDBY) { 1986 mutex_enter(&sl->sl_lock); 1987 sl->sl_access_state = SBD_LU_STANDBY; 1988 for (it = sl->sl_it_list; it != NULL; 1989 it = it->sbd_it_next) { 1990 it->sbd_it_ua_conditions |= 1991 SBD_UA_ASYMMETRIC_ACCESS_CHANGED; 1992 it->sbd_it_flags &= 1993 ~SBD_IT_HAS_SCSI2_RESERVATION; 1994 sl->sl_flags &= ~SL_LU_HAS_SCSI2_RESERVATION; 1995 } 1996 mutex_exit(&sl->sl_lock); 1997 sbd_pgr_reset(sl); 1998 } 1999 sl->sl_trans_op = SL_OP_NONE; 2000 } else { 2001 cmn_err(CE_WARN, "could not find and lock logical unit"); 2002 stret = STMF_FAILURE; 2003 } 2004 out: 2005 return (stret); 2006 } 2007 2008 /* ARGSUSED */ 2009 stmf_status_t 2010 sbd_proxy_dereg_lu(uint8_t *luid, void *proxy_reg_arg, 2011 uint32_t proxy_reg_arg_len) 2012 { 2013 sbd_delete_lu_t dlu = {0}; 2014 uint32_t err_ret; 2015 2016 if (luid == NULL) { 2017 cmn_err(CE_WARN, "de-register lu request had null luid"); 2018 return (STMF_INVALID_ARG); 2019 } 2020 2021 bcopy(luid, &dlu.dlu_guid, 16); 2022 2023 if (sbd_delete_lu(&dlu, (int)sizeof (dlu), &err_ret) != 0) { 2024 cmn_err(CE_WARN, "failed to delete de-register lu request"); 2025 return (STMF_FAILURE); 2026 } 2027 2028 return (STMF_SUCCESS); 2029 } 2030 2031 int 2032 sbd_create_standby_lu(sbd_create_standby_lu_t *slu, uint32_t *err_ret) 2033 { 2034 sbd_lu_t *sl; 2035 stmf_lu_t *lu; 2036 int ret = EIO; 2037 int alloc_sz; 2038 2039 alloc_sz = sizeof (sbd_lu_t) + sizeof (sbd_pgr_t) + 2040 slu->stlu_meta_fname_size; 2041 lu = (stmf_lu_t *)stmf_alloc(STMF_STRUCT_STMF_LU, alloc_sz, 0); 2042 if (lu == NULL) { 2043 return (ENOMEM); 2044 } 2045 sl = (sbd_lu_t *)lu->lu_provider_private; 2046 bzero(sl, alloc_sz); 2047 sl->sl_lu = lu; 2048 sl->sl_alloc_size = alloc_sz; 2049 2050 sl->sl_pgr = (sbd_pgr_t *)(sl + 1); 2051 sl->sl_meta_filename = ((char *)sl) + sizeof (sbd_lu_t) + 2052 sizeof (sbd_pgr_t); 2053 2054 if (slu->stlu_meta_fname_size > 0) { 2055 (void) strcpy(sl->sl_meta_filename, slu->stlu_meta_fname); 2056 } 2057 sl->sl_name = sl->sl_meta_filename; 2058 2059 sl->sl_device_id[3] = 16; 2060 sl->sl_device_id[0] = 0xf1; 2061 sl->sl_device_id[1] = 3; 2062 sl->sl_device_id[2] = 0; 2063 bcopy(slu->stlu_guid, sl->sl_device_id + 4, 16); 2064 lu->lu_id = (scsi_devid_desc_t *)sl->sl_device_id; 2065 sl->sl_access_state = SBD_LU_STANDBY; 2066 2067 rw_init(&sl->sl_pgr->pgr_lock, NULL, RW_DRIVER, NULL); 2068 mutex_init(&sl->sl_lock, NULL, MUTEX_DRIVER, NULL); 2069 mutex_init(&sl->sl_metadata_lock, NULL, MUTEX_DRIVER, NULL); 2070 rw_init(&sl->sl_access_state_lock, NULL, RW_DRIVER, NULL); 2071 2072 sl->sl_trans_op = SL_OP_CREATE_REGISTER_LU; 2073 2074 if (sbd_link_lu(sl) != SBD_SUCCESS) { 2075 *err_ret = SBD_RET_FILE_ALREADY_REGISTERED; 2076 ret = EALREADY; 2077 goto scs_err_out; 2078 } 2079 2080 ret = sbd_populate_and_register_lu(sl, err_ret); 2081 if (ret) { 2082 goto scs_err_out; 2083 } 2084 2085 sl->sl_trans_op = SL_OP_NONE; 2086 atomic_add_32(&sbd_lu_count, 1); 2087 return (0); 2088 2089 scs_err_out: 2090 return (sbd_close_delete_lu(sl, ret)); 2091 } 2092 2093 int 2094 sbd_load_sli_1_0(sbd_lu_t *sl, uint32_t *err_ret) 2095 { 2096 sbd_lu_info_1_0_t *sli = NULL; 2097 sbd_status_t sret; 2098 2099 sret = sbd_read_meta_section(sl, (sm_section_hdr_t **)&sli, 2100 SMS_ID_LU_INFO_1_0); 2101 2102 if (sret != SBD_SUCCESS) { 2103 *err_ret = SBD_RET_NO_META; 2104 return (EIO); 2105 } 2106 if (sli->sli_data_order != SMS_DATA_ORDER) { 2107 sbd_swap_lu_info_1_0(sli); 2108 if (sli->sli_data_order != SMS_DATA_ORDER) { 2109 kmem_free(sli, sli->sli_sms_header.sms_size); 2110 *err_ret = SBD_RET_NO_META; 2111 return (EIO); 2112 } 2113 } 2114 2115 sl->sl_flags |= SL_SHARED_META; 2116 sl->sl_data_blocksize_shift = 9; 2117 sl->sl_data_offset = SHARED_META_DATA_SIZE; 2118 sl->sl_lu_size = sli->sli_total_store_size - SHARED_META_DATA_SIZE; 2119 sl->sl_total_data_size = SHARED_META_DATA_SIZE + sl->sl_lu_size; 2120 bcopy(sli->sli_lu_devid, sl->sl_device_id, 20); 2121 2122 kmem_free(sli, sli->sli_sms_header.sms_size); 2123 return (0); 2124 } 2125 2126 int 2127 sbd_import_lu(sbd_import_lu_t *ilu, int struct_sz, uint32_t *err_ret, 2128 int no_register, sbd_lu_t **slr) 2129 { 2130 stmf_lu_t *lu; 2131 sbd_lu_t *sl; 2132 sbd_lu_info_1_1_t *sli = NULL; 2133 int asz; 2134 int ret = 0; 2135 stmf_status_t stret; 2136 int flag; 2137 int wcd = 0; 2138 int data_opened; 2139 uint16_t sli_buf_sz; 2140 uint8_t *sli_buf_copy = NULL; 2141 enum vtype vt; 2142 int standby = 0; 2143 sbd_status_t sret; 2144 2145 if (no_register && slr == NULL) { 2146 return (EINVAL); 2147 } 2148 ilu->ilu_meta_fname[struct_sz - sizeof (*ilu) + 8 - 1] = 0; 2149 /* 2150 * check whether logical unit is already registered ALUA 2151 * For a standby logical unit, the meta filename is set. Use 2152 * that to search for an existing logical unit. 2153 */ 2154 sret = sbd_find_and_lock_lu(NULL, (uint8_t *)&(ilu->ilu_meta_fname), 2155 SL_OP_IMPORT_LU, &sl); 2156 2157 if (sret == SBD_SUCCESS) { 2158 if (sl->sl_access_state != SBD_LU_ACTIVE) { 2159 no_register = 1; 2160 standby = 1; 2161 lu = sl->sl_lu; 2162 if (sl->sl_alias_alloc_size) { 2163 kmem_free(sl->sl_alias, 2164 sl->sl_alias_alloc_size); 2165 sl->sl_alias_alloc_size = 0; 2166 sl->sl_alias = NULL; 2167 lu->lu_alias = NULL; 2168 } 2169 if (sl->sl_meta_filename == NULL) { 2170 sl->sl_meta_filename = sl->sl_data_filename; 2171 } else if (sl->sl_data_fname_alloc_size) { 2172 kmem_free(sl->sl_data_filename, 2173 sl->sl_data_fname_alloc_size); 2174 sl->sl_data_fname_alloc_size = 0; 2175 } 2176 if (sl->sl_serial_no_alloc_size) { 2177 kmem_free(sl->sl_serial_no, 2178 sl->sl_serial_no_alloc_size); 2179 sl->sl_serial_no_alloc_size = 0; 2180 } 2181 if (sl->sl_mgmt_url_alloc_size) { 2182 kmem_free(sl->sl_mgmt_url, 2183 sl->sl_mgmt_url_alloc_size); 2184 sl->sl_mgmt_url_alloc_size = 0; 2185 } 2186 } else { 2187 *err_ret = SBD_RET_FILE_ALREADY_REGISTERED; 2188 sl->sl_trans_op = SL_OP_NONE; 2189 return (EALREADY); 2190 } 2191 } else if (sret == SBD_NOT_FOUND) { 2192 asz = strlen(ilu->ilu_meta_fname) + 1; 2193 2194 lu = (stmf_lu_t *)stmf_alloc(STMF_STRUCT_STMF_LU, 2195 sizeof (sbd_lu_t) + sizeof (sbd_pgr_t) + asz, 0); 2196 if (lu == NULL) { 2197 return (ENOMEM); 2198 } 2199 sl = (sbd_lu_t *)lu->lu_provider_private; 2200 bzero(sl, sizeof (*sl)); 2201 sl->sl_lu = lu; 2202 sl->sl_pgr = (sbd_pgr_t *)(sl + 1); 2203 sl->sl_meta_filename = ((char *)sl) + sizeof (*sl) + 2204 sizeof (sbd_pgr_t); 2205 (void) strcpy(sl->sl_meta_filename, ilu->ilu_meta_fname); 2206 sl->sl_name = sl->sl_meta_filename; 2207 rw_init(&sl->sl_pgr->pgr_lock, NULL, RW_DRIVER, NULL); 2208 rw_init(&sl->sl_access_state_lock, NULL, RW_DRIVER, NULL); 2209 mutex_init(&sl->sl_lock, NULL, MUTEX_DRIVER, NULL); 2210 mutex_init(&sl->sl_metadata_lock, NULL, MUTEX_DRIVER, NULL); 2211 sl->sl_trans_op = SL_OP_IMPORT_LU; 2212 } else { 2213 *err_ret = SBD_RET_META_FILE_LOOKUP_FAILED; 2214 return (EIO); 2215 } 2216 2217 /* we're only loading the metadata */ 2218 if (!no_register) { 2219 if (sbd_link_lu(sl) != SBD_SUCCESS) { 2220 *err_ret = SBD_RET_FILE_ALREADY_REGISTERED; 2221 ret = EALREADY; 2222 goto sim_err_out; 2223 } 2224 } 2225 if ((ret = lookupname(sl->sl_meta_filename, UIO_SYSSPACE, FOLLOW, 2226 NULLVPP, &sl->sl_meta_vp)) != 0) { 2227 *err_ret = SBD_RET_META_FILE_LOOKUP_FAILED; 2228 goto sim_err_out; 2229 } 2230 if (sbd_is_zvol(sl->sl_meta_filename)) { 2231 sl->sl_flags |= SL_ZFS_META; 2232 sl->sl_data_filename = sl->sl_meta_filename; 2233 } 2234 sl->sl_meta_vtype = vt = sl->sl_meta_vp->v_type; 2235 VN_RELE(sl->sl_meta_vp); 2236 if ((vt != VREG) && (vt != VCHR) && (vt != VBLK)) { 2237 *err_ret = SBD_RET_WRONG_META_FILE_TYPE; 2238 ret = EINVAL; 2239 goto sim_err_out; 2240 } 2241 if (sl->sl_flags & SL_ZFS_META) { 2242 if (sbd_open_zfs_meta(sl) != SBD_SUCCESS) { 2243 /* let see if metadata is in the 64k block */ 2244 sl->sl_flags &= ~SL_ZFS_META; 2245 } 2246 } 2247 if (!(sl->sl_flags & SL_ZFS_META)) { 2248 /* metadata is always writable */ 2249 flag = FREAD | FWRITE | FOFFMAX | FEXCL; 2250 if ((ret = vn_open(sl->sl_meta_filename, UIO_SYSSPACE, flag, 0, 2251 &sl->sl_meta_vp, 0, 0)) != 0) { 2252 *err_ret = SBD_RET_META_FILE_OPEN_FAILED; 2253 goto sim_err_out; 2254 } 2255 } 2256 if ((sl->sl_flags & SL_ZFS_META) || (vt == VREG)) { 2257 sl->sl_meta_blocksize_shift = 0; 2258 } else { 2259 sl->sl_meta_blocksize_shift = 9; 2260 } 2261 sl->sl_meta_offset = (sl->sl_flags & SL_ZFS_META) ? 0 : SBD_META_OFFSET; 2262 sl->sl_flags |= SL_META_OPENED; 2263 2264 mutex_enter(&sl->sl_metadata_lock); 2265 sret = sbd_load_meta_start(sl); 2266 mutex_exit(&sl->sl_metadata_lock); 2267 if (sret != SBD_SUCCESS) { 2268 if (sret == SBD_META_CORRUPTED) { 2269 *err_ret = SBD_RET_NO_META; 2270 } else if (sret == SBD_NOT_SUPPORTED) { 2271 *err_ret = SBD_RET_VERSION_NOT_SUPPORTED; 2272 } else { 2273 *err_ret = SBD_RET_NO_META; 2274 } 2275 ret = EINVAL; 2276 goto sim_err_out; 2277 } 2278 2279 /* Now lets see if we can read the most recent LU info */ 2280 sret = sbd_read_meta_section(sl, (sm_section_hdr_t **)&sli, 2281 SMS_ID_LU_INFO_1_1); 2282 if ((sret == SBD_NOT_FOUND) && ((sl->sl_flags & SL_ZFS_META) == 0)) { 2283 ret = sbd_load_sli_1_0(sl, err_ret); 2284 if (ret) { 2285 goto sim_err_out; 2286 } 2287 goto sim_sli_loaded; 2288 } 2289 if (sret != SBD_SUCCESS) { 2290 *err_ret = SBD_RET_NO_META; 2291 ret = EIO; 2292 goto sim_err_out; 2293 } 2294 /* load sli 1.1 */ 2295 if (sli->sli_data_order != SMS_DATA_ORDER) { 2296 sbd_swap_lu_info_1_1(sli); 2297 if (sli->sli_data_order != SMS_DATA_ORDER) { 2298 *err_ret = SBD_RET_NO_META; 2299 ret = EIO; 2300 goto sim_err_out; 2301 } 2302 } 2303 2304 sli_buf_sz = sli->sli_sms_header.sms_size - 2305 sizeof (sbd_lu_info_1_1_t) + 8; 2306 sli_buf_copy = kmem_alloc(sli_buf_sz + 1, KM_SLEEP); 2307 bcopy(sli->sli_buf, sli_buf_copy, sli_buf_sz); 2308 sli_buf_copy[sli_buf_sz] = 0; 2309 2310 /* Make sure all the offsets are within limits */ 2311 if (((sli->sli_flags & SLI_META_FNAME_VALID) && 2312 (sli->sli_meta_fname_offset > sli_buf_sz)) || 2313 ((sli->sli_flags & SLI_DATA_FNAME_VALID) && 2314 (sli->sli_data_fname_offset > sli_buf_sz)) || 2315 ((sli->sli_flags & SLI_MGMT_URL_VALID) && 2316 (sli->sli_mgmt_url_offset > sli_buf_sz)) || 2317 ((sli->sli_flags & SLI_SERIAL_VALID) && 2318 ((sli->sli_serial_offset + sli->sli_serial_size) > sli_buf_sz)) || 2319 ((sli->sli_flags & SLI_ALIAS_VALID) && 2320 (sli->sli_alias_offset > sli_buf_sz))) { 2321 *err_ret = SBD_RET_NO_META; 2322 ret = EIO; 2323 goto sim_err_out; 2324 } 2325 2326 sl->sl_lu_size = sli->sli_lu_size; 2327 sl->sl_data_blocksize_shift = sli->sli_data_blocksize_shift; 2328 bcopy(sli->sli_device_id, sl->sl_device_id, 20); 2329 if (sli->sli_flags & SLI_SERIAL_VALID) { 2330 sl->sl_serial_no_size = sl->sl_serial_no_alloc_size = 2331 sli->sli_serial_size; 2332 sl->sl_serial_no = kmem_zalloc(sli->sli_serial_size, KM_SLEEP); 2333 bcopy(sli_buf_copy + sli->sli_serial_offset, sl->sl_serial_no, 2334 sl->sl_serial_no_size); 2335 } 2336 if (sli->sli_flags & SLI_SEPARATE_META) { 2337 sl->sl_total_data_size = sl->sl_lu_size; 2338 if (sli->sli_flags & SLI_DATA_FNAME_VALID) { 2339 sl->sl_data_fname_alloc_size = strlen((char *) 2340 sli_buf_copy + sli->sli_data_fname_offset) + 1; 2341 sl->sl_data_filename = kmem_zalloc( 2342 sl->sl_data_fname_alloc_size, KM_SLEEP); 2343 (void) strcpy(sl->sl_data_filename, 2344 (char *)sli_buf_copy + sli->sli_data_fname_offset); 2345 } 2346 } else { 2347 if (sl->sl_flags & SL_ZFS_META) { 2348 sl->sl_total_data_size = sl->sl_lu_size; 2349 sl->sl_data_offset = 0; 2350 } else { 2351 sl->sl_total_data_size = 2352 sl->sl_lu_size + SHARED_META_DATA_SIZE; 2353 sl->sl_data_offset = SHARED_META_DATA_SIZE; 2354 sl->sl_flags |= SL_SHARED_META; 2355 } 2356 } 2357 if (sli->sli_flags & SLI_ALIAS_VALID) { 2358 sl->sl_alias_alloc_size = strlen((char *)sli_buf_copy + 2359 sli->sli_alias_offset) + 1; 2360 sl->sl_alias = kmem_alloc(sl->sl_alias_alloc_size, KM_SLEEP); 2361 (void) strcpy(sl->sl_alias, (char *)sli_buf_copy + 2362 sli->sli_alias_offset); 2363 } 2364 if (sli->sli_flags & SLI_MGMT_URL_VALID) { 2365 sl->sl_mgmt_url_alloc_size = strlen((char *)sli_buf_copy + 2366 sli->sli_mgmt_url_offset) + 1; 2367 sl->sl_mgmt_url = kmem_alloc(sl->sl_mgmt_url_alloc_size, 2368 KM_SLEEP); 2369 (void) strcpy(sl->sl_mgmt_url, (char *)sli_buf_copy + 2370 sli->sli_mgmt_url_offset); 2371 } 2372 if (sli->sli_flags & SLI_WRITE_PROTECTED) { 2373 sl->sl_flags |= SL_WRITE_PROTECTED; 2374 } 2375 if (sli->sli_flags & SLI_VID_VALID) { 2376 sl->sl_flags |= SL_VID_VALID; 2377 bcopy(sli->sli_vid, sl->sl_vendor_id, 8); 2378 } 2379 if (sli->sli_flags & SLI_PID_VALID) { 2380 sl->sl_flags |= SL_PID_VALID; 2381 bcopy(sli->sli_pid, sl->sl_product_id, 16); 2382 } 2383 if (sli->sli_flags & SLI_REV_VALID) { 2384 sl->sl_flags |= SL_REV_VALID; 2385 bcopy(sli->sli_rev, sl->sl_revision, 4); 2386 } 2387 if (sli->sli_flags & SLI_WRITEBACK_CACHE_DISABLE) { 2388 sl->sl_flags |= SL_WRITEBACK_CACHE_DISABLE; 2389 } 2390 sim_sli_loaded: 2391 if ((sl->sl_flags & SL_SHARED_META) == 0) { 2392 data_opened = 0; 2393 } else { 2394 data_opened = 1; 2395 sl->sl_data_filename = sl->sl_meta_filename; 2396 sl->sl_data_vp = sl->sl_meta_vp; 2397 sl->sl_data_vtype = sl->sl_meta_vtype; 2398 } 2399 2400 sret = sbd_pgr_meta_load(sl); 2401 if (sret != SBD_SUCCESS) { 2402 *err_ret = SBD_RET_NO_META; 2403 ret = EIO; 2404 goto sim_err_out; 2405 } 2406 2407 ret = sbd_open_data_file(sl, err_ret, 1, data_opened, 0); 2408 if (ret) { 2409 goto sim_err_out; 2410 } 2411 2412 /* 2413 * set write cache disable on the device 2414 * Note: this shouldn't fail on import unless the cache capabilities 2415 * of the device changed. If that happened, modify will need to 2416 * be used to set the cache flag appropriately after import is done. 2417 */ 2418 if (sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) { 2419 (void) sbd_wcd_set(1, sl); 2420 wcd = 1; 2421 /* 2422 * if not explicitly set, attempt to set it to enable, if that fails 2423 * get the current setting and use that 2424 */ 2425 } else { 2426 sret = sbd_wcd_set(0, sl); 2427 if (sret != SBD_SUCCESS) { 2428 sbd_wcd_get(&wcd, sl); 2429 } 2430 } 2431 2432 if (wcd) { 2433 sl->sl_flags |= SL_WRITEBACK_CACHE_DISABLE | 2434 SL_SAVED_WRITE_CACHE_DISABLE; 2435 } 2436 2437 /* we're only loading the metadata */ 2438 if (!no_register) { 2439 ret = sbd_populate_and_register_lu(sl, err_ret); 2440 if (ret) { 2441 goto sim_err_out; 2442 } 2443 atomic_add_32(&sbd_lu_count, 1); 2444 } 2445 2446 bcopy(sl->sl_device_id + 4, ilu->ilu_ret_guid, 16); 2447 sl->sl_trans_op = SL_OP_NONE; 2448 2449 if (sli) { 2450 kmem_free(sli, sli->sli_sms_header.sms_size); 2451 sli = NULL; 2452 } 2453 if (sli_buf_copy) { 2454 kmem_free(sli_buf_copy, sli_buf_sz + 1); 2455 sli_buf_copy = NULL; 2456 } 2457 if (no_register && !standby) { 2458 *slr = sl; 2459 } 2460 2461 /* 2462 * if this was imported from standby, set the access state 2463 * to active. 2464 */ 2465 if (standby) { 2466 sbd_it_data_t *it; 2467 mutex_enter(&sl->sl_lock); 2468 sl->sl_access_state = SBD_LU_ACTIVE; 2469 for (it = sl->sl_it_list; it != NULL; 2470 it = it->sbd_it_next) { 2471 it->sbd_it_ua_conditions |= 2472 SBD_UA_ASYMMETRIC_ACCESS_CHANGED; 2473 it->sbd_it_ua_conditions |= SBD_UA_POR; 2474 } 2475 mutex_exit(&sl->sl_lock); 2476 /* call set access state */ 2477 stret = stmf_set_lu_access(lu, STMF_LU_ACTIVE); 2478 if (stret != STMF_SUCCESS) { 2479 *err_ret = SBD_RET_ACCESS_STATE_FAILED; 2480 sl->sl_access_state = SBD_LU_STANDBY; 2481 goto sim_err_out; 2482 } 2483 if (sl->sl_alias) { 2484 lu->lu_alias = sl->sl_alias; 2485 } else { 2486 lu->lu_alias = sl->sl_name; 2487 } 2488 } 2489 sl->sl_access_state = SBD_LU_ACTIVE; 2490 return (0); 2491 2492 sim_err_out: 2493 if (sli) { 2494 kmem_free(sli, sli->sli_sms_header.sms_size); 2495 sli = NULL; 2496 } 2497 if (sli_buf_copy) { 2498 kmem_free(sli_buf_copy, sli_buf_sz + 1); 2499 sli_buf_copy = NULL; 2500 } 2501 2502 if (standby) { 2503 *err_ret = SBD_RET_ACCESS_STATE_FAILED; 2504 sl->sl_trans_op = SL_OP_NONE; 2505 return (EIO); 2506 } else { 2507 return (sbd_close_delete_lu(sl, ret)); 2508 } 2509 } 2510 2511 int 2512 sbd_modify_lu(sbd_modify_lu_t *mlu, int struct_sz, uint32_t *err_ret) 2513 { 2514 sbd_lu_t *sl = NULL; 2515 uint16_t alias_sz; 2516 int ret = 0; 2517 sbd_it_data_t *it; 2518 sbd_status_t sret; 2519 uint64_t old_size; 2520 int modify_unregistered = 0; 2521 int ua = 0; 2522 sbd_import_lu_t *ilu; 2523 stmf_lu_t *lu; 2524 uint32_t ilu_sz; 2525 uint32_t sz; 2526 2527 sz = struct_sz - sizeof (*mlu) + 8 + 1; 2528 2529 /* if there is data in the buf, null terminate it */ 2530 if (struct_sz > sizeof (*mlu)) { 2531 mlu->mlu_buf[struct_sz - sizeof (*mlu) + 8 - 1] = 0; 2532 } 2533 2534 *err_ret = 0; 2535 2536 /* Lets validate offsets */ 2537 if (((mlu->mlu_alias_valid) && 2538 (mlu->mlu_alias_off >= sz)) || 2539 ((mlu->mlu_mgmt_url_valid) && 2540 (mlu->mlu_mgmt_url_off >= sz)) || 2541 (mlu->mlu_by_fname) && 2542 (mlu->mlu_fname_off >= sz)) { 2543 return (EINVAL); 2544 } 2545 2546 /* 2547 * We'll look for the device but if we don't find it registered, 2548 * we'll still try to modify the unregistered device. 2549 */ 2550 if (mlu->mlu_by_guid) { 2551 sret = sbd_find_and_lock_lu(mlu->mlu_input_guid, NULL, 2552 SL_OP_MODIFY_LU, &sl); 2553 } else if (mlu->mlu_by_fname) { 2554 sret = sbd_find_and_lock_lu(NULL, 2555 (uint8_t *)&(mlu->mlu_buf[mlu->mlu_fname_off]), 2556 SL_OP_MODIFY_LU, &sl); 2557 } else { 2558 return (EINVAL); 2559 } 2560 2561 2562 if (sret != SBD_SUCCESS) { 2563 if (sret == SBD_BUSY) { 2564 *err_ret = SBD_RET_LU_BUSY; 2565 return (EBUSY); 2566 } else if (sret != SBD_NOT_FOUND) { 2567 return (EIO); 2568 } else if (!mlu->mlu_by_fname) { 2569 return (EINVAL); 2570 } 2571 /* Okay, try to import the device */ 2572 struct_sz = max(8, strlen(&(mlu->mlu_buf[mlu->mlu_fname_off])) 2573 + 1); 2574 struct_sz += sizeof (sbd_import_lu_t) - 8; 2575 ilu_sz = struct_sz; 2576 ilu = (sbd_import_lu_t *)kmem_zalloc(ilu_sz, KM_SLEEP); 2577 ilu->ilu_struct_size = struct_sz; 2578 (void) strcpy(ilu->ilu_meta_fname, 2579 &(mlu->mlu_buf[mlu->mlu_fname_off])); 2580 ret = sbd_import_lu(ilu, struct_sz, err_ret, 1, &sl); 2581 kmem_free(ilu, ilu_sz); 2582 if (ret != SBD_SUCCESS) { 2583 return (ENOENT); 2584 } 2585 modify_unregistered = 1; 2586 } 2587 2588 if (sl->sl_access_state != SBD_LU_ACTIVE) { 2589 *err_ret = SBD_RET_ACCESS_STATE_FAILED; 2590 ret = EINVAL; 2591 goto smm_err_out; 2592 } 2593 2594 /* check for write cache change */ 2595 if (mlu->mlu_writeback_cache_disable_valid) { 2596 /* set wce on device */ 2597 sret = sbd_wcd_set(mlu->mlu_writeback_cache_disable, sl); 2598 if (!mlu->mlu_writeback_cache_disable && sret != SBD_SUCCESS) { 2599 *err_ret = SBD_RET_WRITE_CACHE_SET_FAILED; 2600 ret = EFAULT; 2601 goto smm_err_out; 2602 } 2603 mutex_enter(&sl->sl_lock); 2604 if (!mlu->mlu_writeback_cache_disable) { 2605 if (sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) { 2606 ua = 1; 2607 sl->sl_flags &= ~SL_WRITEBACK_CACHE_DISABLE; 2608 sl->sl_flags &= ~SL_SAVED_WRITE_CACHE_DISABLE; 2609 } 2610 } else { 2611 if ((sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) == 0) { 2612 ua = 1; 2613 sl->sl_flags |= SL_WRITEBACK_CACHE_DISABLE; 2614 sl->sl_flags |= SL_SAVED_WRITE_CACHE_DISABLE; 2615 } 2616 } 2617 for (it = sl->sl_it_list; ua && it != NULL; 2618 it = it->sbd_it_next) { 2619 it->sbd_it_ua_conditions |= 2620 SBD_UA_MODE_PARAMETERS_CHANGED; 2621 } 2622 mutex_exit(&sl->sl_lock); 2623 } 2624 ua = 0; 2625 2626 if (mlu->mlu_alias_valid) { 2627 alias_sz = strlen((char *)mlu->mlu_buf + 2628 mlu->mlu_alias_off) + 1; 2629 /* 2630 * Use the allocated buffer or alloc a new one. 2631 * Don't copy into sl_alias if sl_alias_alloc_size is 0 2632 * otherwise or you'll be writing over the data/metadata 2633 * filename. 2634 */ 2635 mutex_enter(&sl->sl_lock); 2636 if (sl->sl_alias_alloc_size > 0 && 2637 sl->sl_alias_alloc_size < alias_sz) { 2638 kmem_free(sl->sl_alias, 2639 sl->sl_alias_alloc_size); 2640 sl->sl_alias_alloc_size = 0; 2641 } 2642 if (sl->sl_alias_alloc_size == 0) { 2643 sl->sl_alias = kmem_alloc(alias_sz, KM_SLEEP); 2644 sl->sl_alias_alloc_size = alias_sz; 2645 } 2646 (void) strcpy(sl->sl_alias, (char *)mlu->mlu_buf + 2647 mlu->mlu_alias_off); 2648 lu = sl->sl_lu; 2649 lu->lu_alias = sl->sl_alias; 2650 mutex_exit(&sl->sl_lock); 2651 } 2652 2653 if (mlu->mlu_mgmt_url_valid) { 2654 uint16_t url_sz; 2655 2656 url_sz = strlen((char *)mlu->mlu_buf + mlu->mlu_mgmt_url_off); 2657 if (url_sz > 0) 2658 url_sz++; 2659 2660 mutex_enter(&sl->sl_lock); 2661 if (sl->sl_mgmt_url_alloc_size > 0 && 2662 (url_sz == 0 || sl->sl_mgmt_url_alloc_size < url_sz)) { 2663 kmem_free(sl->sl_mgmt_url, sl->sl_mgmt_url_alloc_size); 2664 sl->sl_mgmt_url = NULL; 2665 sl->sl_mgmt_url_alloc_size = 0; 2666 } 2667 if (url_sz > 0) { 2668 if (sl->sl_mgmt_url_alloc_size == 0) { 2669 sl->sl_mgmt_url = kmem_alloc(url_sz, KM_SLEEP); 2670 sl->sl_mgmt_url_alloc_size = url_sz; 2671 } 2672 (void) strcpy(sl->sl_mgmt_url, (char *)mlu->mlu_buf + 2673 mlu->mlu_mgmt_url_off); 2674 } 2675 for (it = sl->sl_it_list; it != NULL; 2676 it = it->sbd_it_next) { 2677 it->sbd_it_ua_conditions |= 2678 SBD_UA_MODE_PARAMETERS_CHANGED; 2679 } 2680 mutex_exit(&sl->sl_lock); 2681 } 2682 2683 if (mlu->mlu_write_protected_valid) { 2684 mutex_enter(&sl->sl_lock); 2685 if (mlu->mlu_write_protected) { 2686 if ((sl->sl_flags & SL_WRITE_PROTECTED) == 0) { 2687 ua = 1; 2688 sl->sl_flags |= SL_WRITE_PROTECTED; 2689 } 2690 } else { 2691 if (sl->sl_flags & SL_WRITE_PROTECTED) { 2692 ua = 1; 2693 sl->sl_flags &= ~SL_WRITE_PROTECTED; 2694 } 2695 } 2696 for (it = sl->sl_it_list; ua && it != NULL; 2697 it = it->sbd_it_next) { 2698 it->sbd_it_ua_conditions |= 2699 SBD_UA_MODE_PARAMETERS_CHANGED; 2700 } 2701 mutex_exit(&sl->sl_lock); 2702 } 2703 2704 if (mlu->mlu_lu_size_valid) { 2705 /* 2706 * validate lu size and set 2707 * For open file only (registered lu) 2708 */ 2709 mutex_enter(&sl->sl_lock); 2710 old_size = sl->sl_lu_size; 2711 sl->sl_lu_size = mlu->mlu_lu_size; 2712 mutex_exit(&sl->sl_lock); 2713 ret = sbd_open_data_file(sl, err_ret, 1, 1, 1); 2714 if (ret) { 2715 mutex_enter(&sl->sl_lock); 2716 sl->sl_lu_size = old_size; 2717 mutex_exit(&sl->sl_lock); 2718 goto smm_err_out; 2719 } 2720 if (old_size != mlu->mlu_lu_size) { 2721 mutex_enter(&sl->sl_lock); 2722 for (it = sl->sl_it_list; it != NULL; 2723 it = it->sbd_it_next) { 2724 it->sbd_it_ua_conditions |= 2725 SBD_UA_CAPACITY_CHANGED; 2726 } 2727 mutex_exit(&sl->sl_lock); 2728 } 2729 } 2730 2731 if (sbd_write_lu_info(sl) != SBD_SUCCESS) { 2732 *err_ret = SBD_RET_META_CREATION_FAILED; 2733 ret = EIO; 2734 } 2735 2736 smm_err_out: 2737 if (modify_unregistered) { 2738 (void) sbd_close_delete_lu(sl, 0); 2739 } else { 2740 sl->sl_trans_op = SL_OP_NONE; 2741 } 2742 return (ret); 2743 } 2744 2745 /* ARGSUSED */ 2746 int 2747 sbd_delete_locked_lu(sbd_lu_t *sl, uint32_t *err_ret, 2748 stmf_state_change_info_t *ssi) 2749 { 2750 int i; 2751 2752 if ((sl->sl_state == STMF_STATE_OFFLINE) && 2753 !sl->sl_state_not_acked) { 2754 goto sdl_do_dereg; 2755 } 2756 2757 if ((sl->sl_state != STMF_STATE_ONLINE) || 2758 sl->sl_state_not_acked) { 2759 return (EBUSY); 2760 } 2761 if (stmf_ctl(STMF_CMD_LU_OFFLINE, sl->sl_lu, ssi) != STMF_SUCCESS) { 2762 return (EBUSY); 2763 } 2764 2765 for (i = 0; i < 500; i++) { 2766 if (sl->sl_state == STMF_STATE_OFFLINE) 2767 break; 2768 delay(drv_usectohz(10000)); 2769 } 2770 2771 if ((sl->sl_state == STMF_STATE_OFFLINE) && 2772 !sl->sl_state_not_acked) { 2773 goto sdl_do_dereg; 2774 } 2775 2776 return (EBUSY); 2777 sdl_do_dereg:; 2778 if (stmf_deregister_lu(sl->sl_lu) != STMF_SUCCESS) 2779 return (EBUSY); 2780 atomic_add_32(&sbd_lu_count, -1); 2781 2782 return (sbd_close_delete_lu(sl, 0)); 2783 } 2784 2785 int 2786 sbd_delete_lu(sbd_delete_lu_t *dlu, int struct_sz, uint32_t *err_ret) 2787 { 2788 sbd_lu_t *sl; 2789 sbd_status_t sret; 2790 stmf_state_change_info_t ssi; 2791 int ret; 2792 2793 if (dlu->dlu_by_meta_name) { 2794 ((char *)dlu)[struct_sz - 1] = 0; 2795 sret = sbd_find_and_lock_lu(NULL, dlu->dlu_meta_name, 2796 SL_OP_DELETE_LU, &sl); 2797 } else { 2798 sret = sbd_find_and_lock_lu(dlu->dlu_guid, NULL, 2799 SL_OP_DELETE_LU, &sl); 2800 } 2801 if (sret != SBD_SUCCESS) { 2802 if (sret == SBD_BUSY) { 2803 *err_ret = SBD_RET_LU_BUSY; 2804 return (EBUSY); 2805 } else if (sret == SBD_NOT_FOUND) { 2806 *err_ret = SBD_RET_NOT_FOUND; 2807 return (ENOENT); 2808 } 2809 return (EIO); 2810 } 2811 2812 ssi.st_rflags = STMF_RFLAG_USER_REQUEST; 2813 ssi.st_additional_info = "sbd_delete_lu call (ioctl)"; 2814 ret = sbd_delete_locked_lu(sl, err_ret, &ssi); 2815 2816 if (ret) { 2817 /* Once its locked, no need to grab mutex again */ 2818 sl->sl_trans_op = SL_OP_NONE; 2819 } 2820 return (ret); 2821 } 2822 2823 sbd_status_t 2824 sbd_data_read(sbd_lu_t *sl, uint64_t offset, uint64_t size, uint8_t *buf) 2825 { 2826 int ret; 2827 long resid; 2828 2829 if ((offset + size) > sl->sl_lu_size) { 2830 return (SBD_IO_PAST_EOF); 2831 } 2832 2833 offset += sl->sl_data_offset; 2834 2835 if ((offset + size) > sl->sl_data_readable_size) { 2836 uint64_t store_end; 2837 if (offset > sl->sl_data_readable_size) { 2838 bzero(buf, size); 2839 return (SBD_SUCCESS); 2840 } 2841 store_end = sl->sl_data_readable_size - offset; 2842 bzero(buf + store_end, size - store_end); 2843 size = store_end; 2844 } 2845 2846 DTRACE_PROBE4(backing__store__read__start, sbd_lu_t *, sl, 2847 uint8_t *, buf, uint64_t, size, uint64_t, offset); 2848 2849 /* 2850 * Don't proceed if the device has been closed 2851 * This can occur on an access state change to standby or 2852 * a delete. The writer lock is acquired before closing the 2853 * lu. 2854 */ 2855 rw_enter(&sl->sl_access_state_lock, RW_READER); 2856 if ((sl->sl_flags & SL_MEDIA_LOADED) == 0) { 2857 rw_exit(&sl->sl_access_state_lock); 2858 return (SBD_FAILURE); 2859 } 2860 ret = vn_rdwr(UIO_READ, sl->sl_data_vp, (caddr_t)buf, (ssize_t)size, 2861 (offset_t)offset, UIO_SYSSPACE, 0, RLIM64_INFINITY, CRED(), 2862 &resid); 2863 rw_exit(&sl->sl_access_state_lock); 2864 2865 DTRACE_PROBE5(backing__store__read__end, sbd_lu_t *, sl, 2866 uint8_t *, buf, uint64_t, size, uint64_t, offset, 2867 int, ret); 2868 2869 over_sl_data_read: 2870 if (ret || resid) { 2871 stmf_trace(0, "UIO_READ failed, ret = %d, resid = %d", ret, 2872 resid); 2873 return (SBD_FAILURE); 2874 } 2875 2876 return (SBD_SUCCESS); 2877 } 2878 2879 sbd_status_t 2880 sbd_data_write(sbd_lu_t *sl, uint64_t offset, uint64_t size, uint8_t *buf) 2881 { 2882 int ret; 2883 long resid; 2884 sbd_status_t sret = SBD_SUCCESS; 2885 int ioflag; 2886 2887 if ((offset + size) > sl->sl_lu_size) { 2888 return (SBD_IO_PAST_EOF); 2889 } 2890 2891 offset += sl->sl_data_offset; 2892 2893 if ((sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) && 2894 (sl->sl_flags & SL_FLUSH_ON_DISABLED_WRITECACHE)) { 2895 ioflag = FSYNC; 2896 } else { 2897 ioflag = 0; 2898 } 2899 2900 DTRACE_PROBE4(backing__store__write__start, sbd_lu_t *, sl, 2901 uint8_t *, buf, uint64_t, size, uint64_t, offset); 2902 2903 /* 2904 * Don't proceed if the device has been closed 2905 * This can occur on an access state change to standby or 2906 * a delete. The writer lock is acquired before closing the 2907 * lu. 2908 */ 2909 rw_enter(&sl->sl_access_state_lock, RW_READER); 2910 if ((sl->sl_flags & SL_MEDIA_LOADED) == 0) { 2911 rw_exit(&sl->sl_access_state_lock); 2912 return (SBD_FAILURE); 2913 } 2914 ret = vn_rdwr(UIO_WRITE, sl->sl_data_vp, (caddr_t)buf, (ssize_t)size, 2915 (offset_t)offset, UIO_SYSSPACE, ioflag, RLIM64_INFINITY, CRED(), 2916 &resid); 2917 rw_exit(&sl->sl_access_state_lock); 2918 2919 DTRACE_PROBE5(backing__store__write__end, sbd_lu_t *, sl, 2920 uint8_t *, buf, uint64_t, size, uint64_t, offset, 2921 int, ret); 2922 2923 if ((ret == 0) && (resid == 0) && 2924 (sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) && 2925 (sl->sl_flags & SL_FLUSH_ON_DISABLED_WRITECACHE)) { 2926 sret = sbd_flush_data_cache(sl, 1); 2927 } 2928 over_sl_data_write: 2929 2930 if ((ret || resid) || (sret != SBD_SUCCESS)) { 2931 return (SBD_FAILURE); 2932 } else if ((offset + size) > sl->sl_data_readable_size) { 2933 uint64_t old_size, new_size; 2934 2935 do { 2936 old_size = sl->sl_data_readable_size; 2937 if ((offset + size) <= old_size) 2938 break; 2939 new_size = offset + size; 2940 } while (atomic_cas_64(&sl->sl_data_readable_size, old_size, 2941 new_size) != old_size); 2942 } 2943 2944 return (SBD_SUCCESS); 2945 } 2946 2947 int 2948 sbd_get_lu_props(sbd_lu_props_t *islp, uint32_t islp_sz, 2949 sbd_lu_props_t *oslp, uint32_t oslp_sz, uint32_t *err_ret) 2950 { 2951 sbd_status_t sret; 2952 sbd_lu_t *sl = NULL; 2953 uint32_t sz; 2954 uint16_t off; 2955 2956 if (islp->slp_input_guid) { 2957 sret = sbd_find_and_lock_lu(islp->slp_guid, NULL, 2958 SL_OP_LU_PROPS, &sl); 2959 } else { 2960 ((char *)islp)[islp_sz - 1] = 0; 2961 sret = sbd_find_and_lock_lu(NULL, islp->slp_buf, 2962 SL_OP_LU_PROPS, &sl); 2963 } 2964 if (sret != SBD_SUCCESS) { 2965 if (sret == SBD_BUSY) { 2966 *err_ret = SBD_RET_LU_BUSY; 2967 return (EBUSY); 2968 } else if (sret == SBD_NOT_FOUND) { 2969 *err_ret = SBD_RET_NOT_FOUND; 2970 return (ENOENT); 2971 } 2972 return (EIO); 2973 } 2974 2975 sz = strlen(sl->sl_name) + 1; 2976 if ((sl->sl_flags & (SL_ZFS_META | SL_SHARED_META)) == 0) { 2977 if (sl->sl_data_filename) { 2978 sz += strlen(sl->sl_data_filename) + 1; 2979 } 2980 } 2981 sz += sl->sl_serial_no_size; 2982 if (sl->sl_alias) { 2983 sz += strlen(sl->sl_alias) + 1; 2984 } 2985 2986 if (sl->sl_mgmt_url) { 2987 sz += strlen(sl->sl_mgmt_url) + 1; 2988 } 2989 bzero(oslp, sizeof (*oslp) - 8); 2990 oslp->slp_buf_size_needed = sz; 2991 2992 if (sz > (oslp_sz - sizeof (*oslp) + 8)) { 2993 sl->sl_trans_op = SL_OP_NONE; 2994 *err_ret = SBD_RET_INSUFFICIENT_BUF_SPACE; 2995 return (ENOMEM); 2996 } 2997 2998 off = 0; 2999 (void) strcpy((char *)oslp->slp_buf, sl->sl_name); 3000 oslp->slp_meta_fname_off = off; 3001 off += strlen(sl->sl_name) + 1; 3002 if ((sl->sl_flags & (SL_ZFS_META | SL_SHARED_META)) == 0) { 3003 oslp->slp_meta_fname_valid = 1; 3004 oslp->slp_separate_meta = 1; 3005 if (sl->sl_data_filename) { 3006 oslp->slp_data_fname_valid = 1; 3007 oslp->slp_data_fname_off = off; 3008 (void) strcpy((char *)&oslp->slp_buf[off], 3009 sl->sl_data_filename); 3010 off += strlen(sl->sl_data_filename) + 1; 3011 } 3012 } else { 3013 oslp->slp_data_fname_valid = 1; 3014 oslp->slp_data_fname_off = oslp->slp_meta_fname_off; 3015 if (sl->sl_flags & SL_ZFS_META) { 3016 oslp->slp_zfs_meta = 1; 3017 } 3018 } 3019 if (sl->sl_alias) { 3020 oslp->slp_alias_valid = 1; 3021 oslp->slp_alias_off = off; 3022 (void) strcpy((char *)&oslp->slp_buf[off], sl->sl_alias); 3023 off += strlen(sl->sl_alias) + 1; 3024 } 3025 if (sl->sl_mgmt_url) { 3026 oslp->slp_mgmt_url_valid = 1; 3027 oslp->slp_mgmt_url_off = off; 3028 (void) strcpy((char *)&oslp->slp_buf[off], sl->sl_mgmt_url); 3029 off += strlen(sl->sl_mgmt_url) + 1; 3030 } 3031 if (sl->sl_serial_no_size) { 3032 oslp->slp_serial_off = off; 3033 bcopy(sl->sl_serial_no, &oslp->slp_buf[off], 3034 sl->sl_serial_no_size); 3035 oslp->slp_serial_size = sl->sl_serial_no_size; 3036 oslp->slp_serial_valid = 1; 3037 off += sl->sl_serial_no_size; 3038 } 3039 3040 oslp->slp_lu_size = sl->sl_lu_size; 3041 oslp->slp_blksize = ((uint16_t)1) << sl->sl_data_blocksize_shift; 3042 3043 oslp->slp_access_state = sl->sl_access_state; 3044 3045 if (sl->sl_flags & SL_VID_VALID) { 3046 oslp->slp_lu_vid = 1; 3047 bcopy(sl->sl_vendor_id, oslp->slp_vid, 8); 3048 } else { 3049 bcopy(sbd_vendor_id, oslp->slp_vid, 8); 3050 } 3051 if (sl->sl_flags & SL_PID_VALID) { 3052 oslp->slp_lu_pid = 1; 3053 bcopy(sl->sl_product_id, oslp->slp_pid, 16); 3054 } else { 3055 bcopy(sbd_product_id, oslp->slp_pid, 16); 3056 } 3057 if (sl->sl_flags & SL_REV_VALID) { 3058 oslp->slp_lu_rev = 1; 3059 bcopy(sl->sl_revision, oslp->slp_rev, 4); 3060 } else { 3061 bcopy(sbd_revision, oslp->slp_rev, 4); 3062 } 3063 bcopy(sl->sl_device_id + 4, oslp->slp_guid, 16); 3064 3065 if (sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) 3066 oslp->slp_writeback_cache_disable_cur = 1; 3067 if (sl->sl_flags & SL_SAVED_WRITE_CACHE_DISABLE) 3068 oslp->slp_writeback_cache_disable_saved = 1; 3069 if (sl->sl_flags & SL_WRITE_PROTECTED) 3070 oslp->slp_write_protected = 1; 3071 3072 sl->sl_trans_op = SL_OP_NONE; 3073 3074 return (0); 3075 } 3076 3077 char * 3078 sbd_get_zvol_name(sbd_lu_t *sl) 3079 { 3080 char *src; 3081 char *p; 3082 3083 if (sl->sl_data_filename) 3084 src = sl->sl_data_filename; 3085 else 3086 src = sl->sl_meta_filename; 3087 /* There has to be a better way */ 3088 if (SBD_IS_ZVOL(src) != 0) { 3089 ASSERT(0); 3090 } 3091 src += 14; 3092 if (*src == '/') 3093 src++; 3094 p = (char *)kmem_alloc(strlen(src) + 1, KM_SLEEP); 3095 (void) strcpy(p, src); 3096 return (p); 3097 } 3098 3099 /* 3100 * this function creates a local metadata zvol property 3101 */ 3102 sbd_status_t 3103 sbd_create_zfs_meta_object(sbd_lu_t *sl) 3104 { 3105 /* 3106 * -allocate 1/2 the property size, the zfs property 3107 * is 8k in size and stored as ascii hex string, all 3108 * we needed is 4k buffer to store the binary data. 3109 * -initialize reader/write lock 3110 */ 3111 if ((sl->sl_zfs_meta = kmem_zalloc(ZAP_MAXVALUELEN / 2, KM_SLEEP)) 3112 == NULL) 3113 return (SBD_FAILURE); 3114 rw_init(&sl->sl_zfs_meta_lock, NULL, RW_DRIVER, NULL); 3115 return (SBD_SUCCESS); 3116 } 3117 3118 char 3119 sbd_ctoi(char c) 3120 { 3121 if ((c >= '0') && (c <= '9')) 3122 c -= '0'; 3123 else if ((c >= 'A') && (c <= 'F')) 3124 c = c - 'A' + 10; 3125 else if ((c >= 'a') && (c <= 'f')) 3126 c = c - 'a' + 10; 3127 else 3128 c = -1; 3129 return (c); 3130 } 3131 3132 /* 3133 * read zvol property and convert to binary 3134 */ 3135 sbd_status_t 3136 sbd_open_zfs_meta(sbd_lu_t *sl) 3137 { 3138 char *meta = NULL, cl, ch; 3139 int i; 3140 char *tmp, *ptr; 3141 uint64_t rc = SBD_SUCCESS; 3142 int len; 3143 char *file; 3144 3145 if (sl->sl_zfs_meta == NULL) { 3146 if (sbd_create_zfs_meta_object(sl) == SBD_FAILURE) 3147 return (SBD_FAILURE); 3148 } else { 3149 bzero(sl->sl_zfs_meta, (ZAP_MAXVALUELEN / 2)); 3150 } 3151 3152 rw_enter(&sl->sl_zfs_meta_lock, RW_WRITER); 3153 file = sbd_get_zvol_name(sl); 3154 if (sbd_zvolget(file, &meta)) { 3155 rc = SBD_FAILURE; 3156 goto done; 3157 } 3158 tmp = meta; 3159 /* convert ascii hex to binary meta */ 3160 len = strlen(meta); 3161 ptr = sl->sl_zfs_meta; 3162 for (i = 0; i < len; i += 2) { 3163 ch = sbd_ctoi(*tmp++); 3164 cl = sbd_ctoi(*tmp++); 3165 if (ch == -1 || cl == -1) { 3166 rc = SBD_FAILURE; 3167 break; 3168 } 3169 *ptr++ = (ch << 4) + cl; 3170 } 3171 done: 3172 rw_exit(&sl->sl_zfs_meta_lock); 3173 if (meta) 3174 kmem_free(meta, len + 1); 3175 kmem_free(file, strlen(file) + 1); 3176 return (rc); 3177 } 3178 3179 sbd_status_t 3180 sbd_read_zfs_meta(sbd_lu_t *sl, uint8_t *buf, uint64_t sz, uint64_t off) 3181 { 3182 ASSERT(sl->sl_zfs_meta); 3183 rw_enter(&sl->sl_zfs_meta_lock, RW_READER); 3184 bcopy(&sl->sl_zfs_meta[off], buf, sz); 3185 rw_exit(&sl->sl_zfs_meta_lock); 3186 return (SBD_SUCCESS); 3187 } 3188 3189 sbd_status_t 3190 sbd_write_zfs_meta(sbd_lu_t *sl, uint8_t *buf, uint64_t sz, uint64_t off) 3191 { 3192 char *ptr, *ah_meta; 3193 char *dp = NULL; 3194 int i, num; 3195 char *file; 3196 3197 ASSERT(sl->sl_zfs_meta); 3198 if ((off + sz) > (ZAP_MAXVALUELEN / 2 - 1)) { 3199 return (SBD_META_CORRUPTED); 3200 } 3201 if ((off + sz) > sl->sl_meta_size_used) { 3202 sl->sl_meta_size_used = off + sz; 3203 if (sl->sl_total_meta_size < sl->sl_meta_size_used) { 3204 uint64_t meta_align = 3205 (((uint64_t)1) << sl->sl_meta_blocksize_shift) - 1; 3206 sl->sl_total_meta_size = (sl->sl_meta_size_used + 3207 meta_align) & (~meta_align); 3208 } 3209 } 3210 ptr = ah_meta = kmem_zalloc(ZAP_MAXVALUELEN, KM_SLEEP); 3211 rw_enter(&sl->sl_zfs_meta_lock, RW_WRITER); 3212 bcopy(buf, &sl->sl_zfs_meta[off], sz); 3213 /* convert local copy to ascii hex */ 3214 dp = sl->sl_zfs_meta; 3215 for (i = 0; i < sl->sl_total_meta_size; i++, dp++) { 3216 num = ((*dp) >> 4) & 0xF; 3217 *ah_meta++ = (num < 10) ? (num + '0') : (num + ('a' - 10)); 3218 num = (*dp) & 0xF; 3219 *ah_meta++ = (num < 10) ? (num + '0') : (num + ('a' - 10)); 3220 } 3221 *ah_meta = NULL; 3222 file = sbd_get_zvol_name(sl); 3223 if (sbd_zvolset(file, (char *)ptr)) { 3224 rw_exit(&sl->sl_zfs_meta_lock); 3225 kmem_free(ptr, ZAP_MAXVALUELEN); 3226 kmem_free(file, strlen(file) + 1); 3227 return (SBD_META_CORRUPTED); 3228 } 3229 rw_exit(&sl->sl_zfs_meta_lock); 3230 kmem_free(ptr, ZAP_MAXVALUELEN); 3231 kmem_free(file, strlen(file) + 1); 3232 return (SBD_SUCCESS); 3233 } 3234 3235 int 3236 sbd_is_zvol(char *path) 3237 { 3238 int is_zfs = 0; 3239 3240 if (SBD_IS_ZVOL(path) == 0) 3241 is_zfs = 1; 3242 3243 return (is_zfs); 3244 } 3245 3246 /* 3247 * set write cache disable 3248 * wcd - 1 = disable, 0 = enable 3249 */ 3250 sbd_status_t 3251 sbd_wcd_set(int wcd, sbd_lu_t *sl) 3252 { 3253 /* translate to wce bit */ 3254 int wce = wcd ? 0 : 1; 3255 int ret; 3256 sbd_status_t sret = SBD_SUCCESS; 3257 3258 mutex_enter(&sl->sl_lock); 3259 sl->sl_flags &= ~SL_WRITEBACK_CACHE_SET_UNSUPPORTED; 3260 3261 if (sl->sl_data_vp->v_type == VREG) { 3262 sl->sl_flags |= SL_FLUSH_ON_DISABLED_WRITECACHE; 3263 goto done; 3264 } 3265 3266 ret = VOP_IOCTL(sl->sl_data_vp, DKIOCSETWCE, (intptr_t)&wce, FKIOCTL, 3267 kcred, NULL, NULL); 3268 if (ret == 0) { 3269 sl->sl_flags &= ~SL_WRITEBACK_CACHE_SET_UNSUPPORTED; 3270 sl->sl_flags &= ~SL_FLUSH_ON_DISABLED_WRITECACHE; 3271 } else { 3272 sl->sl_flags |= SL_WRITEBACK_CACHE_SET_UNSUPPORTED; 3273 sl->sl_flags |= SL_FLUSH_ON_DISABLED_WRITECACHE; 3274 sret = SBD_FAILURE; 3275 goto done; 3276 } 3277 3278 done: 3279 mutex_exit(&sl->sl_lock); 3280 return (sret); 3281 } 3282 3283 /* 3284 * get write cache disable 3285 * wcd - 1 = disable, 0 = enable 3286 */ 3287 void 3288 sbd_wcd_get(int *wcd, sbd_lu_t *sl) 3289 { 3290 int wce; 3291 int ret; 3292 3293 if (sl->sl_data_vp->v_type == VREG) { 3294 *wcd = 0; 3295 return; 3296 } 3297 3298 ret = VOP_IOCTL(sl->sl_data_vp, DKIOCGETWCE, (intptr_t)&wce, FKIOCTL, 3299 kcred, NULL, NULL); 3300 /* if write cache get failed, assume disabled */ 3301 if (ret) { 3302 *wcd = 1; 3303 } else { 3304 /* translate to wcd bit */ 3305 *wcd = wce ? 0 : 1; 3306 } 3307 } 3308 3309 int 3310 sbd_zvolget(char *zvol_name, char **comstarprop) 3311 { 3312 ldi_handle_t zfs_lh; 3313 nvlist_t *nv = NULL, *nv2; 3314 zfs_cmd_t *zc; 3315 char *ptr; 3316 int size = 1024; 3317 int unused; 3318 int rc; 3319 3320 if ((rc = ldi_open_by_name("/dev/zfs", FREAD | FWRITE, kcred, 3321 &zfs_lh, sbd_zfs_ident)) != 0) { 3322 cmn_err(CE_WARN, "ldi_open %d", rc); 3323 return (ENXIO); 3324 } 3325 3326 zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP); 3327 (void) strlcpy(zc->zc_name, zvol_name, sizeof (zc->zc_name)); 3328 again: 3329 zc->zc_nvlist_dst = (uint64_t)(intptr_t)kmem_alloc(size, 3330 KM_SLEEP); 3331 zc->zc_nvlist_dst_size = size; 3332 rc = ldi_ioctl(zfs_lh, ZFS_IOC_OBJSET_STATS, (intptr_t)zc, 3333 FKIOCTL, kcred, &unused); 3334 /* 3335 * ENOMEM means the list is larger than what we've allocated 3336 * ldi_ioctl will fail with ENOMEM only once 3337 */ 3338 if (rc == ENOMEM) { 3339 int newsize; 3340 newsize = zc->zc_nvlist_dst_size; 3341 kmem_free((void *)(uintptr_t)zc->zc_nvlist_dst, size); 3342 size = newsize; 3343 goto again; 3344 } else if (rc != 0) { 3345 goto out; 3346 } 3347 rc = nvlist_unpack((char *)(uintptr_t)zc->zc_nvlist_dst, 3348 zc->zc_nvlist_dst_size, &nv, 0); 3349 ASSERT(rc == 0); /* nvlist_unpack should not fail */ 3350 if ((rc = nvlist_lookup_nvlist(nv, "stmf_sbd_lu", &nv2)) == 0) { 3351 rc = nvlist_lookup_string(nv2, ZPROP_VALUE, &ptr); 3352 if (rc != 0) { 3353 cmn_err(CE_WARN, "couldn't get value"); 3354 } else { 3355 *comstarprop = kmem_alloc(strlen(ptr) + 1, 3356 KM_SLEEP); 3357 (void) strcpy(*comstarprop, ptr); 3358 } 3359 } 3360 out: 3361 if (nv != NULL) 3362 nvlist_free(nv); 3363 kmem_free((void *)(uintptr_t)zc->zc_nvlist_dst, size); 3364 kmem_free(zc, sizeof (zfs_cmd_t)); 3365 (void) ldi_close(zfs_lh, FREAD|FWRITE, kcred); 3366 3367 return (rc); 3368 } 3369 3370 int 3371 sbd_zvolset(char *zvol_name, char *comstarprop) 3372 { 3373 ldi_handle_t zfs_lh; 3374 nvlist_t *nv; 3375 char *packed = NULL; 3376 size_t len; 3377 zfs_cmd_t *zc; 3378 int unused; 3379 int rc; 3380 3381 if ((rc = ldi_open_by_name("/dev/zfs", FREAD | FWRITE, kcred, 3382 &zfs_lh, sbd_zfs_ident)) != 0) { 3383 cmn_err(CE_WARN, "ldi_open %d", rc); 3384 return (ENXIO); 3385 } 3386 (void) nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP); 3387 (void) nvlist_add_string(nv, "stmf_sbd_lu", comstarprop); 3388 if ((rc = nvlist_pack(nv, &packed, &len, NV_ENCODE_NATIVE, KM_SLEEP))) { 3389 goto out; 3390 } 3391 3392 zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP); 3393 (void) strlcpy(zc->zc_name, zvol_name, sizeof (zc->zc_name)); 3394 zc->zc_nvlist_src = (uint64_t)(intptr_t)packed; 3395 zc->zc_nvlist_src_size = len; 3396 rc = ldi_ioctl(zfs_lh, ZFS_IOC_SET_PROP, (intptr_t)zc, 3397 FKIOCTL, kcred, &unused); 3398 if (rc != 0) { 3399 cmn_err(CE_NOTE, "ioctl failed %d", rc); 3400 } 3401 kmem_free(zc, sizeof (zfs_cmd_t)); 3402 if (packed) 3403 kmem_free(packed, len); 3404 out: 3405 nvlist_free(nv); 3406 (void) ldi_close(zfs_lh, FREAD|FWRITE, kcred); 3407 return (rc); 3408 } 3409