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