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 sli->sli_mgmt_url_offset = BSWAP_64(sli->sli_mgmt_url_offset); 829 } 830 831 sbd_status_t 832 sbd_load_section_hdr(sbd_lu_t *sl, sm_section_hdr_t *sms) 833 { 834 sm_section_hdr_t h; 835 uint64_t st; 836 sbd_status_t ret; 837 838 for (st = sl->sl_meta_offset + sizeof (sbd_meta_start_t); 839 st < sl->sl_meta_size_used; st += h.sms_size) { 840 if ((ret = sbd_read_meta(sl, st, sizeof (sm_section_hdr_t), 841 (uint8_t *)&h)) != SBD_SUCCESS) { 842 return (ret); 843 } 844 if (h.sms_data_order != SMS_DATA_ORDER) { 845 sbd_swap_section_hdr(&h); 846 } 847 if ((h.sms_data_order != SMS_DATA_ORDER) || 848 (h.sms_offset != st) || (h.sms_size < sizeof (h)) || 849 ((st + h.sms_size) > sl->sl_meta_size_used)) { 850 return (SBD_META_CORRUPTED); 851 } 852 if (h.sms_id == sms->sms_id) { 853 bcopy(&h, sms, sizeof (h)); 854 return (SBD_SUCCESS); 855 } 856 } 857 858 return (SBD_NOT_FOUND); 859 } 860 861 sbd_status_t 862 sbd_load_meta_start(sbd_lu_t *sl) 863 { 864 sbd_meta_start_t *sm; 865 sbd_status_t ret; 866 867 /* Fake meta params initially */ 868 sl->sl_total_meta_size = (uint64_t)-1; 869 sl->sl_meta_size_used = sl->sl_meta_offset + sizeof (sbd_meta_start_t); 870 871 sm = kmem_zalloc(sizeof (*sm), KM_SLEEP); 872 ret = sbd_read_meta(sl, sl->sl_meta_offset, sizeof (*sm), 873 (uint8_t *)sm); 874 if (ret != SBD_SUCCESS) { 875 goto load_meta_start_failed; 876 } 877 878 if (sm->sm_magic != SBD_MAGIC) { 879 sbd_swap_meta_start(sm); 880 } 881 882 if ((sm->sm_magic != SBD_MAGIC) || (sbd_calc_sum((uint8_t *)sm, 883 sizeof (*sm) - 1) != sm->sm_chksum)) { 884 ret = SBD_META_CORRUPTED; 885 goto load_meta_start_failed; 886 } 887 888 if (sm->sm_ver_major != SBD_VER_MAJOR) { 889 ret = SBD_NOT_SUPPORTED; 890 goto load_meta_start_failed; 891 } 892 893 sl->sl_total_meta_size = sm->sm_meta_size; 894 sl->sl_meta_size_used = sm->sm_meta_size_used; 895 ret = SBD_SUCCESS; 896 897 load_meta_start_failed: 898 kmem_free(sm, sizeof (*sm)); 899 return (ret); 900 } 901 902 sbd_status_t 903 sbd_write_meta_start(sbd_lu_t *sl, uint64_t meta_size, uint64_t meta_size_used) 904 { 905 sbd_meta_start_t *sm; 906 sbd_status_t ret; 907 908 sm = (sbd_meta_start_t *)kmem_zalloc(sizeof (sbd_meta_start_t), 909 KM_SLEEP); 910 911 sm->sm_magic = SBD_MAGIC; 912 sm->sm_meta_size = meta_size; 913 sm->sm_meta_size_used = meta_size_used; 914 sm->sm_ver_major = SBD_VER_MAJOR; 915 sm->sm_ver_minor = SBD_VER_MINOR; 916 sm->sm_ver_subminor = SBD_VER_SUBMINOR; 917 sm->sm_chksum = sbd_calc_sum((uint8_t *)sm, sizeof (*sm) - 1); 918 919 ret = sbd_write_meta(sl, sl->sl_meta_offset, sizeof (*sm), 920 (uint8_t *)sm); 921 kmem_free(sm, sizeof (*sm)); 922 923 return (ret); 924 } 925 926 sbd_status_t 927 sbd_read_meta_section(sbd_lu_t *sl, sm_section_hdr_t **ppsms, uint16_t sms_id) 928 { 929 sbd_status_t ret; 930 sm_section_hdr_t sms; 931 int alloced = 0; 932 933 mutex_enter(&sl->sl_metadata_lock); 934 if (((*ppsms) == NULL) || ((*ppsms)->sms_offset == 0)) { 935 bzero(&sms, sizeof (sm_section_hdr_t)); 936 sms.sms_id = sms_id; 937 if ((ret = sbd_load_section_hdr(sl, &sms)) != SBD_SUCCESS) { 938 mutex_exit(&sl->sl_metadata_lock); 939 return (ret); 940 } else { 941 if ((*ppsms) == NULL) { 942 *ppsms = (sm_section_hdr_t *)kmem_zalloc( 943 sms.sms_size, KM_SLEEP); 944 alloced = 1; 945 } 946 bcopy(&sms, *ppsms, sizeof (sm_section_hdr_t)); 947 } 948 } 949 950 ret = sbd_read_meta(sl, (*ppsms)->sms_offset, (*ppsms)->sms_size, 951 (uint8_t *)(*ppsms)); 952 if (ret == SBD_SUCCESS) { 953 uint8_t s; 954 if ((*ppsms)->sms_data_order != SMS_DATA_ORDER) 955 sbd_swap_section_hdr(*ppsms); 956 if ((*ppsms)->sms_id != SMS_ID_UNUSED) { 957 s = sbd_calc_section_sum(*ppsms, (*ppsms)->sms_size); 958 if (s != (*ppsms)->sms_chksum) 959 ret = SBD_META_CORRUPTED; 960 } 961 } 962 mutex_exit(&sl->sl_metadata_lock); 963 964 if ((ret != SBD_SUCCESS) && alloced) 965 kmem_free(*ppsms, sms.sms_size); 966 return (ret); 967 } 968 969 sbd_status_t 970 sbd_load_section_hdr_unbuffered(sbd_lu_t *sl, sm_section_hdr_t *sms) 971 { 972 sbd_status_t ret; 973 974 /* 975 * Bypass buffering and re-read the meta data from permanent storage. 976 */ 977 if (sl->sl_flags & SL_ZFS_META) { 978 if ((ret = sbd_open_zfs_meta(sl)) != SBD_SUCCESS) { 979 return (ret); 980 } 981 } 982 /* Re-get the meta sizes into sl */ 983 if ((ret = sbd_load_meta_start(sl)) != SBD_SUCCESS) { 984 return (ret); 985 } 986 return (sbd_load_section_hdr(sl, sms)); 987 } 988 989 sbd_status_t 990 sbd_write_meta_section(sbd_lu_t *sl, sm_section_hdr_t *sms) 991 { 992 sm_section_hdr_t t; 993 uint64_t off, s; 994 uint64_t unused_start; 995 sbd_status_t ret; 996 sbd_status_t write_meta_ret = SBD_SUCCESS; 997 uint8_t *cb; 998 int meta_size_changed = 0; 999 sm_section_hdr_t sms_before_unused = {0}; 1000 1001 mutex_enter(&sl->sl_metadata_lock); 1002 write_meta_section_again: 1003 if (sms->sms_offset) { 1004 /* 1005 * If the section already exists and the size is the 1006 * same as this new data then overwrite in place. If 1007 * the sizes are different then mark the existing as 1008 * unused and look for free space. 1009 */ 1010 ret = sbd_read_meta(sl, sms->sms_offset, sizeof (t), 1011 (uint8_t *)&t); 1012 if (ret != SBD_SUCCESS) { 1013 mutex_exit(&sl->sl_metadata_lock); 1014 return (ret); 1015 } 1016 if (t.sms_data_order != SMS_DATA_ORDER) { 1017 sbd_swap_section_hdr(&t); 1018 } 1019 if (t.sms_id != sms->sms_id) { 1020 mutex_exit(&sl->sl_metadata_lock); 1021 return (SBD_INVALID_ARG); 1022 } 1023 if (t.sms_size == sms->sms_size) { 1024 ret = sbd_write_meta(sl, sms->sms_offset, 1025 sms->sms_size, (uint8_t *)sms); 1026 mutex_exit(&sl->sl_metadata_lock); 1027 return (ret); 1028 } 1029 sms_before_unused = t; 1030 1031 t.sms_id = SMS_ID_UNUSED; 1032 /* 1033 * For unused sections we only use chksum of the header. for 1034 * all other sections, the chksum is for the entire section. 1035 */ 1036 t.sms_chksum = sbd_calc_section_sum(&t, sizeof (t)); 1037 ret = sbd_write_meta(sl, t.sms_offset, sizeof (t), 1038 (uint8_t *)&t); 1039 if (ret != SBD_SUCCESS) { 1040 mutex_exit(&sl->sl_metadata_lock); 1041 return (ret); 1042 } 1043 sms->sms_offset = 0; 1044 } else { 1045 /* Section location is unknown, search for it. */ 1046 t.sms_id = sms->sms_id; 1047 t.sms_data_order = SMS_DATA_ORDER; 1048 ret = sbd_load_section_hdr(sl, &t); 1049 if (ret == SBD_SUCCESS) { 1050 sms->sms_offset = t.sms_offset; 1051 sms->sms_chksum = 1052 sbd_calc_section_sum(sms, sms->sms_size); 1053 goto write_meta_section_again; 1054 } else if (ret != SBD_NOT_FOUND) { 1055 mutex_exit(&sl->sl_metadata_lock); 1056 return (ret); 1057 } 1058 } 1059 1060 /* 1061 * At this point we know that section does not already exist. 1062 * Find space large enough to hold the section or grow meta if 1063 * possible. 1064 */ 1065 unused_start = 0; 1066 s = 0; /* size of space found */ 1067 1068 /* 1069 * Search all sections for unused space of sufficient size. 1070 * The first one found is taken. Contiguous unused sections 1071 * will be combined. 1072 */ 1073 for (off = sl->sl_meta_offset + sizeof (sbd_meta_start_t); 1074 off < sl->sl_meta_size_used; off += t.sms_size) { 1075 ret = sbd_read_meta(sl, off, sizeof (t), (uint8_t *)&t); 1076 if (ret != SBD_SUCCESS) { 1077 mutex_exit(&sl->sl_metadata_lock); 1078 return (ret); 1079 } 1080 if (t.sms_data_order != SMS_DATA_ORDER) 1081 sbd_swap_section_hdr(&t); 1082 if (t.sms_size == 0) { 1083 mutex_exit(&sl->sl_metadata_lock); 1084 return (SBD_META_CORRUPTED); 1085 } 1086 if (t.sms_id == SMS_ID_UNUSED) { 1087 if (unused_start == 0) 1088 unused_start = off; 1089 /* 1090 * Calculate size of the unused space, break out 1091 * if it satisfies the requirement. 1092 */ 1093 s = t.sms_size - unused_start + off; 1094 if ((s == sms->sms_size) || (s >= (sms->sms_size + 1095 sizeof (t)))) { 1096 break; 1097 } else { 1098 s = 0; 1099 } 1100 } else { 1101 unused_start = 0; 1102 } 1103 } 1104 1105 off = (unused_start == 0) ? sl->sl_meta_size_used : unused_start; 1106 /* 1107 * If none found, how much room is at the end? 1108 * See if the data can be expanded. 1109 */ 1110 if (s == 0) { 1111 s = sl->sl_total_meta_size - off; 1112 if (s >= sms->sms_size || !(sl->sl_flags & SL_SHARED_META)) { 1113 s = sms->sms_size; 1114 meta_size_changed = 1; 1115 } else { 1116 s = 0; 1117 } 1118 } 1119 1120 if (s == 0) { 1121 mutex_exit(&sl->sl_metadata_lock); 1122 return (SBD_ALLOC_FAILURE); 1123 } 1124 1125 sms->sms_offset = off; 1126 sms->sms_chksum = sbd_calc_section_sum(sms, sms->sms_size); 1127 /* 1128 * Since we may have to write more than one section (current + 1129 * any unused), use a combined buffer. 1130 */ 1131 cb = kmem_zalloc(s, KM_SLEEP); 1132 bcopy(sms, cb, sms->sms_size); 1133 if (s > sms->sms_size) { 1134 t.sms_offset = off + sms->sms_size; 1135 t.sms_size = s - sms->sms_size; 1136 t.sms_id = SMS_ID_UNUSED; 1137 t.sms_data_order = SMS_DATA_ORDER; 1138 t.sms_chksum = sbd_calc_section_sum(&t, sizeof (t)); 1139 bcopy(&t, cb + sms->sms_size, sizeof (t)); 1140 } 1141 /* 1142 * Two write events & statuses take place. Failure writing the 1143 * meta section takes precedence, can possibly be rolled back, 1144 * & gets reported. Else return status from writing the meta start. 1145 */ 1146 ret = SBD_SUCCESS; /* Set a default, it's not always loaded below. */ 1147 if (meta_size_changed) { 1148 uint64_t old_meta_size; 1149 uint64_t old_sz_used = sl->sl_meta_size_used; /* save a copy */ 1150 old_meta_size = sl->sl_total_meta_size; /* save a copy */ 1151 1152 write_meta_ret = sbd_write_meta(sl, off, s, cb); 1153 if (write_meta_ret == SBD_SUCCESS) { 1154 sl->sl_meta_size_used = off + s; 1155 if (sl->sl_total_meta_size < sl->sl_meta_size_used) { 1156 uint64_t meta_align = 1157 (((uint64_t)1) << 1158 sl->sl_meta_blocksize_shift) - 1; 1159 sl->sl_total_meta_size = 1160 (sl->sl_meta_size_used + meta_align) & 1161 (~meta_align); 1162 } 1163 ret = sbd_write_meta_start(sl, sl->sl_total_meta_size, 1164 sl->sl_meta_size_used); 1165 if (ret != SBD_SUCCESS) { 1166 sl->sl_meta_size_used = old_sz_used; 1167 sl->sl_total_meta_size = old_meta_size; 1168 } 1169 } else { 1170 sl->sl_meta_size_used = old_sz_used; 1171 sl->sl_total_meta_size = old_meta_size; 1172 } 1173 } else { 1174 write_meta_ret = sbd_write_meta(sl, off, s, cb); 1175 } 1176 if ((write_meta_ret != SBD_SUCCESS) && 1177 (sms_before_unused.sms_offset != 0)) { 1178 sm_section_hdr_t new_sms; 1179 sm_section_hdr_t *unused_sms; 1180 /* 1181 * On failure writing the meta section attempt to undo 1182 * the change to unused. 1183 * Re-read the meta data from permanent storage. 1184 * The section id can't exist for undo to be possible. 1185 * Read what should be the entire old section data and 1186 * insure the old data's still present by validating 1187 * against it's old checksum. 1188 */ 1189 new_sms.sms_id = sms->sms_id; 1190 new_sms.sms_data_order = SMS_DATA_ORDER; 1191 if (sbd_load_section_hdr_unbuffered(sl, &new_sms) != 1192 SBD_NOT_FOUND) { 1193 goto done; 1194 } 1195 unused_sms = kmem_zalloc(sms_before_unused.sms_size, KM_SLEEP); 1196 if (sbd_read_meta(sl, sms_before_unused.sms_offset, 1197 sms_before_unused.sms_size, 1198 (uint8_t *)unused_sms) != SBD_SUCCESS) { 1199 goto done; 1200 } 1201 if (unused_sms->sms_data_order != SMS_DATA_ORDER) { 1202 sbd_swap_section_hdr(unused_sms); 1203 } 1204 if (unused_sms->sms_id != SMS_ID_UNUSED) { 1205 goto done; 1206 } 1207 if (unused_sms->sms_offset != sms_before_unused.sms_offset) { 1208 goto done; 1209 } 1210 if (unused_sms->sms_size != sms_before_unused.sms_size) { 1211 goto done; 1212 } 1213 unused_sms->sms_id = sms_before_unused.sms_id; 1214 if (sbd_calc_section_sum(unused_sms, 1215 sizeof (sm_section_hdr_t)) != 1216 sbd_calc_section_sum(&sms_before_unused, 1217 sizeof (sm_section_hdr_t))) { 1218 goto done; 1219 } 1220 unused_sms->sms_chksum = 1221 sbd_calc_section_sum(unused_sms, unused_sms->sms_size); 1222 if (unused_sms->sms_chksum != sms_before_unused.sms_chksum) { 1223 goto done; 1224 } 1225 (void) sbd_write_meta(sl, unused_sms->sms_offset, 1226 sizeof (sm_section_hdr_t), (uint8_t *)unused_sms); 1227 } 1228 done: 1229 mutex_exit(&sl->sl_metadata_lock); 1230 kmem_free(cb, s); 1231 if (write_meta_ret != SBD_SUCCESS) { 1232 return (write_meta_ret); 1233 } 1234 return (ret); 1235 } 1236 1237 sbd_status_t 1238 sbd_write_lu_info(sbd_lu_t *sl) 1239 { 1240 sbd_lu_info_1_1_t *sli; 1241 int s; 1242 uint8_t *p; 1243 char *zvol_name = NULL; 1244 sbd_status_t ret; 1245 1246 mutex_enter(&sl->sl_lock); 1247 1248 s = sl->sl_serial_no_size; 1249 if ((sl->sl_flags & (SL_SHARED_META | SL_ZFS_META)) == 0) { 1250 if (sl->sl_data_filename) { 1251 s += strlen(sl->sl_data_filename) + 1; 1252 } 1253 } 1254 if (sl->sl_flags & SL_ZFS_META) { 1255 zvol_name = sbd_get_zvol_name(sl); 1256 s += strlen(zvol_name) + 1; 1257 } 1258 if (sl->sl_alias) { 1259 s += strlen(sl->sl_alias) + 1; 1260 } 1261 if (sl->sl_mgmt_url) { 1262 s += strlen(sl->sl_mgmt_url) + 1; 1263 } 1264 sli = (sbd_lu_info_1_1_t *)kmem_zalloc(sizeof (*sli) + s, KM_SLEEP); 1265 p = sli->sli_buf; 1266 if ((sl->sl_flags & (SL_SHARED_META | SL_ZFS_META)) == 0) { 1267 sli->sli_flags |= SLI_SEPARATE_META; 1268 (void) strcpy((char *)p, sl->sl_data_filename); 1269 sli->sli_data_fname_offset = 1270 (uintptr_t)p - (uintptr_t)sli->sli_buf; 1271 sli->sli_flags |= SLI_DATA_FNAME_VALID; 1272 p += strlen(sl->sl_data_filename) + 1; 1273 } 1274 if (sl->sl_flags & SL_ZFS_META) { 1275 (void) strcpy((char *)p, zvol_name); 1276 sli->sli_meta_fname_offset = 1277 (uintptr_t)p - (uintptr_t)sli->sli_buf; 1278 sli->sli_flags |= SLI_META_FNAME_VALID | SLI_ZFS_META; 1279 p += strlen(zvol_name) + 1; 1280 kmem_free(zvol_name, strlen(zvol_name) + 1); 1281 zvol_name = NULL; 1282 } 1283 if (sl->sl_alias) { 1284 (void) strcpy((char *)p, sl->sl_alias); 1285 sli->sli_alias_offset = 1286 (uintptr_t)p - (uintptr_t)sli->sli_buf; 1287 sli->sli_flags |= SLI_ALIAS_VALID; 1288 p += strlen(sl->sl_alias) + 1; 1289 } 1290 if (sl->sl_mgmt_url) { 1291 (void) strcpy((char *)p, sl->sl_mgmt_url); 1292 sli->sli_mgmt_url_offset = 1293 (uintptr_t)p - (uintptr_t)sli->sli_buf; 1294 sli->sli_flags |= SLI_MGMT_URL_VALID; 1295 p += strlen(sl->sl_mgmt_url) + 1; 1296 } 1297 if (sl->sl_flags & SL_WRITE_PROTECTED) { 1298 sli->sli_flags |= SLI_WRITE_PROTECTED; 1299 } 1300 if (sl->sl_flags & SL_SAVED_WRITE_CACHE_DISABLE) { 1301 sli->sli_flags |= SLI_WRITEBACK_CACHE_DISABLE; 1302 } 1303 if (sl->sl_flags & SL_VID_VALID) { 1304 bcopy(sl->sl_vendor_id, sli->sli_vid, 8); 1305 sli->sli_flags |= SLI_VID_VALID; 1306 } 1307 if (sl->sl_flags & SL_PID_VALID) { 1308 bcopy(sl->sl_product_id, sli->sli_pid, 16); 1309 sli->sli_flags |= SLI_PID_VALID; 1310 } 1311 if (sl->sl_flags & SL_REV_VALID) { 1312 bcopy(sl->sl_revision, sli->sli_rev, 4); 1313 sli->sli_flags |= SLI_REV_VALID; 1314 } 1315 if (sl->sl_serial_no_size) { 1316 bcopy(sl->sl_serial_no, p, sl->sl_serial_no_size); 1317 sli->sli_serial_size = sl->sl_serial_no_size; 1318 sli->sli_serial_offset = 1319 (uintptr_t)p - (uintptr_t)sli->sli_buf; 1320 sli->sli_flags |= SLI_SERIAL_VALID; 1321 p += sli->sli_serial_size; 1322 } 1323 sli->sli_lu_size = sl->sl_lu_size; 1324 sli->sli_data_blocksize_shift = sl->sl_data_blocksize_shift; 1325 sli->sli_data_order = SMS_DATA_ORDER; 1326 bcopy(sl->sl_device_id, sli->sli_device_id, 20); 1327 1328 sli->sli_sms_header.sms_size = sizeof (*sli) + s; 1329 sli->sli_sms_header.sms_id = SMS_ID_LU_INFO_1_1; 1330 sli->sli_sms_header.sms_data_order = SMS_DATA_ORDER; 1331 1332 mutex_exit(&sl->sl_lock); 1333 ret = sbd_write_meta_section(sl, (sm_section_hdr_t *)sli); 1334 kmem_free(sli, sizeof (*sli) + s); 1335 return (ret); 1336 } 1337 1338 int 1339 sbd_populate_and_register_lu(sbd_lu_t *sl, uint32_t *err_ret) 1340 { 1341 stmf_lu_t *lu = sl->sl_lu; 1342 stmf_status_t ret; 1343 1344 lu->lu_id = (scsi_devid_desc_t *)sl->sl_device_id; 1345 if (sl->sl_alias) { 1346 lu->lu_alias = sl->sl_alias; 1347 } else { 1348 lu->lu_alias = sl->sl_name; 1349 } 1350 if (sl->sl_access_state == SBD_LU_STANDBY) { 1351 /* call set access state */ 1352 ret = stmf_set_lu_access(lu, STMF_LU_STANDBY); 1353 if (ret != STMF_SUCCESS) { 1354 *err_ret = SBD_RET_ACCESS_STATE_FAILED; 1355 return (EIO); 1356 } 1357 } 1358 /* set proxy_reg_cb_arg to meta filename */ 1359 if (sl->sl_meta_filename) { 1360 lu->lu_proxy_reg_arg = sl->sl_meta_filename; 1361 lu->lu_proxy_reg_arg_len = strlen(sl->sl_meta_filename) + 1; 1362 } else { 1363 lu->lu_proxy_reg_arg = sl->sl_data_filename; 1364 lu->lu_proxy_reg_arg_len = strlen(sl->sl_data_filename) + 1; 1365 } 1366 lu->lu_lp = sbd_lp; 1367 lu->lu_task_alloc = sbd_task_alloc; 1368 lu->lu_new_task = sbd_new_task; 1369 lu->lu_dbuf_xfer_done = sbd_dbuf_xfer_done; 1370 lu->lu_send_status_done = sbd_send_status_done; 1371 lu->lu_task_free = sbd_task_free; 1372 lu->lu_abort = sbd_abort; 1373 lu->lu_ctl = sbd_ctl; 1374 lu->lu_info = sbd_info; 1375 sl->sl_state = STMF_STATE_OFFLINE; 1376 1377 if ((ret = stmf_register_lu(lu)) != STMF_SUCCESS) { 1378 stmf_trace(0, "Failed to register with framework, ret=%llx", 1379 ret); 1380 if (ret == STMF_ALREADY) { 1381 *err_ret = SBD_RET_GUID_ALREADY_REGISTERED; 1382 } 1383 return (EIO); 1384 } 1385 1386 *err_ret = 0; 1387 return (0); 1388 } 1389 1390 int 1391 sbd_open_data_file(sbd_lu_t *sl, uint32_t *err_ret, int lu_size_valid, 1392 int vp_valid, int keep_open) 1393 { 1394 int ret; 1395 int flag; 1396 ulong_t nbits; 1397 uint64_t supported_size; 1398 vattr_t vattr; 1399 enum vtype vt; 1400 1401 mutex_enter(&sl->sl_lock); 1402 if (vp_valid) { 1403 goto odf_over_open; 1404 } 1405 if (sl->sl_data_filename[0] != '/') { 1406 *err_ret = SBD_RET_DATA_PATH_NOT_ABSOLUTE; 1407 mutex_exit(&sl->sl_lock); 1408 return (EINVAL); 1409 } 1410 if ((ret = lookupname(sl->sl_data_filename, UIO_SYSSPACE, FOLLOW, 1411 NULLVPP, &sl->sl_data_vp)) != 0) { 1412 *err_ret = SBD_RET_DATA_FILE_LOOKUP_FAILED; 1413 mutex_exit(&sl->sl_lock); 1414 return (ret); 1415 } 1416 sl->sl_data_vtype = vt = sl->sl_data_vp->v_type; 1417 VN_RELE(sl->sl_data_vp); 1418 if ((vt != VREG) && (vt != VCHR) && (vt != VBLK)) { 1419 *err_ret = SBD_RET_WRONG_DATA_FILE_TYPE; 1420 mutex_exit(&sl->sl_lock); 1421 return (EINVAL); 1422 } 1423 if (sl->sl_flags & SL_WRITE_PROTECTED) { 1424 flag = FREAD | FOFFMAX; 1425 } else { 1426 flag = FREAD | FWRITE | FOFFMAX | FEXCL; 1427 } 1428 if ((ret = vn_open(sl->sl_data_filename, UIO_SYSSPACE, flag, 0, 1429 &sl->sl_data_vp, 0, 0)) != 0) { 1430 *err_ret = SBD_RET_DATA_FILE_OPEN_FAILED; 1431 mutex_exit(&sl->sl_lock); 1432 return (ret); 1433 } 1434 odf_over_open: 1435 vattr.va_mask = AT_SIZE; 1436 if ((ret = VOP_GETATTR(sl->sl_data_vp, &vattr, 0, CRED(), NULL)) != 0) { 1437 *err_ret = SBD_RET_DATA_FILE_GETATTR_FAILED; 1438 goto odf_close_data_and_exit; 1439 } 1440 if ((vt != VREG) && (vattr.va_size == 0)) { 1441 /* 1442 * Its a zero byte block or char device. This cannot be 1443 * a raw disk. 1444 */ 1445 *err_ret = SBD_RET_WRONG_DATA_FILE_TYPE; 1446 ret = EINVAL; 1447 goto odf_close_data_and_exit; 1448 } 1449 /* sl_data_readable size includes any metadata. */ 1450 sl->sl_data_readable_size = vattr.va_size; 1451 if (VOP_PATHCONF(sl->sl_data_vp, _PC_FILESIZEBITS, &nbits, 1452 CRED(), NULL) != 0) { 1453 nbits = 0; 1454 } 1455 /* nbits cannot be greater than 64 */ 1456 sl->sl_data_fs_nbits = (uint8_t)nbits; 1457 if (lu_size_valid) { 1458 sl->sl_total_data_size = sl->sl_lu_size; 1459 if (sl->sl_flags & SL_SHARED_META) { 1460 sl->sl_total_data_size += SHARED_META_DATA_SIZE; 1461 } 1462 if ((nbits > 0) && (nbits < 64)) { 1463 /* 1464 * The expression below is correct only if nbits is 1465 * positive and less than 64. 1466 */ 1467 supported_size = (((uint64_t)1) << nbits) - 1; 1468 if (sl->sl_total_data_size > supported_size) { 1469 *err_ret = SBD_RET_SIZE_NOT_SUPPORTED_BY_FS; 1470 ret = EINVAL; 1471 goto odf_close_data_and_exit; 1472 } 1473 } 1474 } else { 1475 sl->sl_total_data_size = vattr.va_size; 1476 if (sl->sl_flags & SL_SHARED_META) { 1477 if (vattr.va_size > SHARED_META_DATA_SIZE) { 1478 sl->sl_lu_size = vattr.va_size - 1479 SHARED_META_DATA_SIZE; 1480 } else { 1481 *err_ret = SBD_RET_FILE_SIZE_ERROR; 1482 ret = EINVAL; 1483 goto odf_close_data_and_exit; 1484 } 1485 } else { 1486 sl->sl_lu_size = vattr.va_size; 1487 } 1488 } 1489 if (sl->sl_lu_size < SBD_MIN_LU_SIZE) { 1490 *err_ret = SBD_RET_FILE_SIZE_ERROR; 1491 ret = EINVAL; 1492 goto odf_close_data_and_exit; 1493 } 1494 if (sl->sl_lu_size & 1495 ((((uint64_t)1) << sl->sl_data_blocksize_shift) - 1)) { 1496 *err_ret = SBD_RET_FILE_ALIGN_ERROR; 1497 ret = EINVAL; 1498 goto odf_close_data_and_exit; 1499 } 1500 sl->sl_flags |= SL_MEDIA_LOADED; 1501 mutex_exit(&sl->sl_lock); 1502 return (0); 1503 1504 odf_close_data_and_exit: 1505 if (!keep_open) { 1506 (void) VOP_CLOSE(sl->sl_data_vp, flag, 1, 0, CRED(), NULL); 1507 VN_RELE(sl->sl_data_vp); 1508 } 1509 mutex_exit(&sl->sl_lock); 1510 return (ret); 1511 } 1512 1513 void 1514 sbd_close_lu(sbd_lu_t *sl) 1515 { 1516 int flag; 1517 1518 if (((sl->sl_flags & SL_SHARED_META) == 0) && 1519 (sl->sl_flags & SL_META_OPENED)) { 1520 if (sl->sl_flags & SL_ZFS_META) { 1521 rw_destroy(&sl->sl_zfs_meta_lock); 1522 if (sl->sl_zfs_meta) { 1523 kmem_free(sl->sl_zfs_meta, ZAP_MAXVALUELEN / 2); 1524 sl->sl_zfs_meta = NULL; 1525 } 1526 } else { 1527 flag = FREAD | FWRITE | FOFFMAX | FEXCL; 1528 (void) VOP_CLOSE(sl->sl_meta_vp, flag, 1, 0, 1529 CRED(), NULL); 1530 VN_RELE(sl->sl_meta_vp); 1531 } 1532 sl->sl_flags &= ~SL_META_OPENED; 1533 } 1534 if (sl->sl_flags & SL_MEDIA_LOADED) { 1535 if (sl->sl_flags & SL_WRITE_PROTECTED) { 1536 flag = FREAD | FOFFMAX; 1537 } else { 1538 flag = FREAD | FWRITE | FOFFMAX | FEXCL; 1539 } 1540 (void) VOP_CLOSE(sl->sl_data_vp, flag, 1, 0, CRED(), NULL); 1541 VN_RELE(sl->sl_data_vp); 1542 sl->sl_flags &= ~SL_MEDIA_LOADED; 1543 if (sl->sl_flags & SL_SHARED_META) { 1544 sl->sl_flags &= ~SL_META_OPENED; 1545 } 1546 } 1547 } 1548 1549 int 1550 sbd_set_lu_standby(sbd_set_lu_standby_t *stlu, uint32_t *err_ret) 1551 { 1552 sbd_lu_t *sl; 1553 sbd_status_t sret; 1554 stmf_status_t stret; 1555 1556 sret = sbd_find_and_lock_lu(stlu->stlu_guid, NULL, 1557 SL_OP_MODIFY_LU, &sl); 1558 if (sret != SBD_SUCCESS) { 1559 if (sret == SBD_BUSY) { 1560 *err_ret = SBD_RET_LU_BUSY; 1561 return (EBUSY); 1562 } else if (sret == SBD_NOT_FOUND) { 1563 *err_ret = SBD_RET_NOT_FOUND; 1564 return (ENOENT); 1565 } 1566 *err_ret = SBD_RET_ACCESS_STATE_FAILED; 1567 return (EIO); 1568 } 1569 1570 sl->sl_access_state = SBD_LU_TRANSITION_TO_STANDBY; 1571 stret = stmf_set_lu_access((stmf_lu_t *)sl->sl_lu, STMF_LU_STANDBY); 1572 if (stret != STMF_SUCCESS) { 1573 sl->sl_trans_op = SL_OP_NONE; 1574 *err_ret = SBD_RET_ACCESS_STATE_FAILED; 1575 sl->sl_access_state = SBD_LU_TRANSITION_TO_STANDBY; 1576 return (EIO); 1577 } 1578 1579 /* 1580 * acquire the writer lock here to ensure we're not pulling 1581 * the rug from the vn_rdwr to the backing store 1582 */ 1583 rw_enter(&sl->sl_access_state_lock, RW_WRITER); 1584 sbd_close_lu(sl); 1585 rw_exit(&sl->sl_access_state_lock); 1586 1587 sl->sl_trans_op = SL_OP_NONE; 1588 return (0); 1589 } 1590 1591 int 1592 sbd_close_delete_lu(sbd_lu_t *sl, int ret) 1593 { 1594 1595 /* 1596 * acquire the writer lock here to ensure we're not pulling 1597 * the rug from the vn_rdwr to the backing store 1598 */ 1599 rw_enter(&sl->sl_access_state_lock, RW_WRITER); 1600 sbd_close_lu(sl); 1601 rw_exit(&sl->sl_access_state_lock); 1602 1603 if (sl->sl_flags & SL_LINKED) 1604 sbd_unlink_lu(sl); 1605 mutex_destroy(&sl->sl_metadata_lock); 1606 mutex_destroy(&sl->sl_lock); 1607 rw_destroy(&sl->sl_pgr->pgr_lock); 1608 rw_destroy(&sl->sl_access_state_lock); 1609 if (sl->sl_serial_no_alloc_size) { 1610 kmem_free(sl->sl_serial_no, sl->sl_serial_no_alloc_size); 1611 } 1612 if (sl->sl_data_fname_alloc_size) { 1613 kmem_free(sl->sl_data_filename, sl->sl_data_fname_alloc_size); 1614 } 1615 if (sl->sl_alias_alloc_size) { 1616 kmem_free(sl->sl_alias, sl->sl_alias_alloc_size); 1617 } 1618 if (sl->sl_mgmt_url_alloc_size) { 1619 kmem_free(sl->sl_mgmt_url, sl->sl_mgmt_url_alloc_size); 1620 } 1621 stmf_free(sl->sl_lu); 1622 return (ret); 1623 } 1624 1625 int 1626 sbd_create_register_lu(sbd_create_and_reg_lu_t *slu, int struct_sz, 1627 uint32_t *err_ret) 1628 { 1629 char *namebuf; 1630 sbd_lu_t *sl; 1631 stmf_lu_t *lu; 1632 sbd_status_t sret; 1633 char *p; 1634 int sz; 1635 int alloc_sz; 1636 int ret = EIO; 1637 int flag; 1638 int wcd = 0; 1639 uint32_t hid = 0; 1640 enum vtype vt; 1641 1642 sz = struct_sz - sizeof (sbd_create_and_reg_lu_t) + 8 + 1; 1643 1644 *err_ret = 0; 1645 1646 /* Lets validate various offsets */ 1647 if (((slu->slu_meta_fname_valid) && 1648 (slu->slu_meta_fname_off >= sz)) || 1649 (slu->slu_data_fname_off >= sz) || 1650 ((slu->slu_alias_valid) && 1651 (slu->slu_alias_off >= sz)) || 1652 ((slu->slu_mgmt_url_valid) && 1653 (slu->slu_mgmt_url_off >= sz)) || 1654 ((slu->slu_serial_valid) && 1655 ((slu->slu_serial_off + slu->slu_serial_size) >= sz))) { 1656 return (EINVAL); 1657 } 1658 1659 namebuf = kmem_zalloc(sz, KM_SLEEP); 1660 bcopy(slu->slu_buf, namebuf, sz - 1); 1661 namebuf[sz - 1] = 0; 1662 1663 alloc_sz = sizeof (sbd_lu_t) + sizeof (sbd_pgr_t); 1664 if (slu->slu_meta_fname_valid) { 1665 alloc_sz += strlen(namebuf + slu->slu_meta_fname_off) + 1; 1666 } 1667 alloc_sz += strlen(namebuf + slu->slu_data_fname_off) + 1; 1668 if (slu->slu_alias_valid) { 1669 alloc_sz += strlen(namebuf + slu->slu_alias_off) + 1; 1670 } 1671 if (slu->slu_mgmt_url_valid) { 1672 alloc_sz += strlen(namebuf + slu->slu_mgmt_url_off) + 1; 1673 } 1674 if (slu->slu_serial_valid) { 1675 alloc_sz += slu->slu_serial_size; 1676 } 1677 1678 lu = (stmf_lu_t *)stmf_alloc(STMF_STRUCT_STMF_LU, alloc_sz, 0); 1679 if (lu == NULL) { 1680 kmem_free(namebuf, sz); 1681 return (ENOMEM); 1682 } 1683 sl = (sbd_lu_t *)lu->lu_provider_private; 1684 bzero(sl, alloc_sz); 1685 sl->sl_lu = lu; 1686 sl->sl_alloc_size = alloc_sz; 1687 sl->sl_pgr = (sbd_pgr_t *)(sl + 1); 1688 rw_init(&sl->sl_pgr->pgr_lock, NULL, RW_DRIVER, NULL); 1689 mutex_init(&sl->sl_lock, NULL, MUTEX_DRIVER, NULL); 1690 mutex_init(&sl->sl_metadata_lock, NULL, MUTEX_DRIVER, NULL); 1691 rw_init(&sl->sl_access_state_lock, NULL, RW_DRIVER, NULL); 1692 p = ((char *)sl) + sizeof (sbd_lu_t) + sizeof (sbd_pgr_t); 1693 sl->sl_data_filename = p; 1694 (void) strcpy(sl->sl_data_filename, namebuf + slu->slu_data_fname_off); 1695 p += strlen(sl->sl_data_filename) + 1; 1696 sl->sl_meta_offset = SBD_META_OFFSET; 1697 sl->sl_access_state = SBD_LU_ACTIVE; 1698 if (slu->slu_meta_fname_valid) { 1699 sl->sl_alias = sl->sl_name = sl->sl_meta_filename = p; 1700 (void) strcpy(sl->sl_meta_filename, namebuf + 1701 slu->slu_meta_fname_off); 1702 p += strlen(sl->sl_meta_filename) + 1; 1703 } else { 1704 sl->sl_alias = sl->sl_name = sl->sl_data_filename; 1705 if (sbd_is_zvol(sl->sl_data_filename)) { 1706 sl->sl_flags |= SL_ZFS_META; 1707 sl->sl_meta_offset = 0; 1708 } else { 1709 sl->sl_flags |= SL_SHARED_META; 1710 sl->sl_data_offset = SHARED_META_DATA_SIZE; 1711 sl->sl_total_meta_size = SHARED_META_DATA_SIZE; 1712 sl->sl_meta_size_used = 0; 1713 } 1714 } 1715 if (slu->slu_alias_valid) { 1716 sl->sl_alias = p; 1717 (void) strcpy(p, namebuf + slu->slu_alias_off); 1718 p += strlen(sl->sl_alias) + 1; 1719 } 1720 if (slu->slu_mgmt_url_valid) { 1721 sl->sl_mgmt_url = p; 1722 (void) strcpy(p, namebuf + slu->slu_mgmt_url_off); 1723 p += strlen(sl->sl_mgmt_url) + 1; 1724 } 1725 if (slu->slu_serial_valid) { 1726 sl->sl_serial_no = (uint8_t *)p; 1727 bcopy(namebuf + slu->slu_serial_off, sl->sl_serial_no, 1728 slu->slu_serial_size); 1729 sl->sl_serial_no_size = slu->slu_serial_size; 1730 p += slu->slu_serial_size; 1731 } 1732 kmem_free(namebuf, sz); 1733 if (slu->slu_vid_valid) { 1734 bcopy(slu->slu_vid, sl->sl_vendor_id, 8); 1735 sl->sl_flags |= SL_VID_VALID; 1736 } 1737 if (slu->slu_pid_valid) { 1738 bcopy(slu->slu_pid, sl->sl_product_id, 16); 1739 sl->sl_flags |= SL_PID_VALID; 1740 } 1741 if (slu->slu_rev_valid) { 1742 bcopy(slu->slu_rev, sl->sl_revision, 4); 1743 sl->sl_flags |= SL_REV_VALID; 1744 } 1745 if (slu->slu_write_protected) { 1746 sl->sl_flags |= SL_WRITE_PROTECTED; 1747 } 1748 if (slu->slu_writeback_cache_disable) { 1749 sl->sl_flags |= SL_WRITEBACK_CACHE_DISABLE | 1750 SL_SAVED_WRITE_CACHE_DISABLE; 1751 } 1752 1753 if (slu->slu_blksize_valid) { 1754 if ((slu->slu_blksize & (slu->slu_blksize - 1)) || 1755 (slu->slu_blksize > (32 * 1024)) || 1756 (slu->slu_blksize == 0)) { 1757 *err_ret = SBD_RET_INVALID_BLKSIZE; 1758 ret = EINVAL; 1759 goto scm_err_out; 1760 } 1761 while ((1 << sl->sl_data_blocksize_shift) != slu->slu_blksize) { 1762 sl->sl_data_blocksize_shift++; 1763 } 1764 } else { 1765 sl->sl_data_blocksize_shift = 9; /* 512 by default */ 1766 slu->slu_blksize = 512; 1767 } 1768 1769 /* Now lets start creating meta */ 1770 sl->sl_trans_op = SL_OP_CREATE_REGISTER_LU; 1771 if (sbd_link_lu(sl) != SBD_SUCCESS) { 1772 *err_ret = SBD_RET_FILE_ALREADY_REGISTERED; 1773 ret = EALREADY; 1774 goto scm_err_out; 1775 } 1776 1777 /* 1st focus on the data store */ 1778 if (slu->slu_lu_size_valid) { 1779 sl->sl_lu_size = slu->slu_lu_size; 1780 } 1781 ret = sbd_open_data_file(sl, err_ret, slu->slu_lu_size_valid, 0, 0); 1782 slu->slu_ret_filesize_nbits = sl->sl_data_fs_nbits; 1783 slu->slu_lu_size = sl->sl_lu_size; 1784 if (ret) { 1785 goto scm_err_out; 1786 } 1787 1788 /* 1789 * set write cache disable on the device 1790 * if it fails, we'll support it using sync/flush 1791 */ 1792 if (slu->slu_writeback_cache_disable) { 1793 (void) sbd_wcd_set(1, sl); 1794 wcd = 1; 1795 /* 1796 * Attempt to set it to enable, if that fails and it was explicitly set 1797 * return an error, otherwise get the current setting and use that 1798 */ 1799 } else { 1800 sret = sbd_wcd_set(0, sl); 1801 if (slu->slu_writeback_cache_disable_valid && 1802 sret != SBD_SUCCESS) { 1803 *err_ret = SBD_RET_WRITE_CACHE_SET_FAILED; 1804 ret = EFAULT; 1805 goto scm_err_out; 1806 } 1807 if (sret != SBD_SUCCESS) { 1808 sbd_wcd_get(&wcd, sl); 1809 } 1810 } 1811 1812 if (wcd) { 1813 sl->sl_flags |= SL_WRITEBACK_CACHE_DISABLE | 1814 SL_SAVED_WRITE_CACHE_DISABLE; 1815 } 1816 1817 if (sl->sl_flags & SL_SHARED_META) { 1818 goto over_meta_open; 1819 } 1820 if (sl->sl_flags & SL_ZFS_META) { 1821 if (sbd_create_zfs_meta_object(sl) != SBD_SUCCESS) { 1822 *err_ret = SBD_RET_ZFS_META_CREATE_FAILED; 1823 ret = ENOMEM; 1824 goto scm_err_out; 1825 } 1826 sl->sl_meta_blocksize_shift = 0; 1827 goto over_meta_create; 1828 } 1829 if ((ret = lookupname(sl->sl_meta_filename, UIO_SYSSPACE, FOLLOW, 1830 NULLVPP, &sl->sl_meta_vp)) != 0) { 1831 *err_ret = SBD_RET_META_FILE_LOOKUP_FAILED; 1832 goto scm_err_out; 1833 } 1834 sl->sl_meta_vtype = vt = sl->sl_meta_vp->v_type; 1835 VN_RELE(sl->sl_meta_vp); 1836 if ((vt != VREG) && (vt != VCHR) && (vt != VBLK)) { 1837 *err_ret = SBD_RET_WRONG_META_FILE_TYPE; 1838 ret = EINVAL; 1839 goto scm_err_out; 1840 } 1841 if (vt == VREG) { 1842 sl->sl_meta_blocksize_shift = 0; 1843 } else { 1844 sl->sl_meta_blocksize_shift = 9; 1845 } 1846 flag = FREAD | FWRITE | FOFFMAX | FEXCL; 1847 if ((ret = vn_open(sl->sl_meta_filename, UIO_SYSSPACE, flag, 0, 1848 &sl->sl_meta_vp, 0, 0)) != 0) { 1849 *err_ret = SBD_RET_META_FILE_OPEN_FAILED; 1850 goto scm_err_out; 1851 } 1852 over_meta_create: 1853 sl->sl_total_meta_size = sl->sl_meta_offset + sizeof (sbd_meta_start_t); 1854 sl->sl_total_meta_size += 1855 (((uint64_t)1) << sl->sl_meta_blocksize_shift) - 1; 1856 sl->sl_total_meta_size &= 1857 ~((((uint64_t)1) << sl->sl_meta_blocksize_shift) - 1); 1858 sl->sl_meta_size_used = 0; 1859 over_meta_open: 1860 sl->sl_flags |= SL_META_OPENED; 1861 1862 sl->sl_device_id[3] = 16; 1863 if (slu->slu_guid_valid) { 1864 sl->sl_device_id[0] = 0xf1; 1865 sl->sl_device_id[1] = 3; 1866 sl->sl_device_id[2] = 0; 1867 bcopy(slu->slu_guid, sl->sl_device_id + 4, 16); 1868 } else { 1869 if (slu->slu_host_id_valid) 1870 hid = slu->slu_host_id; 1871 if (!slu->slu_company_id_valid) 1872 slu->slu_company_id = COMPANY_ID_SUN; 1873 if (stmf_scsilib_uniq_lu_id2(slu->slu_company_id, hid, 1874 (scsi_devid_desc_t *)&sl->sl_device_id[0]) != 1875 STMF_SUCCESS) { 1876 *err_ret = SBD_RET_META_CREATION_FAILED; 1877 ret = EIO; 1878 goto scm_err_out; 1879 } 1880 bcopy(sl->sl_device_id + 4, slu->slu_guid, 16); 1881 } 1882 1883 /* Lets create the meta now */ 1884 mutex_enter(&sl->sl_metadata_lock); 1885 if (sbd_write_meta_start(sl, sl->sl_total_meta_size, 1886 sizeof (sbd_meta_start_t)) != SBD_SUCCESS) { 1887 mutex_exit(&sl->sl_metadata_lock); 1888 *err_ret = SBD_RET_META_CREATION_FAILED; 1889 ret = EIO; 1890 goto scm_err_out; 1891 } 1892 mutex_exit(&sl->sl_metadata_lock); 1893 sl->sl_meta_size_used = sl->sl_meta_offset + sizeof (sbd_meta_start_t); 1894 1895 if (sbd_write_lu_info(sl) != SBD_SUCCESS) { 1896 *err_ret = SBD_RET_META_CREATION_FAILED; 1897 ret = EIO; 1898 goto scm_err_out; 1899 } 1900 1901 if (sbd_pgr_meta_init(sl) != SBD_SUCCESS) { 1902 *err_ret = SBD_RET_META_CREATION_FAILED; 1903 ret = EIO; 1904 goto scm_err_out; 1905 } 1906 1907 ret = sbd_populate_and_register_lu(sl, err_ret); 1908 if (ret) { 1909 goto scm_err_out; 1910 } 1911 1912 sl->sl_trans_op = SL_OP_NONE; 1913 atomic_add_32(&sbd_lu_count, 1); 1914 return (0); 1915 1916 scm_err_out: 1917 return (sbd_close_delete_lu(sl, ret)); 1918 } 1919 1920 stmf_status_t 1921 sbd_proxy_msg(uint8_t *luid, void *proxy_arg, uint32_t proxy_arg_len, 1922 uint32_t type) 1923 { 1924 switch (type) { 1925 case STMF_MSG_LU_ACTIVE: 1926 return (sbd_proxy_reg_lu(luid, proxy_arg, 1927 proxy_arg_len)); 1928 case STMF_MSG_LU_REGISTER: 1929 return (sbd_proxy_reg_lu(luid, proxy_arg, 1930 proxy_arg_len)); 1931 case STMF_MSG_LU_DEREGISTER: 1932 return (sbd_proxy_dereg_lu(luid, proxy_arg, 1933 proxy_arg_len)); 1934 default: 1935 return (STMF_INVALID_ARG); 1936 } 1937 } 1938 1939 1940 /* 1941 * register a standby logical unit 1942 * proxy_reg_arg contains the meta filename 1943 */ 1944 stmf_status_t 1945 sbd_proxy_reg_lu(uint8_t *luid, void *proxy_reg_arg, uint32_t proxy_reg_arg_len) 1946 { 1947 sbd_lu_t *sl; 1948 sbd_status_t sret; 1949 sbd_create_standby_lu_t *stlu; 1950 int alloc_sz; 1951 uint32_t err_ret = 0; 1952 stmf_status_t stret = STMF_SUCCESS; 1953 1954 if (luid == NULL) { 1955 return (STMF_INVALID_ARG); 1956 } 1957 1958 do { 1959 sret = sbd_find_and_lock_lu(luid, NULL, SL_OP_MODIFY_LU, &sl); 1960 } while (sret == SBD_BUSY); 1961 1962 if (sret == SBD_NOT_FOUND) { 1963 alloc_sz = sizeof (*stlu) + proxy_reg_arg_len - 8; 1964 stlu = (sbd_create_standby_lu_t *)kmem_zalloc(alloc_sz, 1965 KM_SLEEP); 1966 bcopy(luid, stlu->stlu_guid, 16); 1967 if (proxy_reg_arg_len) { 1968 bcopy(proxy_reg_arg, stlu->stlu_meta_fname, 1969 proxy_reg_arg_len); 1970 stlu->stlu_meta_fname_size = proxy_reg_arg_len; 1971 } 1972 if (sbd_create_standby_lu(stlu, &err_ret) != 0) { 1973 cmn_err(CE_WARN, 1974 "Unable to create standby logical unit for %s", 1975 stlu->stlu_meta_fname); 1976 stret = STMF_FAILURE; 1977 } 1978 kmem_free(stlu, alloc_sz); 1979 return (stret); 1980 } else if (sret == SBD_SUCCESS) { 1981 /* 1982 * if the lu is already registered, then the lu should now 1983 * be in standby mode 1984 */ 1985 sbd_it_data_t *it; 1986 if (sl->sl_access_state != SBD_LU_STANDBY) { 1987 mutex_enter(&sl->sl_lock); 1988 sl->sl_access_state = SBD_LU_STANDBY; 1989 for (it = sl->sl_it_list; it != NULL; 1990 it = it->sbd_it_next) { 1991 it->sbd_it_ua_conditions |= 1992 SBD_UA_ASYMMETRIC_ACCESS_CHANGED; 1993 it->sbd_it_flags &= 1994 ~SBD_IT_HAS_SCSI2_RESERVATION; 1995 sl->sl_flags &= ~SL_LU_HAS_SCSI2_RESERVATION; 1996 } 1997 mutex_exit(&sl->sl_lock); 1998 sbd_pgr_reset(sl); 1999 } 2000 sl->sl_trans_op = SL_OP_NONE; 2001 } else { 2002 cmn_err(CE_WARN, "could not find and lock logical unit"); 2003 stret = STMF_FAILURE; 2004 } 2005 out: 2006 return (stret); 2007 } 2008 2009 /* ARGSUSED */ 2010 stmf_status_t 2011 sbd_proxy_dereg_lu(uint8_t *luid, void *proxy_reg_arg, 2012 uint32_t proxy_reg_arg_len) 2013 { 2014 sbd_delete_lu_t dlu = {0}; 2015 uint32_t err_ret; 2016 2017 if (luid == NULL) { 2018 cmn_err(CE_WARN, "de-register lu request had null luid"); 2019 return (STMF_INVALID_ARG); 2020 } 2021 2022 bcopy(luid, &dlu.dlu_guid, 16); 2023 2024 if (sbd_delete_lu(&dlu, (int)sizeof (dlu), &err_ret) != 0) { 2025 cmn_err(CE_WARN, "failed to delete de-register lu request"); 2026 return (STMF_FAILURE); 2027 } 2028 2029 return (STMF_SUCCESS); 2030 } 2031 2032 int 2033 sbd_create_standby_lu(sbd_create_standby_lu_t *slu, uint32_t *err_ret) 2034 { 2035 sbd_lu_t *sl; 2036 stmf_lu_t *lu; 2037 int ret = EIO; 2038 int alloc_sz; 2039 2040 alloc_sz = sizeof (sbd_lu_t) + sizeof (sbd_pgr_t) + 2041 slu->stlu_meta_fname_size; 2042 lu = (stmf_lu_t *)stmf_alloc(STMF_STRUCT_STMF_LU, alloc_sz, 0); 2043 if (lu == NULL) { 2044 return (ENOMEM); 2045 } 2046 sl = (sbd_lu_t *)lu->lu_provider_private; 2047 bzero(sl, alloc_sz); 2048 sl->sl_lu = lu; 2049 sl->sl_alloc_size = alloc_sz; 2050 2051 sl->sl_pgr = (sbd_pgr_t *)(sl + 1); 2052 sl->sl_meta_filename = ((char *)sl) + sizeof (sbd_lu_t) + 2053 sizeof (sbd_pgr_t); 2054 2055 if (slu->stlu_meta_fname_size > 0) { 2056 (void) strcpy(sl->sl_meta_filename, slu->stlu_meta_fname); 2057 } 2058 sl->sl_name = sl->sl_meta_filename; 2059 2060 sl->sl_device_id[3] = 16; 2061 sl->sl_device_id[0] = 0xf1; 2062 sl->sl_device_id[1] = 3; 2063 sl->sl_device_id[2] = 0; 2064 bcopy(slu->stlu_guid, sl->sl_device_id + 4, 16); 2065 lu->lu_id = (scsi_devid_desc_t *)sl->sl_device_id; 2066 sl->sl_access_state = SBD_LU_STANDBY; 2067 2068 rw_init(&sl->sl_pgr->pgr_lock, NULL, RW_DRIVER, NULL); 2069 mutex_init(&sl->sl_lock, NULL, MUTEX_DRIVER, NULL); 2070 mutex_init(&sl->sl_metadata_lock, NULL, MUTEX_DRIVER, NULL); 2071 rw_init(&sl->sl_access_state_lock, NULL, RW_DRIVER, NULL); 2072 2073 sl->sl_trans_op = SL_OP_CREATE_REGISTER_LU; 2074 2075 if (sbd_link_lu(sl) != SBD_SUCCESS) { 2076 *err_ret = SBD_RET_FILE_ALREADY_REGISTERED; 2077 ret = EALREADY; 2078 goto scs_err_out; 2079 } 2080 2081 ret = sbd_populate_and_register_lu(sl, err_ret); 2082 if (ret) { 2083 goto scs_err_out; 2084 } 2085 2086 sl->sl_trans_op = SL_OP_NONE; 2087 atomic_add_32(&sbd_lu_count, 1); 2088 return (0); 2089 2090 scs_err_out: 2091 return (sbd_close_delete_lu(sl, ret)); 2092 } 2093 2094 int 2095 sbd_load_sli_1_0(sbd_lu_t *sl, uint32_t *err_ret) 2096 { 2097 sbd_lu_info_1_0_t *sli = NULL; 2098 sbd_status_t sret; 2099 2100 sret = sbd_read_meta_section(sl, (sm_section_hdr_t **)&sli, 2101 SMS_ID_LU_INFO_1_0); 2102 2103 if (sret != SBD_SUCCESS) { 2104 *err_ret = SBD_RET_NO_META; 2105 return (EIO); 2106 } 2107 if (sli->sli_data_order != SMS_DATA_ORDER) { 2108 sbd_swap_lu_info_1_0(sli); 2109 if (sli->sli_data_order != SMS_DATA_ORDER) { 2110 kmem_free(sli, sli->sli_sms_header.sms_size); 2111 *err_ret = SBD_RET_NO_META; 2112 return (EIO); 2113 } 2114 } 2115 2116 sl->sl_flags |= SL_SHARED_META; 2117 sl->sl_data_blocksize_shift = 9; 2118 sl->sl_data_offset = SHARED_META_DATA_SIZE; 2119 sl->sl_lu_size = sli->sli_total_store_size - SHARED_META_DATA_SIZE; 2120 sl->sl_total_data_size = SHARED_META_DATA_SIZE + sl->sl_lu_size; 2121 bcopy(sli->sli_lu_devid, sl->sl_device_id, 20); 2122 2123 kmem_free(sli, sli->sli_sms_header.sms_size); 2124 return (0); 2125 } 2126 2127 int 2128 sbd_import_lu(sbd_import_lu_t *ilu, int struct_sz, uint32_t *err_ret, 2129 int no_register, sbd_lu_t **slr) 2130 { 2131 stmf_lu_t *lu; 2132 sbd_lu_t *sl; 2133 sbd_lu_info_1_1_t *sli = NULL; 2134 int asz; 2135 int ret = 0; 2136 stmf_status_t stret; 2137 int flag; 2138 int wcd = 0; 2139 int data_opened; 2140 uint16_t sli_buf_sz; 2141 uint8_t *sli_buf_copy = NULL; 2142 enum vtype vt; 2143 int standby = 0; 2144 sbd_status_t sret; 2145 2146 if (no_register && slr == NULL) { 2147 return (EINVAL); 2148 } 2149 ilu->ilu_meta_fname[struct_sz - sizeof (*ilu) + 8 - 1] = 0; 2150 /* 2151 * check whether logical unit is already registered ALUA 2152 * For a standby logical unit, the meta filename is set. Use 2153 * that to search for an existing logical unit. 2154 */ 2155 sret = sbd_find_and_lock_lu(NULL, (uint8_t *)&(ilu->ilu_meta_fname), 2156 SL_OP_IMPORT_LU, &sl); 2157 2158 if (sret == SBD_SUCCESS) { 2159 if (sl->sl_access_state != SBD_LU_ACTIVE) { 2160 no_register = 1; 2161 standby = 1; 2162 lu = sl->sl_lu; 2163 if (sl->sl_alias_alloc_size) { 2164 kmem_free(sl->sl_alias, 2165 sl->sl_alias_alloc_size); 2166 sl->sl_alias_alloc_size = 0; 2167 sl->sl_alias = NULL; 2168 lu->lu_alias = NULL; 2169 } 2170 if (sl->sl_meta_filename == NULL) { 2171 sl->sl_meta_filename = sl->sl_data_filename; 2172 } else if (sl->sl_data_fname_alloc_size) { 2173 kmem_free(sl->sl_data_filename, 2174 sl->sl_data_fname_alloc_size); 2175 sl->sl_data_fname_alloc_size = 0; 2176 } 2177 if (sl->sl_serial_no_alloc_size) { 2178 kmem_free(sl->sl_serial_no, 2179 sl->sl_serial_no_alloc_size); 2180 sl->sl_serial_no_alloc_size = 0; 2181 } 2182 if (sl->sl_mgmt_url_alloc_size) { 2183 kmem_free(sl->sl_mgmt_url, 2184 sl->sl_mgmt_url_alloc_size); 2185 sl->sl_mgmt_url_alloc_size = 0; 2186 } 2187 } else { 2188 *err_ret = SBD_RET_FILE_ALREADY_REGISTERED; 2189 sl->sl_trans_op = SL_OP_NONE; 2190 return (EALREADY); 2191 } 2192 } else if (sret == SBD_NOT_FOUND) { 2193 asz = strlen(ilu->ilu_meta_fname) + 1; 2194 2195 lu = (stmf_lu_t *)stmf_alloc(STMF_STRUCT_STMF_LU, 2196 sizeof (sbd_lu_t) + sizeof (sbd_pgr_t) + asz, 0); 2197 if (lu == NULL) { 2198 return (ENOMEM); 2199 } 2200 sl = (sbd_lu_t *)lu->lu_provider_private; 2201 bzero(sl, sizeof (*sl)); 2202 sl->sl_lu = lu; 2203 sl->sl_pgr = (sbd_pgr_t *)(sl + 1); 2204 sl->sl_meta_filename = ((char *)sl) + sizeof (*sl) + 2205 sizeof (sbd_pgr_t); 2206 (void) strcpy(sl->sl_meta_filename, ilu->ilu_meta_fname); 2207 sl->sl_name = sl->sl_meta_filename; 2208 rw_init(&sl->sl_pgr->pgr_lock, NULL, RW_DRIVER, NULL); 2209 rw_init(&sl->sl_access_state_lock, NULL, RW_DRIVER, NULL); 2210 mutex_init(&sl->sl_lock, NULL, MUTEX_DRIVER, NULL); 2211 mutex_init(&sl->sl_metadata_lock, NULL, MUTEX_DRIVER, NULL); 2212 sl->sl_trans_op = SL_OP_IMPORT_LU; 2213 } else { 2214 *err_ret = SBD_RET_META_FILE_LOOKUP_FAILED; 2215 return (EIO); 2216 } 2217 2218 /* we're only loading the metadata */ 2219 if (!no_register) { 2220 if (sbd_link_lu(sl) != SBD_SUCCESS) { 2221 *err_ret = SBD_RET_FILE_ALREADY_REGISTERED; 2222 ret = EALREADY; 2223 goto sim_err_out; 2224 } 2225 } 2226 if ((ret = lookupname(sl->sl_meta_filename, UIO_SYSSPACE, FOLLOW, 2227 NULLVPP, &sl->sl_meta_vp)) != 0) { 2228 *err_ret = SBD_RET_META_FILE_LOOKUP_FAILED; 2229 goto sim_err_out; 2230 } 2231 if (sbd_is_zvol(sl->sl_meta_filename)) { 2232 sl->sl_flags |= SL_ZFS_META; 2233 sl->sl_data_filename = sl->sl_meta_filename; 2234 } 2235 sl->sl_meta_vtype = vt = sl->sl_meta_vp->v_type; 2236 VN_RELE(sl->sl_meta_vp); 2237 if ((vt != VREG) && (vt != VCHR) && (vt != VBLK)) { 2238 *err_ret = SBD_RET_WRONG_META_FILE_TYPE; 2239 ret = EINVAL; 2240 goto sim_err_out; 2241 } 2242 if (sl->sl_flags & SL_ZFS_META) { 2243 if (sbd_open_zfs_meta(sl) != SBD_SUCCESS) { 2244 /* let see if metadata is in the 64k block */ 2245 sl->sl_flags &= ~SL_ZFS_META; 2246 } 2247 } 2248 if (!(sl->sl_flags & SL_ZFS_META)) { 2249 /* metadata is always writable */ 2250 flag = FREAD | FWRITE | FOFFMAX | FEXCL; 2251 if ((ret = vn_open(sl->sl_meta_filename, UIO_SYSSPACE, flag, 0, 2252 &sl->sl_meta_vp, 0, 0)) != 0) { 2253 *err_ret = SBD_RET_META_FILE_OPEN_FAILED; 2254 goto sim_err_out; 2255 } 2256 } 2257 if ((sl->sl_flags & SL_ZFS_META) || (vt == VREG)) { 2258 sl->sl_meta_blocksize_shift = 0; 2259 } else { 2260 sl->sl_meta_blocksize_shift = 9; 2261 } 2262 sl->sl_meta_offset = (sl->sl_flags & SL_ZFS_META) ? 0 : SBD_META_OFFSET; 2263 sl->sl_flags |= SL_META_OPENED; 2264 2265 mutex_enter(&sl->sl_metadata_lock); 2266 sret = sbd_load_meta_start(sl); 2267 mutex_exit(&sl->sl_metadata_lock); 2268 if (sret != SBD_SUCCESS) { 2269 if (sret == SBD_META_CORRUPTED) { 2270 *err_ret = SBD_RET_NO_META; 2271 } else if (sret == SBD_NOT_SUPPORTED) { 2272 *err_ret = SBD_RET_VERSION_NOT_SUPPORTED; 2273 } else { 2274 *err_ret = SBD_RET_NO_META; 2275 } 2276 ret = EINVAL; 2277 goto sim_err_out; 2278 } 2279 2280 /* Now lets see if we can read the most recent LU info */ 2281 sret = sbd_read_meta_section(sl, (sm_section_hdr_t **)&sli, 2282 SMS_ID_LU_INFO_1_1); 2283 if ((sret == SBD_NOT_FOUND) && ((sl->sl_flags & SL_ZFS_META) == 0)) { 2284 ret = sbd_load_sli_1_0(sl, err_ret); 2285 if (ret) { 2286 goto sim_err_out; 2287 } 2288 goto sim_sli_loaded; 2289 } 2290 if (sret != SBD_SUCCESS) { 2291 *err_ret = SBD_RET_NO_META; 2292 ret = EIO; 2293 goto sim_err_out; 2294 } 2295 /* load sli 1.1 */ 2296 if (sli->sli_data_order != SMS_DATA_ORDER) { 2297 sbd_swap_lu_info_1_1(sli); 2298 if (sli->sli_data_order != SMS_DATA_ORDER) { 2299 *err_ret = SBD_RET_NO_META; 2300 ret = EIO; 2301 goto sim_err_out; 2302 } 2303 } 2304 2305 sli_buf_sz = sli->sli_sms_header.sms_size - 2306 sizeof (sbd_lu_info_1_1_t) + 8; 2307 sli_buf_copy = kmem_alloc(sli_buf_sz + 1, KM_SLEEP); 2308 bcopy(sli->sli_buf, sli_buf_copy, sli_buf_sz); 2309 sli_buf_copy[sli_buf_sz] = 0; 2310 2311 /* Make sure all the offsets are within limits */ 2312 if (((sli->sli_flags & SLI_META_FNAME_VALID) && 2313 (sli->sli_meta_fname_offset > sli_buf_sz)) || 2314 ((sli->sli_flags & SLI_DATA_FNAME_VALID) && 2315 (sli->sli_data_fname_offset > sli_buf_sz)) || 2316 ((sli->sli_flags & SLI_MGMT_URL_VALID) && 2317 (sli->sli_mgmt_url_offset > sli_buf_sz)) || 2318 ((sli->sli_flags & SLI_SERIAL_VALID) && 2319 ((sli->sli_serial_offset + sli->sli_serial_size) > sli_buf_sz)) || 2320 ((sli->sli_flags & SLI_ALIAS_VALID) && 2321 (sli->sli_alias_offset > sli_buf_sz))) { 2322 *err_ret = SBD_RET_NO_META; 2323 ret = EIO; 2324 goto sim_err_out; 2325 } 2326 2327 sl->sl_lu_size = sli->sli_lu_size; 2328 sl->sl_data_blocksize_shift = sli->sli_data_blocksize_shift; 2329 bcopy(sli->sli_device_id, sl->sl_device_id, 20); 2330 if (sli->sli_flags & SLI_SERIAL_VALID) { 2331 sl->sl_serial_no_size = sl->sl_serial_no_alloc_size = 2332 sli->sli_serial_size; 2333 sl->sl_serial_no = kmem_zalloc(sli->sli_serial_size, KM_SLEEP); 2334 bcopy(sli_buf_copy + sli->sli_serial_offset, sl->sl_serial_no, 2335 sl->sl_serial_no_size); 2336 } 2337 if (sli->sli_flags & SLI_SEPARATE_META) { 2338 sl->sl_total_data_size = sl->sl_lu_size; 2339 if (sli->sli_flags & SLI_DATA_FNAME_VALID) { 2340 sl->sl_data_fname_alloc_size = strlen((char *) 2341 sli_buf_copy + sli->sli_data_fname_offset) + 1; 2342 sl->sl_data_filename = kmem_zalloc( 2343 sl->sl_data_fname_alloc_size, KM_SLEEP); 2344 (void) strcpy(sl->sl_data_filename, 2345 (char *)sli_buf_copy + sli->sli_data_fname_offset); 2346 } 2347 } else { 2348 if (sl->sl_flags & SL_ZFS_META) { 2349 sl->sl_total_data_size = sl->sl_lu_size; 2350 sl->sl_data_offset = 0; 2351 } else { 2352 sl->sl_total_data_size = 2353 sl->sl_lu_size + SHARED_META_DATA_SIZE; 2354 sl->sl_data_offset = SHARED_META_DATA_SIZE; 2355 sl->sl_flags |= SL_SHARED_META; 2356 } 2357 } 2358 if (sli->sli_flags & SLI_ALIAS_VALID) { 2359 sl->sl_alias_alloc_size = strlen((char *)sli_buf_copy + 2360 sli->sli_alias_offset) + 1; 2361 sl->sl_alias = kmem_alloc(sl->sl_alias_alloc_size, KM_SLEEP); 2362 (void) strcpy(sl->sl_alias, (char *)sli_buf_copy + 2363 sli->sli_alias_offset); 2364 } 2365 if (sli->sli_flags & SLI_MGMT_URL_VALID) { 2366 sl->sl_mgmt_url_alloc_size = strlen((char *)sli_buf_copy + 2367 sli->sli_mgmt_url_offset) + 1; 2368 sl->sl_mgmt_url = kmem_alloc(sl->sl_mgmt_url_alloc_size, 2369 KM_SLEEP); 2370 (void) strcpy(sl->sl_mgmt_url, (char *)sli_buf_copy + 2371 sli->sli_mgmt_url_offset); 2372 } 2373 if (sli->sli_flags & SLI_WRITE_PROTECTED) { 2374 sl->sl_flags |= SL_WRITE_PROTECTED; 2375 } 2376 if (sli->sli_flags & SLI_VID_VALID) { 2377 sl->sl_flags |= SL_VID_VALID; 2378 bcopy(sli->sli_vid, sl->sl_vendor_id, 8); 2379 } 2380 if (sli->sli_flags & SLI_PID_VALID) { 2381 sl->sl_flags |= SL_PID_VALID; 2382 bcopy(sli->sli_pid, sl->sl_product_id, 16); 2383 } 2384 if (sli->sli_flags & SLI_REV_VALID) { 2385 sl->sl_flags |= SL_REV_VALID; 2386 bcopy(sli->sli_rev, sl->sl_revision, 4); 2387 } 2388 if (sli->sli_flags & SLI_WRITEBACK_CACHE_DISABLE) { 2389 sl->sl_flags |= SL_WRITEBACK_CACHE_DISABLE; 2390 } 2391 sim_sli_loaded: 2392 if ((sl->sl_flags & SL_SHARED_META) == 0) { 2393 data_opened = 0; 2394 } else { 2395 data_opened = 1; 2396 sl->sl_data_filename = sl->sl_meta_filename; 2397 sl->sl_data_vp = sl->sl_meta_vp; 2398 sl->sl_data_vtype = sl->sl_meta_vtype; 2399 } 2400 2401 sret = sbd_pgr_meta_load(sl); 2402 if (sret != SBD_SUCCESS) { 2403 *err_ret = SBD_RET_NO_META; 2404 ret = EIO; 2405 goto sim_err_out; 2406 } 2407 2408 ret = sbd_open_data_file(sl, err_ret, 1, data_opened, 0); 2409 if (ret) { 2410 goto sim_err_out; 2411 } 2412 2413 /* 2414 * set write cache disable on the device 2415 * Note: this shouldn't fail on import unless the cache capabilities 2416 * of the device changed. If that happened, modify will need to 2417 * be used to set the cache flag appropriately after import is done. 2418 */ 2419 if (sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) { 2420 (void) sbd_wcd_set(1, sl); 2421 wcd = 1; 2422 /* 2423 * if not explicitly set, attempt to set it to enable, if that fails 2424 * get the current setting and use that 2425 */ 2426 } else { 2427 sret = sbd_wcd_set(0, sl); 2428 if (sret != SBD_SUCCESS) { 2429 sbd_wcd_get(&wcd, sl); 2430 } 2431 } 2432 2433 if (wcd) { 2434 sl->sl_flags |= SL_WRITEBACK_CACHE_DISABLE | 2435 SL_SAVED_WRITE_CACHE_DISABLE; 2436 } 2437 2438 /* we're only loading the metadata */ 2439 if (!no_register) { 2440 ret = sbd_populate_and_register_lu(sl, err_ret); 2441 if (ret) { 2442 goto sim_err_out; 2443 } 2444 atomic_add_32(&sbd_lu_count, 1); 2445 } 2446 2447 bcopy(sl->sl_device_id + 4, ilu->ilu_ret_guid, 16); 2448 sl->sl_trans_op = SL_OP_NONE; 2449 2450 if (sli) { 2451 kmem_free(sli, sli->sli_sms_header.sms_size); 2452 sli = NULL; 2453 } 2454 if (sli_buf_copy) { 2455 kmem_free(sli_buf_copy, sli_buf_sz + 1); 2456 sli_buf_copy = NULL; 2457 } 2458 if (no_register && !standby) { 2459 *slr = sl; 2460 } 2461 2462 /* 2463 * if this was imported from standby, set the access state 2464 * to active. 2465 */ 2466 if (standby) { 2467 sbd_it_data_t *it; 2468 mutex_enter(&sl->sl_lock); 2469 sl->sl_access_state = SBD_LU_ACTIVE; 2470 for (it = sl->sl_it_list; it != NULL; 2471 it = it->sbd_it_next) { 2472 it->sbd_it_ua_conditions |= 2473 SBD_UA_ASYMMETRIC_ACCESS_CHANGED; 2474 it->sbd_it_ua_conditions |= SBD_UA_POR; 2475 } 2476 mutex_exit(&sl->sl_lock); 2477 /* call set access state */ 2478 stret = stmf_set_lu_access(lu, STMF_LU_ACTIVE); 2479 if (stret != STMF_SUCCESS) { 2480 *err_ret = SBD_RET_ACCESS_STATE_FAILED; 2481 sl->sl_access_state = SBD_LU_STANDBY; 2482 goto sim_err_out; 2483 } 2484 if (sl->sl_alias) { 2485 lu->lu_alias = sl->sl_alias; 2486 } else { 2487 lu->lu_alias = sl->sl_name; 2488 } 2489 } 2490 sl->sl_access_state = SBD_LU_ACTIVE; 2491 return (0); 2492 2493 sim_err_out: 2494 if (sli) { 2495 kmem_free(sli, sli->sli_sms_header.sms_size); 2496 sli = NULL; 2497 } 2498 if (sli_buf_copy) { 2499 kmem_free(sli_buf_copy, sli_buf_sz + 1); 2500 sli_buf_copy = NULL; 2501 } 2502 2503 if (standby) { 2504 *err_ret = SBD_RET_ACCESS_STATE_FAILED; 2505 sl->sl_trans_op = SL_OP_NONE; 2506 return (EIO); 2507 } else { 2508 return (sbd_close_delete_lu(sl, ret)); 2509 } 2510 } 2511 2512 int 2513 sbd_modify_lu(sbd_modify_lu_t *mlu, int struct_sz, uint32_t *err_ret) 2514 { 2515 sbd_lu_t *sl = NULL; 2516 uint16_t alias_sz; 2517 int ret = 0; 2518 sbd_it_data_t *it; 2519 sbd_status_t sret; 2520 uint64_t old_size; 2521 int modify_unregistered = 0; 2522 int ua = 0; 2523 sbd_import_lu_t *ilu; 2524 stmf_lu_t *lu; 2525 uint32_t ilu_sz; 2526 uint32_t sz; 2527 2528 sz = struct_sz - sizeof (*mlu) + 8 + 1; 2529 2530 /* if there is data in the buf, null terminate it */ 2531 if (struct_sz > sizeof (*mlu)) { 2532 mlu->mlu_buf[struct_sz - sizeof (*mlu) + 8 - 1] = 0; 2533 } 2534 2535 *err_ret = 0; 2536 2537 /* Lets validate offsets */ 2538 if (((mlu->mlu_alias_valid) && 2539 (mlu->mlu_alias_off >= sz)) || 2540 ((mlu->mlu_mgmt_url_valid) && 2541 (mlu->mlu_mgmt_url_off >= sz)) || 2542 (mlu->mlu_by_fname) && 2543 (mlu->mlu_fname_off >= sz)) { 2544 return (EINVAL); 2545 } 2546 2547 /* 2548 * We'll look for the device but if we don't find it registered, 2549 * we'll still try to modify the unregistered device. 2550 */ 2551 if (mlu->mlu_by_guid) { 2552 sret = sbd_find_and_lock_lu(mlu->mlu_input_guid, NULL, 2553 SL_OP_MODIFY_LU, &sl); 2554 } else if (mlu->mlu_by_fname) { 2555 sret = sbd_find_and_lock_lu(NULL, 2556 (uint8_t *)&(mlu->mlu_buf[mlu->mlu_fname_off]), 2557 SL_OP_MODIFY_LU, &sl); 2558 } else { 2559 return (EINVAL); 2560 } 2561 2562 2563 if (sret != SBD_SUCCESS) { 2564 if (sret == SBD_BUSY) { 2565 *err_ret = SBD_RET_LU_BUSY; 2566 return (EBUSY); 2567 } else if (sret != SBD_NOT_FOUND) { 2568 return (EIO); 2569 } else if (!mlu->mlu_by_fname) { 2570 return (EINVAL); 2571 } 2572 /* Okay, try to import the device */ 2573 struct_sz = max(8, strlen(&(mlu->mlu_buf[mlu->mlu_fname_off])) 2574 + 1); 2575 struct_sz += sizeof (sbd_import_lu_t) - 8; 2576 ilu_sz = struct_sz; 2577 ilu = (sbd_import_lu_t *)kmem_zalloc(ilu_sz, KM_SLEEP); 2578 ilu->ilu_struct_size = struct_sz; 2579 (void) strcpy(ilu->ilu_meta_fname, 2580 &(mlu->mlu_buf[mlu->mlu_fname_off])); 2581 ret = sbd_import_lu(ilu, struct_sz, err_ret, 1, &sl); 2582 kmem_free(ilu, ilu_sz); 2583 if (ret != SBD_SUCCESS) { 2584 return (ENOENT); 2585 } 2586 modify_unregistered = 1; 2587 } 2588 2589 if (sl->sl_access_state != SBD_LU_ACTIVE) { 2590 *err_ret = SBD_RET_ACCESS_STATE_FAILED; 2591 ret = EINVAL; 2592 goto smm_err_out; 2593 } 2594 2595 /* check for write cache change */ 2596 if (mlu->mlu_writeback_cache_disable_valid) { 2597 /* set wce on device */ 2598 sret = sbd_wcd_set(mlu->mlu_writeback_cache_disable, sl); 2599 if (!mlu->mlu_writeback_cache_disable && sret != SBD_SUCCESS) { 2600 *err_ret = SBD_RET_WRITE_CACHE_SET_FAILED; 2601 ret = EFAULT; 2602 goto smm_err_out; 2603 } 2604 mutex_enter(&sl->sl_lock); 2605 if (!mlu->mlu_writeback_cache_disable) { 2606 if (sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) { 2607 ua = 1; 2608 sl->sl_flags &= ~SL_WRITEBACK_CACHE_DISABLE; 2609 sl->sl_flags &= ~SL_SAVED_WRITE_CACHE_DISABLE; 2610 } 2611 } else { 2612 if ((sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) == 0) { 2613 ua = 1; 2614 sl->sl_flags |= SL_WRITEBACK_CACHE_DISABLE; 2615 sl->sl_flags |= SL_SAVED_WRITE_CACHE_DISABLE; 2616 } 2617 } 2618 for (it = sl->sl_it_list; ua && it != NULL; 2619 it = it->sbd_it_next) { 2620 it->sbd_it_ua_conditions |= 2621 SBD_UA_MODE_PARAMETERS_CHANGED; 2622 } 2623 mutex_exit(&sl->sl_lock); 2624 } 2625 ua = 0; 2626 2627 if (mlu->mlu_alias_valid) { 2628 alias_sz = strlen((char *)mlu->mlu_buf + 2629 mlu->mlu_alias_off) + 1; 2630 /* 2631 * Use the allocated buffer or alloc a new one. 2632 * Don't copy into sl_alias if sl_alias_alloc_size is 0 2633 * otherwise or you'll be writing over the data/metadata 2634 * filename. 2635 */ 2636 mutex_enter(&sl->sl_lock); 2637 if (sl->sl_alias_alloc_size > 0 && 2638 sl->sl_alias_alloc_size < alias_sz) { 2639 kmem_free(sl->sl_alias, 2640 sl->sl_alias_alloc_size); 2641 sl->sl_alias_alloc_size = 0; 2642 } 2643 if (sl->sl_alias_alloc_size == 0) { 2644 sl->sl_alias = kmem_alloc(alias_sz, KM_SLEEP); 2645 sl->sl_alias_alloc_size = alias_sz; 2646 } 2647 (void) strcpy(sl->sl_alias, (char *)mlu->mlu_buf + 2648 mlu->mlu_alias_off); 2649 lu = sl->sl_lu; 2650 lu->lu_alias = sl->sl_alias; 2651 mutex_exit(&sl->sl_lock); 2652 } 2653 2654 if (mlu->mlu_mgmt_url_valid) { 2655 uint16_t url_sz; 2656 2657 url_sz = strlen((char *)mlu->mlu_buf + mlu->mlu_mgmt_url_off); 2658 if (url_sz > 0) 2659 url_sz++; 2660 2661 mutex_enter(&sl->sl_lock); 2662 if (sl->sl_mgmt_url_alloc_size > 0 && 2663 (url_sz == 0 || sl->sl_mgmt_url_alloc_size < url_sz)) { 2664 kmem_free(sl->sl_mgmt_url, sl->sl_mgmt_url_alloc_size); 2665 sl->sl_mgmt_url = NULL; 2666 sl->sl_mgmt_url_alloc_size = 0; 2667 } 2668 if (url_sz > 0) { 2669 if (sl->sl_mgmt_url_alloc_size == 0) { 2670 sl->sl_mgmt_url = kmem_alloc(url_sz, KM_SLEEP); 2671 sl->sl_mgmt_url_alloc_size = url_sz; 2672 } 2673 (void) strcpy(sl->sl_mgmt_url, (char *)mlu->mlu_buf + 2674 mlu->mlu_mgmt_url_off); 2675 } 2676 for (it = sl->sl_it_list; it != NULL; 2677 it = it->sbd_it_next) { 2678 it->sbd_it_ua_conditions |= 2679 SBD_UA_MODE_PARAMETERS_CHANGED; 2680 } 2681 mutex_exit(&sl->sl_lock); 2682 } 2683 2684 if (mlu->mlu_write_protected_valid) { 2685 mutex_enter(&sl->sl_lock); 2686 if (mlu->mlu_write_protected) { 2687 if ((sl->sl_flags & SL_WRITE_PROTECTED) == 0) { 2688 ua = 1; 2689 sl->sl_flags |= SL_WRITE_PROTECTED; 2690 } 2691 } else { 2692 if (sl->sl_flags & SL_WRITE_PROTECTED) { 2693 ua = 1; 2694 sl->sl_flags &= ~SL_WRITE_PROTECTED; 2695 } 2696 } 2697 for (it = sl->sl_it_list; ua && it != NULL; 2698 it = it->sbd_it_next) { 2699 it->sbd_it_ua_conditions |= 2700 SBD_UA_MODE_PARAMETERS_CHANGED; 2701 } 2702 mutex_exit(&sl->sl_lock); 2703 } 2704 2705 if (mlu->mlu_lu_size_valid) { 2706 /* 2707 * validate lu size and set 2708 * For open file only (registered lu) 2709 */ 2710 mutex_enter(&sl->sl_lock); 2711 old_size = sl->sl_lu_size; 2712 sl->sl_lu_size = mlu->mlu_lu_size; 2713 mutex_exit(&sl->sl_lock); 2714 ret = sbd_open_data_file(sl, err_ret, 1, 1, 1); 2715 if (ret) { 2716 mutex_enter(&sl->sl_lock); 2717 sl->sl_lu_size = old_size; 2718 mutex_exit(&sl->sl_lock); 2719 goto smm_err_out; 2720 } 2721 if (old_size != mlu->mlu_lu_size) { 2722 mutex_enter(&sl->sl_lock); 2723 for (it = sl->sl_it_list; it != NULL; 2724 it = it->sbd_it_next) { 2725 it->sbd_it_ua_conditions |= 2726 SBD_UA_CAPACITY_CHANGED; 2727 } 2728 mutex_exit(&sl->sl_lock); 2729 } 2730 } 2731 2732 if (sbd_write_lu_info(sl) != SBD_SUCCESS) { 2733 *err_ret = SBD_RET_META_CREATION_FAILED; 2734 ret = EIO; 2735 } 2736 2737 smm_err_out: 2738 if (modify_unregistered) { 2739 (void) sbd_close_delete_lu(sl, 0); 2740 } else { 2741 sl->sl_trans_op = SL_OP_NONE; 2742 } 2743 return (ret); 2744 } 2745 2746 /* ARGSUSED */ 2747 int 2748 sbd_delete_locked_lu(sbd_lu_t *sl, uint32_t *err_ret, 2749 stmf_state_change_info_t *ssi) 2750 { 2751 int i; 2752 2753 if ((sl->sl_state == STMF_STATE_OFFLINE) && 2754 !sl->sl_state_not_acked) { 2755 goto sdl_do_dereg; 2756 } 2757 2758 if ((sl->sl_state != STMF_STATE_ONLINE) || 2759 sl->sl_state_not_acked) { 2760 return (EBUSY); 2761 } 2762 if (stmf_ctl(STMF_CMD_LU_OFFLINE, sl->sl_lu, ssi) != STMF_SUCCESS) { 2763 return (EBUSY); 2764 } 2765 2766 for (i = 0; i < 500; i++) { 2767 if (sl->sl_state == STMF_STATE_OFFLINE) 2768 break; 2769 delay(drv_usectohz(10000)); 2770 } 2771 2772 if ((sl->sl_state == STMF_STATE_OFFLINE) && 2773 !sl->sl_state_not_acked) { 2774 goto sdl_do_dereg; 2775 } 2776 2777 return (EBUSY); 2778 sdl_do_dereg:; 2779 if (stmf_deregister_lu(sl->sl_lu) != STMF_SUCCESS) 2780 return (EBUSY); 2781 atomic_add_32(&sbd_lu_count, -1); 2782 2783 return (sbd_close_delete_lu(sl, 0)); 2784 } 2785 2786 int 2787 sbd_delete_lu(sbd_delete_lu_t *dlu, int struct_sz, uint32_t *err_ret) 2788 { 2789 sbd_lu_t *sl; 2790 sbd_status_t sret; 2791 stmf_state_change_info_t ssi; 2792 int ret; 2793 2794 if (dlu->dlu_by_meta_name) { 2795 ((char *)dlu)[struct_sz - 1] = 0; 2796 sret = sbd_find_and_lock_lu(NULL, dlu->dlu_meta_name, 2797 SL_OP_DELETE_LU, &sl); 2798 } else { 2799 sret = sbd_find_and_lock_lu(dlu->dlu_guid, NULL, 2800 SL_OP_DELETE_LU, &sl); 2801 } 2802 if (sret != SBD_SUCCESS) { 2803 if (sret == SBD_BUSY) { 2804 *err_ret = SBD_RET_LU_BUSY; 2805 return (EBUSY); 2806 } else if (sret == SBD_NOT_FOUND) { 2807 *err_ret = SBD_RET_NOT_FOUND; 2808 return (ENOENT); 2809 } 2810 return (EIO); 2811 } 2812 2813 ssi.st_rflags = STMF_RFLAG_USER_REQUEST; 2814 ssi.st_additional_info = "sbd_delete_lu call (ioctl)"; 2815 ret = sbd_delete_locked_lu(sl, err_ret, &ssi); 2816 2817 if (ret) { 2818 /* Once its locked, no need to grab mutex again */ 2819 sl->sl_trans_op = SL_OP_NONE; 2820 } 2821 return (ret); 2822 } 2823 2824 sbd_status_t 2825 sbd_data_read(sbd_lu_t *sl, uint64_t offset, uint64_t size, uint8_t *buf) 2826 { 2827 int ret; 2828 long resid; 2829 2830 if ((offset + size) > sl->sl_lu_size) { 2831 return (SBD_IO_PAST_EOF); 2832 } 2833 2834 offset += sl->sl_data_offset; 2835 2836 if ((offset + size) > sl->sl_data_readable_size) { 2837 uint64_t store_end; 2838 if (offset > sl->sl_data_readable_size) { 2839 bzero(buf, size); 2840 return (SBD_SUCCESS); 2841 } 2842 store_end = sl->sl_data_readable_size - offset; 2843 bzero(buf + store_end, size - store_end); 2844 size = store_end; 2845 } 2846 2847 DTRACE_PROBE4(backing__store__read__start, sbd_lu_t *, sl, 2848 uint8_t *, buf, uint64_t, size, uint64_t, offset); 2849 2850 /* 2851 * Don't proceed if the device has been closed 2852 * This can occur on an access state change to standby or 2853 * a delete. The writer lock is acquired before closing the 2854 * lu. 2855 */ 2856 rw_enter(&sl->sl_access_state_lock, RW_READER); 2857 if ((sl->sl_flags & SL_MEDIA_LOADED) == 0) { 2858 rw_exit(&sl->sl_access_state_lock); 2859 return (SBD_FAILURE); 2860 } 2861 ret = vn_rdwr(UIO_READ, sl->sl_data_vp, (caddr_t)buf, (ssize_t)size, 2862 (offset_t)offset, UIO_SYSSPACE, 0, RLIM64_INFINITY, CRED(), 2863 &resid); 2864 rw_exit(&sl->sl_access_state_lock); 2865 2866 DTRACE_PROBE5(backing__store__read__end, sbd_lu_t *, sl, 2867 uint8_t *, buf, uint64_t, size, uint64_t, offset, 2868 int, ret); 2869 2870 over_sl_data_read: 2871 if (ret || resid) { 2872 stmf_trace(0, "UIO_READ failed, ret = %d, resid = %d", ret, 2873 resid); 2874 return (SBD_FAILURE); 2875 } 2876 2877 return (SBD_SUCCESS); 2878 } 2879 2880 sbd_status_t 2881 sbd_data_write(sbd_lu_t *sl, uint64_t offset, uint64_t size, uint8_t *buf) 2882 { 2883 int ret; 2884 long resid; 2885 sbd_status_t sret = SBD_SUCCESS; 2886 int ioflag; 2887 2888 if ((offset + size) > sl->sl_lu_size) { 2889 return (SBD_IO_PAST_EOF); 2890 } 2891 2892 offset += sl->sl_data_offset; 2893 2894 if ((sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) && 2895 (sl->sl_flags & SL_FLUSH_ON_DISABLED_WRITECACHE)) { 2896 ioflag = FSYNC; 2897 } else { 2898 ioflag = 0; 2899 } 2900 2901 DTRACE_PROBE4(backing__store__write__start, sbd_lu_t *, sl, 2902 uint8_t *, buf, uint64_t, size, uint64_t, offset); 2903 2904 /* 2905 * Don't proceed if the device has been closed 2906 * This can occur on an access state change to standby or 2907 * a delete. The writer lock is acquired before closing the 2908 * lu. 2909 */ 2910 rw_enter(&sl->sl_access_state_lock, RW_READER); 2911 if ((sl->sl_flags & SL_MEDIA_LOADED) == 0) { 2912 rw_exit(&sl->sl_access_state_lock); 2913 return (SBD_FAILURE); 2914 } 2915 ret = vn_rdwr(UIO_WRITE, sl->sl_data_vp, (caddr_t)buf, (ssize_t)size, 2916 (offset_t)offset, UIO_SYSSPACE, ioflag, RLIM64_INFINITY, CRED(), 2917 &resid); 2918 rw_exit(&sl->sl_access_state_lock); 2919 2920 DTRACE_PROBE5(backing__store__write__end, sbd_lu_t *, sl, 2921 uint8_t *, buf, uint64_t, size, uint64_t, offset, 2922 int, ret); 2923 2924 if ((ret == 0) && (resid == 0) && 2925 (sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) && 2926 (sl->sl_flags & SL_FLUSH_ON_DISABLED_WRITECACHE)) { 2927 sret = sbd_flush_data_cache(sl, 1); 2928 } 2929 over_sl_data_write: 2930 2931 if ((ret || resid) || (sret != SBD_SUCCESS)) { 2932 return (SBD_FAILURE); 2933 } else if ((offset + size) > sl->sl_data_readable_size) { 2934 uint64_t old_size, new_size; 2935 2936 do { 2937 old_size = sl->sl_data_readable_size; 2938 if ((offset + size) <= old_size) 2939 break; 2940 new_size = offset + size; 2941 } while (atomic_cas_64(&sl->sl_data_readable_size, old_size, 2942 new_size) != old_size); 2943 } 2944 2945 return (SBD_SUCCESS); 2946 } 2947 2948 int 2949 sbd_get_lu_props(sbd_lu_props_t *islp, uint32_t islp_sz, 2950 sbd_lu_props_t *oslp, uint32_t oslp_sz, uint32_t *err_ret) 2951 { 2952 sbd_status_t sret; 2953 sbd_lu_t *sl = NULL; 2954 uint32_t sz; 2955 uint16_t off; 2956 2957 if (islp->slp_input_guid) { 2958 sret = sbd_find_and_lock_lu(islp->slp_guid, NULL, 2959 SL_OP_LU_PROPS, &sl); 2960 } else { 2961 ((char *)islp)[islp_sz - 1] = 0; 2962 sret = sbd_find_and_lock_lu(NULL, islp->slp_buf, 2963 SL_OP_LU_PROPS, &sl); 2964 } 2965 if (sret != SBD_SUCCESS) { 2966 if (sret == SBD_BUSY) { 2967 *err_ret = SBD_RET_LU_BUSY; 2968 return (EBUSY); 2969 } else if (sret == SBD_NOT_FOUND) { 2970 *err_ret = SBD_RET_NOT_FOUND; 2971 return (ENOENT); 2972 } 2973 return (EIO); 2974 } 2975 2976 sz = strlen(sl->sl_name) + 1; 2977 if ((sl->sl_flags & (SL_ZFS_META | SL_SHARED_META)) == 0) { 2978 if (sl->sl_data_filename) { 2979 sz += strlen(sl->sl_data_filename) + 1; 2980 } 2981 } 2982 sz += sl->sl_serial_no_size; 2983 if (sl->sl_alias) { 2984 sz += strlen(sl->sl_alias) + 1; 2985 } 2986 2987 if (sl->sl_mgmt_url) { 2988 sz += strlen(sl->sl_mgmt_url) + 1; 2989 } 2990 bzero(oslp, sizeof (*oslp) - 8); 2991 oslp->slp_buf_size_needed = sz; 2992 2993 if (sz > (oslp_sz - sizeof (*oslp) + 8)) { 2994 sl->sl_trans_op = SL_OP_NONE; 2995 *err_ret = SBD_RET_INSUFFICIENT_BUF_SPACE; 2996 return (ENOMEM); 2997 } 2998 2999 off = 0; 3000 (void) strcpy((char *)oslp->slp_buf, sl->sl_name); 3001 oslp->slp_meta_fname_off = off; 3002 off += strlen(sl->sl_name) + 1; 3003 if ((sl->sl_flags & (SL_ZFS_META | SL_SHARED_META)) == 0) { 3004 oslp->slp_meta_fname_valid = 1; 3005 oslp->slp_separate_meta = 1; 3006 if (sl->sl_data_filename) { 3007 oslp->slp_data_fname_valid = 1; 3008 oslp->slp_data_fname_off = off; 3009 (void) strcpy((char *)&oslp->slp_buf[off], 3010 sl->sl_data_filename); 3011 off += strlen(sl->sl_data_filename) + 1; 3012 } 3013 } else { 3014 oslp->slp_data_fname_valid = 1; 3015 oslp->slp_data_fname_off = oslp->slp_meta_fname_off; 3016 if (sl->sl_flags & SL_ZFS_META) { 3017 oslp->slp_zfs_meta = 1; 3018 } 3019 } 3020 if (sl->sl_alias) { 3021 oslp->slp_alias_valid = 1; 3022 oslp->slp_alias_off = off; 3023 (void) strcpy((char *)&oslp->slp_buf[off], sl->sl_alias); 3024 off += strlen(sl->sl_alias) + 1; 3025 } 3026 if (sl->sl_mgmt_url) { 3027 oslp->slp_mgmt_url_valid = 1; 3028 oslp->slp_mgmt_url_off = off; 3029 (void) strcpy((char *)&oslp->slp_buf[off], sl->sl_mgmt_url); 3030 off += strlen(sl->sl_mgmt_url) + 1; 3031 } 3032 if (sl->sl_serial_no_size) { 3033 oslp->slp_serial_off = off; 3034 bcopy(sl->sl_serial_no, &oslp->slp_buf[off], 3035 sl->sl_serial_no_size); 3036 oslp->slp_serial_size = sl->sl_serial_no_size; 3037 oslp->slp_serial_valid = 1; 3038 off += sl->sl_serial_no_size; 3039 } 3040 3041 oslp->slp_lu_size = sl->sl_lu_size; 3042 oslp->slp_blksize = ((uint16_t)1) << sl->sl_data_blocksize_shift; 3043 3044 oslp->slp_access_state = sl->sl_access_state; 3045 3046 if (sl->sl_flags & SL_VID_VALID) { 3047 oslp->slp_lu_vid = 1; 3048 bcopy(sl->sl_vendor_id, oslp->slp_vid, 8); 3049 } else { 3050 bcopy(sbd_vendor_id, oslp->slp_vid, 8); 3051 } 3052 if (sl->sl_flags & SL_PID_VALID) { 3053 oslp->slp_lu_pid = 1; 3054 bcopy(sl->sl_product_id, oslp->slp_pid, 16); 3055 } else { 3056 bcopy(sbd_product_id, oslp->slp_pid, 16); 3057 } 3058 if (sl->sl_flags & SL_REV_VALID) { 3059 oslp->slp_lu_rev = 1; 3060 bcopy(sl->sl_revision, oslp->slp_rev, 4); 3061 } else { 3062 bcopy(sbd_revision, oslp->slp_rev, 4); 3063 } 3064 bcopy(sl->sl_device_id + 4, oslp->slp_guid, 16); 3065 3066 if (sl->sl_flags & SL_WRITEBACK_CACHE_DISABLE) 3067 oslp->slp_writeback_cache_disable_cur = 1; 3068 if (sl->sl_flags & SL_SAVED_WRITE_CACHE_DISABLE) 3069 oslp->slp_writeback_cache_disable_saved = 1; 3070 if (sl->sl_flags & SL_WRITE_PROTECTED) 3071 oslp->slp_write_protected = 1; 3072 3073 sl->sl_trans_op = SL_OP_NONE; 3074 3075 return (0); 3076 } 3077 3078 char * 3079 sbd_get_zvol_name(sbd_lu_t *sl) 3080 { 3081 char *src; 3082 char *p; 3083 3084 if (sl->sl_data_filename) 3085 src = sl->sl_data_filename; 3086 else 3087 src = sl->sl_meta_filename; 3088 /* There has to be a better way */ 3089 if (SBD_IS_ZVOL(src) != 0) { 3090 ASSERT(0); 3091 } 3092 src += 14; 3093 if (*src == '/') 3094 src++; 3095 p = (char *)kmem_alloc(strlen(src) + 1, KM_SLEEP); 3096 (void) strcpy(p, src); 3097 return (p); 3098 } 3099 3100 /* 3101 * this function creates a local metadata zvol property 3102 */ 3103 sbd_status_t 3104 sbd_create_zfs_meta_object(sbd_lu_t *sl) 3105 { 3106 /* 3107 * -allocate 1/2 the property size, the zfs property 3108 * is 8k in size and stored as ascii hex string, all 3109 * we needed is 4k buffer to store the binary data. 3110 * -initialize reader/write lock 3111 */ 3112 if ((sl->sl_zfs_meta = kmem_zalloc(ZAP_MAXVALUELEN / 2, KM_SLEEP)) 3113 == NULL) 3114 return (SBD_FAILURE); 3115 rw_init(&sl->sl_zfs_meta_lock, NULL, RW_DRIVER, NULL); 3116 return (SBD_SUCCESS); 3117 } 3118 3119 char 3120 sbd_ctoi(char c) 3121 { 3122 if ((c >= '0') && (c <= '9')) 3123 c -= '0'; 3124 else if ((c >= 'A') && (c <= 'F')) 3125 c = c - 'A' + 10; 3126 else if ((c >= 'a') && (c <= 'f')) 3127 c = c - 'a' + 10; 3128 else 3129 c = -1; 3130 return (c); 3131 } 3132 3133 /* 3134 * read zvol property and convert to binary 3135 */ 3136 sbd_status_t 3137 sbd_open_zfs_meta(sbd_lu_t *sl) 3138 { 3139 char *meta = NULL, cl, ch; 3140 int i; 3141 char *tmp, *ptr; 3142 uint64_t rc = SBD_SUCCESS; 3143 int len; 3144 char *file; 3145 3146 if (sl->sl_zfs_meta == NULL) { 3147 if (sbd_create_zfs_meta_object(sl) == SBD_FAILURE) 3148 return (SBD_FAILURE); 3149 } else { 3150 bzero(sl->sl_zfs_meta, (ZAP_MAXVALUELEN / 2)); 3151 } 3152 3153 rw_enter(&sl->sl_zfs_meta_lock, RW_WRITER); 3154 file = sbd_get_zvol_name(sl); 3155 if (sbd_zvolget(file, &meta)) { 3156 rc = SBD_FAILURE; 3157 goto done; 3158 } 3159 tmp = meta; 3160 /* convert ascii hex to binary meta */ 3161 len = strlen(meta); 3162 ptr = sl->sl_zfs_meta; 3163 for (i = 0; i < len; i += 2) { 3164 ch = sbd_ctoi(*tmp++); 3165 cl = sbd_ctoi(*tmp++); 3166 if (ch == -1 || cl == -1) { 3167 rc = SBD_FAILURE; 3168 break; 3169 } 3170 *ptr++ = (ch << 4) + cl; 3171 } 3172 done: 3173 rw_exit(&sl->sl_zfs_meta_lock); 3174 if (meta) 3175 kmem_free(meta, len + 1); 3176 kmem_free(file, strlen(file) + 1); 3177 return (rc); 3178 } 3179 3180 sbd_status_t 3181 sbd_read_zfs_meta(sbd_lu_t *sl, uint8_t *buf, uint64_t sz, uint64_t off) 3182 { 3183 ASSERT(sl->sl_zfs_meta); 3184 rw_enter(&sl->sl_zfs_meta_lock, RW_READER); 3185 bcopy(&sl->sl_zfs_meta[off], buf, sz); 3186 rw_exit(&sl->sl_zfs_meta_lock); 3187 return (SBD_SUCCESS); 3188 } 3189 3190 sbd_status_t 3191 sbd_write_zfs_meta(sbd_lu_t *sl, uint8_t *buf, uint64_t sz, uint64_t off) 3192 { 3193 char *ptr, *ah_meta; 3194 char *dp = NULL; 3195 int i, num; 3196 char *file; 3197 3198 ASSERT(sl->sl_zfs_meta); 3199 if ((off + sz) > (ZAP_MAXVALUELEN / 2 - 1)) { 3200 return (SBD_META_CORRUPTED); 3201 } 3202 if ((off + sz) > sl->sl_meta_size_used) { 3203 sl->sl_meta_size_used = off + sz; 3204 if (sl->sl_total_meta_size < sl->sl_meta_size_used) { 3205 uint64_t meta_align = 3206 (((uint64_t)1) << sl->sl_meta_blocksize_shift) - 1; 3207 sl->sl_total_meta_size = (sl->sl_meta_size_used + 3208 meta_align) & (~meta_align); 3209 } 3210 } 3211 ptr = ah_meta = kmem_zalloc(ZAP_MAXVALUELEN, KM_SLEEP); 3212 rw_enter(&sl->sl_zfs_meta_lock, RW_WRITER); 3213 bcopy(buf, &sl->sl_zfs_meta[off], sz); 3214 /* convert local copy to ascii hex */ 3215 dp = sl->sl_zfs_meta; 3216 for (i = 0; i < sl->sl_total_meta_size; i++, dp++) { 3217 num = ((*dp) >> 4) & 0xF; 3218 *ah_meta++ = (num < 10) ? (num + '0') : (num + ('a' - 10)); 3219 num = (*dp) & 0xF; 3220 *ah_meta++ = (num < 10) ? (num + '0') : (num + ('a' - 10)); 3221 } 3222 *ah_meta = NULL; 3223 file = sbd_get_zvol_name(sl); 3224 if (sbd_zvolset(file, (char *)ptr)) { 3225 rw_exit(&sl->sl_zfs_meta_lock); 3226 kmem_free(ptr, ZAP_MAXVALUELEN); 3227 kmem_free(file, strlen(file) + 1); 3228 return (SBD_META_CORRUPTED); 3229 } 3230 rw_exit(&sl->sl_zfs_meta_lock); 3231 kmem_free(ptr, ZAP_MAXVALUELEN); 3232 kmem_free(file, strlen(file) + 1); 3233 return (SBD_SUCCESS); 3234 } 3235 3236 int 3237 sbd_is_zvol(char *path) 3238 { 3239 int is_zfs = 0; 3240 3241 if (SBD_IS_ZVOL(path) == 0) 3242 is_zfs = 1; 3243 3244 return (is_zfs); 3245 } 3246 3247 /* 3248 * set write cache disable 3249 * wcd - 1 = disable, 0 = enable 3250 */ 3251 sbd_status_t 3252 sbd_wcd_set(int wcd, sbd_lu_t *sl) 3253 { 3254 /* translate to wce bit */ 3255 int wce = wcd ? 0 : 1; 3256 int ret; 3257 sbd_status_t sret = SBD_SUCCESS; 3258 3259 mutex_enter(&sl->sl_lock); 3260 sl->sl_flags &= ~SL_WRITEBACK_CACHE_SET_UNSUPPORTED; 3261 3262 if (sl->sl_data_vp->v_type == VREG) { 3263 sl->sl_flags |= SL_FLUSH_ON_DISABLED_WRITECACHE; 3264 goto done; 3265 } 3266 3267 ret = VOP_IOCTL(sl->sl_data_vp, DKIOCSETWCE, (intptr_t)&wce, FKIOCTL, 3268 kcred, NULL, NULL); 3269 if (ret == 0) { 3270 sl->sl_flags &= ~SL_WRITEBACK_CACHE_SET_UNSUPPORTED; 3271 sl->sl_flags &= ~SL_FLUSH_ON_DISABLED_WRITECACHE; 3272 } else { 3273 sl->sl_flags |= SL_WRITEBACK_CACHE_SET_UNSUPPORTED; 3274 sl->sl_flags |= SL_FLUSH_ON_DISABLED_WRITECACHE; 3275 sret = SBD_FAILURE; 3276 goto done; 3277 } 3278 3279 done: 3280 mutex_exit(&sl->sl_lock); 3281 return (sret); 3282 } 3283 3284 /* 3285 * get write cache disable 3286 * wcd - 1 = disable, 0 = enable 3287 */ 3288 void 3289 sbd_wcd_get(int *wcd, sbd_lu_t *sl) 3290 { 3291 int wce; 3292 int ret; 3293 3294 if (sl->sl_data_vp->v_type == VREG) { 3295 *wcd = 0; 3296 return; 3297 } 3298 3299 ret = VOP_IOCTL(sl->sl_data_vp, DKIOCGETWCE, (intptr_t)&wce, FKIOCTL, 3300 kcred, NULL, NULL); 3301 /* if write cache get failed, assume disabled */ 3302 if (ret) { 3303 *wcd = 1; 3304 } else { 3305 /* translate to wcd bit */ 3306 *wcd = wce ? 0 : 1; 3307 } 3308 } 3309 3310 int 3311 sbd_zvolget(char *zvol_name, char **comstarprop) 3312 { 3313 ldi_handle_t zfs_lh; 3314 nvlist_t *nv = NULL, *nv2; 3315 zfs_cmd_t *zc; 3316 char *ptr; 3317 int size = 1024; 3318 int unused; 3319 int rc; 3320 3321 if ((rc = ldi_open_by_name("/dev/zfs", FREAD | FWRITE, kcred, 3322 &zfs_lh, sbd_zfs_ident)) != 0) { 3323 cmn_err(CE_WARN, "ldi_open %d", rc); 3324 return (ENXIO); 3325 } 3326 3327 zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP); 3328 (void) strlcpy(zc->zc_name, zvol_name, sizeof (zc->zc_name)); 3329 again: 3330 zc->zc_nvlist_dst = (uint64_t)(intptr_t)kmem_alloc(size, 3331 KM_SLEEP); 3332 zc->zc_nvlist_dst_size = size; 3333 rc = ldi_ioctl(zfs_lh, ZFS_IOC_OBJSET_STATS, (intptr_t)zc, 3334 FKIOCTL, kcred, &unused); 3335 /* 3336 * ENOMEM means the list is larger than what we've allocated 3337 * ldi_ioctl will fail with ENOMEM only once 3338 */ 3339 if (rc == ENOMEM) { 3340 int newsize; 3341 newsize = zc->zc_nvlist_dst_size; 3342 kmem_free((void *)(uintptr_t)zc->zc_nvlist_dst, size); 3343 size = newsize; 3344 goto again; 3345 } else if (rc != 0) { 3346 goto out; 3347 } 3348 rc = nvlist_unpack((char *)(uintptr_t)zc->zc_nvlist_dst, 3349 zc->zc_nvlist_dst_size, &nv, 0); 3350 ASSERT(rc == 0); /* nvlist_unpack should not fail */ 3351 if ((rc = nvlist_lookup_nvlist(nv, "stmf_sbd_lu", &nv2)) == 0) { 3352 rc = nvlist_lookup_string(nv2, ZPROP_VALUE, &ptr); 3353 if (rc != 0) { 3354 cmn_err(CE_WARN, "couldn't get value"); 3355 } else { 3356 *comstarprop = kmem_alloc(strlen(ptr) + 1, 3357 KM_SLEEP); 3358 (void) strcpy(*comstarprop, ptr); 3359 } 3360 } 3361 out: 3362 if (nv != NULL) 3363 nvlist_free(nv); 3364 kmem_free((void *)(uintptr_t)zc->zc_nvlist_dst, size); 3365 kmem_free(zc, sizeof (zfs_cmd_t)); 3366 (void) ldi_close(zfs_lh, FREAD|FWRITE, kcred); 3367 3368 return (rc); 3369 } 3370 3371 int 3372 sbd_zvolset(char *zvol_name, char *comstarprop) 3373 { 3374 ldi_handle_t zfs_lh; 3375 nvlist_t *nv; 3376 char *packed = NULL; 3377 size_t len; 3378 zfs_cmd_t *zc; 3379 int unused; 3380 int rc; 3381 3382 if ((rc = ldi_open_by_name("/dev/zfs", FREAD | FWRITE, kcred, 3383 &zfs_lh, sbd_zfs_ident)) != 0) { 3384 cmn_err(CE_WARN, "ldi_open %d", rc); 3385 return (ENXIO); 3386 } 3387 (void) nvlist_alloc(&nv, NV_UNIQUE_NAME, KM_SLEEP); 3388 (void) nvlist_add_string(nv, "stmf_sbd_lu", comstarprop); 3389 if ((rc = nvlist_pack(nv, &packed, &len, NV_ENCODE_NATIVE, KM_SLEEP))) { 3390 goto out; 3391 } 3392 3393 zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP); 3394 (void) strlcpy(zc->zc_name, zvol_name, sizeof (zc->zc_name)); 3395 zc->zc_nvlist_src = (uint64_t)(intptr_t)packed; 3396 zc->zc_nvlist_src_size = len; 3397 rc = ldi_ioctl(zfs_lh, ZFS_IOC_SET_PROP, (intptr_t)zc, 3398 FKIOCTL, kcred, &unused); 3399 if (rc != 0) { 3400 cmn_err(CE_NOTE, "ioctl failed %d", rc); 3401 } 3402 kmem_free(zc, sizeof (zfs_cmd_t)); 3403 if (packed) 3404 kmem_free(packed, len); 3405 out: 3406 nvlist_free(nv); 3407 (void) ldi_close(zfs_lh, FREAD|FWRITE, kcred); 3408 return (rc); 3409 } 3410