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