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