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