1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/types.h> 27 #include <sys/debug.h> 28 #include <sys/ksynch.h> 29 #include <sys/kmem.h> 30 #include <sys/cmn_err.h> 31 #include <sys/errno.h> 32 #include <sys/ddi.h> 33 34 #include <sys/ncall/ncall.h> 35 36 #define __NSC_GEN__ 37 #include "nsc_dev.h" 38 39 #ifdef DS_DDICT 40 #include "../contract.h" 41 #endif 42 43 #include "../nsctl.h" 44 45 #define NSC_DEVMIN "DevMin" 46 #define NSC_DEVMAJ "DevMaj" 47 48 #define _I(x) (((long)(&((nsc_io_t *)0)->x))/sizeof (long)) 49 #define _F(x) (((long)(&((nsc_fd_t *)0)->x))/sizeof (long)) 50 51 52 nsc_def_t _nsc_io_def[] = { 53 "Open", (uintptr_t)nsc_null, _I(open), 54 "Close", (uintptr_t)nsc_null, _I(close), 55 "Attach", (uintptr_t)nsc_null, _I(attach), 56 "Detach", (uintptr_t)nsc_null, _I(detach), 57 "Flush", (uintptr_t)nsc_null, _I(flush), 58 "Provide", 0, _I(provide), 59 0, 0, 0 60 }; 61 62 nsc_def_t _nsc_fd_def[] = { 63 "Pinned", (uintptr_t)nsc_null, _F(sf_pinned), 64 "Unpinned", (uintptr_t)nsc_null, _F(sf_unpinned), 65 "Attach", (uintptr_t)nsc_null, _F(sf_attach), 66 "Detach", (uintptr_t)nsc_null, _F(sf_detach), 67 "Flush", (uintptr_t)nsc_null, _F(sf_flush), 68 0, 0, 0 69 }; 70 71 kmutex_t _nsc_io_lock; 72 kmutex_t _nsc_devval_lock; 73 74 nsc_io_t *_nsc_io_top = NULL; 75 nsc_io_t *_nsc_null_io = NULL; 76 nsc_dev_t *_nsc_dev_top = NULL; 77 nsc_dev_t *_nsc_dev_pend = NULL; 78 nsc_path_t *_nsc_path_top = NULL; 79 nsc_devval_t *_nsc_devval_top = NULL; 80 81 extern nsc_def_t _nsc_disk_def[]; 82 extern nsc_def_t _nsc_cache_def[]; 83 84 extern nsc_mem_t *_nsc_local_mem; 85 extern nsc_rmmap_t *_nsc_global_map; 86 87 static clock_t _nsc_io_lbolt; 88 89 static nsc_io_t *_nsc_find_io(char *, int, int *); 90 nsc_io_t *_nsc_reserve_io(char *, int); 91 static nsc_io_t *_nsc_alloc_io(int, char *, int); 92 93 static int _nsc_open_fn(nsc_fd_t *, int); 94 static int _nsc_close_fn(nsc_fd_t *); 95 static int _nsc_alloc_fd(char *, int, int, nsc_fd_t **); 96 static int _nsc_alloc_iodev(nsc_dev_t *, int, nsc_iodev_t **); 97 static int _nsc_alloc_dev(char *, nsc_dev_t **); 98 static int _nsc_reopen_io(char *, int); 99 static int _nsc_reopen_dev(nsc_dev_t *, int); 100 static int _nsc_relock_dev(nsc_dev_t *, nsc_fd_t *, nsc_iodev_t *); 101 static int _nsc_reopen_fd(nsc_fd_t *, int); 102 static int _nsc_decode_io(nsc_def_t *, nsc_io_t *); 103 104 void _nsc_release_io(nsc_io_t *); 105 static void _nsc_free_fd(nsc_fd_t *); 106 static void _nsc_free_iodev(nsc_iodev_t *); 107 static void _nsc_free_dev(nsc_dev_t *); 108 static void _nsc_free_io(nsc_io_t *); 109 static void _nsc_relink_fd(nsc_fd_t *, nsc_fd_t **, nsc_fd_t **, nsc_iodev_t *); 110 111 static int _nsc_setval(nsc_dev_t *, char *, char *, int, int); 112 static void r_nsc_setval(ncall_t *, int *); 113 static void r_nsc_setval_all(ncall_t *, int *); 114 115 extern void _nsc_add_disk(nsc_io_t *); 116 extern void _nsc_add_cache(nsc_io_t *); 117 118 119 /* 120 * void 121 * _nsc_init_dev (void) 122 * Initialise device subsystem. 123 * 124 * Calling/Exit State: 125 * Called at driver initialisation time to allocate necessary 126 * data structures. 127 */ 128 void 129 _nsc_init_dev() 130 { 131 mutex_init(&_nsc_io_lock, NULL, MUTEX_DRIVER, NULL); 132 mutex_init(&_nsc_devval_lock, NULL, MUTEX_DRIVER, NULL); 133 134 _nsc_null_io = nsc_register_io("null", NSC_NULL, (nsc_def_t *)0); 135 136 if (!_nsc_null_io) 137 cmn_err(CE_PANIC, "nsctl: nsc_init_dev"); 138 139 ncall_register_svc(NSC_SETVAL_ALL, r_nsc_setval_all); 140 ncall_register_svc(NSC_SETVAL, r_nsc_setval); 141 } 142 143 144 void 145 _nsc_deinit_dev() 146 { 147 nsc_devval_t *dv; 148 nsc_val_t *vp; 149 150 mutex_enter(&_nsc_devval_lock); 151 152 while ((dv = _nsc_devval_top) != NULL) { 153 while ((vp = dv->dv_values) != NULL) { 154 dv->dv_values = vp->sv_next; 155 nsc_kmem_free(vp, sizeof (*vp)); 156 } 157 158 _nsc_devval_top = dv->dv_next; 159 nsc_kmem_free(dv, sizeof (*dv)); 160 } 161 162 mutex_exit(&_nsc_devval_lock); 163 164 ncall_unregister_svc(NSC_SETVAL_ALL); 165 ncall_unregister_svc(NSC_SETVAL); 166 167 mutex_destroy(&_nsc_devval_lock); 168 mutex_destroy(&_nsc_io_lock); 169 } 170 171 172 /* 173 * nsc_io_t * 174 * nsc_register_io (char *name, int type, nsc_def_t *def) 175 * Register an I/O module. 176 * 177 * Calling/Exit State: 178 * Returns a token for use in future calls to nsc_unregister_io. 179 * The ID and flags for the module are specified by 'type' and 180 * the appropriate entry points are defined using 'def'. If 181 * registration fails NULL is returned. 182 * 183 * Description: 184 * Registers an I/O module for use by subsequent calls to 185 * nsc_open. 186 */ 187 nsc_io_t * 188 nsc_register_io(name, type, def) 189 char *name; 190 int type; 191 nsc_def_t *def; 192 { 193 nsc_io_t *io, *tp; 194 int rc, id, flag; 195 nsc_io_t **iop; 196 197 id = (type & NSC_TYPES); 198 flag = (type & ~NSC_TYPES); 199 200 if ((!(id & NSC_ID) || (id & ~NSC_IDS)) && 201 (id != NSC_NULL || _nsc_null_io)) 202 return (NULL); 203 204 if (!(io = _nsc_alloc_io(id, name, flag))) 205 return (NULL); 206 207 rc = _nsc_decode_io(def, io); 208 209 if (!rc && id != NSC_NULL) { 210 _nsc_free_io(io); 211 return (NULL); 212 } 213 214 mutex_enter(&_nsc_io_lock); 215 216 for (tp = _nsc_io_top; tp; tp = tp->next) { 217 if (strcmp(tp->name, name) == 0 || tp->id == id) { 218 mutex_exit(&_nsc_io_lock); 219 _nsc_free_io(io); 220 return (NULL); 221 } 222 } 223 224 for (iop = &_nsc_io_top; *iop; iop = &(*iop)->next) 225 if (id >= (*iop)->id) 226 break; 227 228 io->next = (*iop); 229 (*iop) = io; 230 231 _nsc_io_lbolt = nsc_lbolt(); 232 233 while ((rc = _nsc_reopen_io(NULL, 0)) != 0) 234 if (rc != ERESTART) 235 break; 236 237 mutex_exit(&_nsc_io_lock); 238 return (io); 239 } 240 241 242 /* 243 * static int 244 * _nsc_decode_io (nsc_def_t *def, nsc_io_t *io) 245 * Decode I/O module definition. 246 * 247 * Calling/Exit State: 248 * Returns TRUE if the definition contains an adequate 249 * description of an I/O module. 250 * 251 * Description: 252 * Decode the definition of an I/O module and supply 253 * translation routines where possible for operations 254 * that are not defined. 255 */ 256 static int 257 _nsc_decode_io(def, io) 258 nsc_def_t *def; 259 nsc_io_t *io; 260 { 261 nsc_decode_param(def, _nsc_io_def, (long *)io); 262 nsc_decode_param(def, _nsc_disk_def, (long *)io); 263 nsc_decode_param(def, _nsc_cache_def, (long *)io); 264 265 _nsc_add_disk(io); 266 _nsc_add_cache(io); 267 268 return (1); 269 } 270 271 272 /* 273 * int 274 * nsc_unregister_io (nsc_io_t *io, int flag) 275 * Un-register an I/O module. 276 * 277 * Calling/Exit State: 278 * Returns 0 on success, otherwise returns an error code. 279 * 280 * Description: 281 * The specified I/O module is un-registered if possible. 282 * All open file descriptors using the module will be closed 283 * in preparation for a subsequent re-open. 284 * 285 * If NSC_PCATCH is specified and a signal is received, 286 * the unregister will be terminated and EINTR returned. 287 */ 288 int 289 nsc_unregister_io(nsc_io_t *io, int flag) 290 { 291 nsc_path_t *sp; 292 nsc_io_t *xio; 293 int rc = 0; 294 295 if (io == _nsc_null_io) 296 return (EINVAL); 297 298 mutex_enter(&_nsc_io_lock); 299 300 for (xio = _nsc_io_top; xio; xio = xio->next) 301 if (xio == io) 302 break; 303 304 if (!xio || io->pend) { 305 mutex_exit(&_nsc_io_lock); 306 return (xio ? EALREADY : 0); 307 } 308 309 io->pend = 1; 310 lp: 311 for (sp = _nsc_path_top; sp; sp = sp->sp_next) 312 if (sp->sp_io == io) { 313 mutex_exit(&_nsc_io_lock); 314 315 if ((rc = nsc_unregister_path(sp, flag)) != 0) { 316 io->pend = 0; 317 return (rc); 318 } 319 320 mutex_enter(&_nsc_io_lock); 321 goto lp; 322 } 323 324 _nsc_io_lbolt = nsc_lbolt(); 325 326 while (io->refcnt && !rc) { 327 while ((rc = _nsc_reopen_io(NULL, flag)) != 0) 328 if (rc != ERESTART) 329 break; 330 331 if (rc || !io->refcnt) 332 break; 333 334 if (!cv_wait_sig(&io->cv, &_nsc_io_lock)) 335 rc = EINTR; 336 } 337 338 /* 339 * We have tried to get rid of all the IO provider's clients. 340 * If there are still anonymous buffers outstanding, then fail 341 * the unregister. 342 */ 343 344 if (!rc && io->abufcnt > 0) 345 rc = EUSERS; 346 347 if (rc) 348 io->pend = 0; 349 350 mutex_exit(&_nsc_io_lock); 351 352 if (!rc) 353 _nsc_free_io(io); 354 355 return (rc); 356 } 357 358 359 /* 360 * nsc_path_t * 361 * nsc_register_path (char *path, int type, nsc_io_t *io) 362 * Register interest in pathname. 363 * 364 * Calling/Exit State: 365 * Returns a token for use in future calls to 366 * nsc_unregister_path. The 'path' argument can contain 367 * wild characters. If registration fails NULL is returned. 368 * May not be called for io providers that support NSC_ANON. 369 * 370 * Description: 371 * Registers an interest in any pathnames matching 'path' 372 * which are opened with the specified type. 373 */ 374 nsc_path_t * 375 nsc_register_path(char *path, int type, nsc_io_t *io) 376 { 377 nsc_path_t *sp, **spp; 378 int rc; 379 380 if ((type & NSC_IDS) || !io || (io->provide & NSC_ANON) || 381 !(sp = nsc_kmem_zalloc(sizeof (*sp), KM_SLEEP, _nsc_local_mem))) 382 return (NULL); 383 384 sp->sp_path = nsc_strdup(path); 385 sp->sp_type = type; 386 sp->sp_io = io; 387 388 mutex_enter(&_nsc_io_lock); 389 390 for (spp = &_nsc_path_top; *spp; spp = &(*spp)->sp_next) 391 if (io->id >= (*spp)->sp_io->id) 392 break; 393 394 sp->sp_next = (*spp); 395 (*spp) = sp; 396 397 _nsc_io_lbolt = nsc_lbolt(); 398 399 while ((rc = _nsc_reopen_io(path, 0)) != 0) 400 if (rc != ERESTART) 401 break; 402 403 mutex_exit(&_nsc_io_lock); 404 return (sp); 405 } 406 407 408 /* 409 * int 410 * nsc_unregister_path (nsc_path_t *sp, int flag) 411 * Un-register interest in pathname. 412 * 413 * Calling/Exit State: 414 * Returns 0 on success, otherwise returns an error code. 415 * 416 * Description: 417 * Interest in the specified pathname is un-registered 418 * if possible. All appropriate file descriptors will be 419 * closed in preparation for a subsequent re-open. 420 * 421 * If NSC_PCATCH is specified and a signal is received, 422 * the unregister will be terminated and EINTR returned. 423 */ 424 int 425 nsc_unregister_path(sp, flag) 426 nsc_path_t *sp; 427 int flag; 428 { 429 nsc_path_t *xsp, **spp; 430 int rc; 431 432 mutex_enter(&_nsc_io_lock); 433 434 for (xsp = _nsc_path_top; xsp; xsp = xsp->sp_next) 435 if (xsp == sp) 436 break; 437 438 if (!xsp || sp->sp_pend) { 439 mutex_exit(&_nsc_io_lock); 440 return (xsp ? EALREADY : 0); 441 } 442 443 sp->sp_pend = 1; 444 _nsc_io_lbolt = nsc_lbolt(); 445 446 while ((rc = _nsc_reopen_io(sp->sp_path, flag)) != 0) 447 if (rc != ERESTART) { 448 sp->sp_pend = 0; 449 mutex_exit(&_nsc_io_lock); 450 return (rc); 451 } 452 453 for (spp = &_nsc_path_top; *spp; spp = &(*spp)->sp_next) 454 if (*spp == sp) 455 break; 456 457 if (*spp) 458 (*spp) = sp->sp_next; 459 460 mutex_exit(&_nsc_io_lock); 461 462 nsc_strfree(sp->sp_path); 463 nsc_kmem_free(sp, sizeof (*sp)); 464 return (0); 465 } 466 467 468 /* 469 * static int 470 * _nsc_reopen_io (char *path, int flag) 471 * Force re-open of all file descriptors. 472 * 473 * Calling/Exit State: 474 * The _nsc_io_lock must be held across calls to 475 * this function. 476 * 477 * Returns 0 if the force succeeds without releasing 478 * _nsc_io_lock, otherwise returns an error code. 479 * 480 * Description: 481 * A re-open is forced for all file descriptors as 482 * appropriate. For performance reasons available 483 * devices are re-opened before those that would block. 484 */ 485 static int 486 _nsc_reopen_io(path, flag) 487 char *path; 488 int flag; 489 { 490 nsc_dev_t *dp, *dev; 491 int rc, errno = 0; 492 int try, run; 493 494 for (run = 1, try = (NSC_TRY | NSC_DEFER); run--; try = 0) { 495 for (dev = _nsc_dev_top; dev; dev = dev->nsc_next) { 496 if (path && !nsc_strmatch(dev->nsc_path, path)) 497 continue; 498 499 if (!(rc = _nsc_reopen_dev(dev, flag | try))) 500 continue; 501 502 for (dp = _nsc_dev_top; dp; dp = dp->nsc_next) 503 if (dp == dev) 504 break; 505 506 if (!dp) 507 return (ERESTART); 508 509 if (try && !(flag & NSC_TRY)) 510 run = 1; 511 if (!run && errno != ERESTART) 512 errno = rc; 513 } 514 } 515 516 return (errno); 517 } 518 519 520 /* 521 * static int 522 * _nsc_reopen_dev (nsc_dev_t *dev, int flag) 523 * Force re-open of entire device. 524 * 525 * Calling/Exit State: 526 * The _nsc_io_lock must be held across calls to 527 * this function. 528 * 529 * Returns 0 if the force succeeds without releasing 530 * _nsc_io_lock, otherwise returns an error code. 531 * 532 * Description: 533 * A re-open is forced for all file descriptors for the 534 * device as appropriate. 535 */ 536 static int 537 _nsc_reopen_dev(dev, flag) 538 nsc_dev_t *dev; 539 int flag; 540 { 541 int rc, errno = 0; 542 nsc_iodev_t *iodev; 543 int try, run; 544 nsc_fd_t *fd; 545 546 mutex_enter(&dev->nsc_lock); 547 548 for (run = 1, try = (NSC_TRY | NSC_DEFER); run--; try = 0) 549 for (iodev = dev->nsc_list; iodev; iodev = iodev->si_next) { 550 for (fd = iodev->si_open; fd; fd = fd->sf_next) { 551 if (!(rc = _nsc_reopen_fd(fd, flag | try))) 552 continue; 553 554 if (rc == -ERESTART) 555 return (ERESTART); 556 557 if (!_nsc_relock_dev(dev, fd, iodev)) 558 return (ERESTART); 559 560 if (try && !(flag & NSC_TRY)) 561 run = 1; 562 if (!run && errno != ERESTART) 563 errno = rc; 564 } 565 } 566 567 for (run = 1, try = (NSC_TRY | NSC_DEFER); run--; try = 0) 568 for (fd = dev->nsc_close; fd; fd = fd->sf_next) { 569 if (!(rc = _nsc_reopen_fd(fd, flag | try))) 570 continue; 571 572 if (rc == -ERESTART) 573 return (ERESTART); 574 575 if (!_nsc_relock_dev(dev, fd, NULL)) 576 return (ERESTART); 577 578 if (try && !(flag & NSC_TRY)) 579 run = 1; 580 if (!run && errno != ERESTART) 581 errno = rc; 582 } 583 584 mutex_exit(&dev->nsc_lock); 585 return (errno); 586 } 587 588 589 /* 590 * static int 591 * _nsc_relock_dev (nsc_dev_t *dev, nsc_fd_t *fd, nsc_iodev_t *iodev) 592 * Relock device structure if possible. 593 * 594 * Calling/Exit State: 595 * The _nsc_io_lock must be held across calls to 596 * this function. 597 * 598 * Checks whether the file descriptor is still part 599 * of the specified device and I/O device. If so the 600 * device lock is taken. Otherwise FALSE is returned. 601 */ 602 static int 603 _nsc_relock_dev(nsc_dev_t *dev, nsc_fd_t *fd, nsc_iodev_t *iodev) 604 { 605 nsc_fd_t *fp = NULL; 606 nsc_iodev_t *iop; 607 nsc_dev_t *dp; 608 609 for (dp = _nsc_dev_top; dp; dp = dp->nsc_next) 610 if (dp == dev) 611 break; 612 613 if (!dp) 614 return (0); 615 616 mutex_enter(&dev->nsc_lock); 617 618 if (iodev) 619 for (iop = dev->nsc_list; iop; iop = iop->si_next) 620 if (iop == iodev) 621 break; 622 623 if (!iodev || iop) { 624 fp = (iodev) ? iodev->si_open : dev->nsc_close; 625 626 for (; fp; fp = fp->sf_next) 627 if (fp == fd) 628 break; 629 } 630 631 if (!fp) { 632 mutex_exit(&dev->nsc_lock); 633 return (0); 634 } 635 636 return (1); 637 } 638 639 640 /* 641 * static int 642 * _nsc_reopen_fd (nsc_fd_t *dev, int flag) 643 * Force re-open of file descriptor. 644 * 645 * Calling/Exit State: 646 * Both _nsc_io_lock and the device lock must be held 647 * across calls to this function. 648 * 649 * Returns 0 if the force succeeds without releasing 650 * any locks, otherwise returns an error code. If an 651 * error code is returned the device lock is released. 652 * 653 * Description: 654 * If appropriate the file descriptor is closed in order 655 * to force a subsequent open using the currently available 656 * resources. 657 */ 658 static int 659 _nsc_reopen_fd(fd, flag) 660 nsc_fd_t *fd; 661 int flag; 662 { 663 nsc_dev_t *dev = fd->sf_dev; 664 nsc_iodev_t *iodev = fd->sf_iodev; 665 int changed = 0; 666 int rc; 667 668 if (!fd->sf_pend && !iodev) 669 return (0); 670 671 if (fd->sf_pend == _NSC_OPEN) 672 if (fd->sf_lbolt - _nsc_io_lbolt > 0) 673 return (0); 674 675 if (iodev && 676 (iodev->si_io == 677 _nsc_find_io(dev->nsc_path, fd->sf_type, &changed)) && 678 !changed) 679 return (0); 680 681 if (iodev) 682 fd->sf_reopen = 1; 683 684 mutex_exit(&_nsc_io_lock); 685 686 dev->nsc_reopen = 1; 687 688 rc = _nsc_close_fd(fd, flag); 689 690 dev->nsc_reopen = 0; 691 692 if (rc == EAGAIN && (flag & NSC_DEFER) && fd->sf_reopen) 693 dev->nsc_drop = 1; 694 695 mutex_exit(&dev->nsc_lock); 696 697 if (rc == -ERESTART) 698 delay(2); /* allow other threads cpu time */ 699 700 mutex_enter(&_nsc_io_lock); 701 return (rc ? rc : ERESTART); 702 } 703 704 705 /* 706 * nsc_fd_t * 707 * nsc_open (char *path, int type, nsc_def_t *def, blind_t arg, int *sts) 708 * Open file descriptor for pathname. 709 * 710 * Calling/Exit State: 711 * Returns file descriptor if open succeeds, otherwise 712 * returns 0 and puts error code in the location pointed 713 * to by sts. 714 * 715 * Description: 716 * Open the specified pathname using an appropriate access 717 * method. 718 */ 719 nsc_fd_t * 720 nsc_open(path, type, def, arg, sts) 721 char *path; 722 int type; 723 nsc_def_t *def; 724 blind_t arg; 725 int *sts; 726 { 727 int flag, rc; 728 nsc_fd_t *fd; 729 730 flag = (type & ~NSC_TYPES); 731 type &= NSC_TYPES; 732 733 if ((flag & NSC_READ) == 0) 734 flag |= NSC_RDWR; 735 736 if ((rc = _nsc_alloc_fd(path, type, flag, &fd)) != 0) { 737 if (sts) 738 *sts = rc; 739 return (NULL); 740 } 741 742 fd->sf_arg = arg; 743 fd->sf_aio = _nsc_null_io; 744 745 nsc_decode_param(def, _nsc_fd_def, (long *)fd); 746 747 mutex_enter(&fd->sf_dev->nsc_lock); 748 749 while ((rc = _nsc_open_fd(fd, flag)) != 0) 750 if (rc != ERESTART) 751 break; 752 753 mutex_exit(&fd->sf_dev->nsc_lock); 754 755 if (rc) { 756 _nsc_free_fd(fd); 757 if (sts) 758 *sts = rc; 759 return (NULL); 760 } 761 762 return (fd); 763 } 764 765 766 /* 767 * int 768 * _nsc_open_fd (nsc_fd_t *fd, int flag) 769 * Open file descriptor. 770 * 771 * Calling/Exit State: 772 * The device lock must be held across calls to 773 * this function. 774 * 775 * Returns 0 if the open succeeds, otherwise 776 * returns an error code. 777 * 778 * Description: 779 * Open the specified file descriptor. 780 */ 781 int 782 _nsc_open_fd(fd, flag) 783 nsc_fd_t *fd; 784 int flag; 785 { 786 nsc_dev_t *dev = fd->sf_dev; 787 int rc; 788 789 if (fd->sf_pend) 790 return (_nsc_wait_dev(dev, flag)); 791 792 if (fd->sf_iodev) 793 return (0); 794 if (flag & NSC_NOBLOCK) 795 return (EAGAIN); 796 797 fd->sf_pend = _NSC_OPEN; 798 fd->sf_lbolt = nsc_lbolt(); 799 800 mutex_exit(&dev->nsc_lock); 801 802 rc = _nsc_open_fn(fd, flag); 803 804 mutex_enter(&dev->nsc_lock); 805 fd->sf_pend = 0; 806 807 if (!rc) 808 fd->sf_iodev->si_pend = 0; 809 810 if (dev->nsc_wait || dev->nsc_refcnt <= 0) 811 cv_broadcast(&dev->nsc_cv); 812 813 return (rc ? rc : ERESTART); 814 } 815 816 817 /* 818 * static int 819 * _nsc_open_fn (nsc_fd_t *fd, int flag) 820 * Allocate I/O device and open file descriptor. 821 * 822 * Calling/Exit State: 823 * No locks may be held across this function. 824 * 825 * If the open succeeds an I/O device will be 826 * attached to the file descriptor, marked as 827 * pending and 0 returned. Otherwise, returns 828 * an error code. 829 * 830 * Description: 831 * Allocate an I/O device and open the specified 832 * file descriptor. 833 */ 834 static int 835 _nsc_open_fn(fd, flag) 836 nsc_fd_t *fd; 837 int flag; 838 { 839 nsc_dev_t *dev = fd->sf_dev; 840 nsc_iodev_t *iodev; 841 int rc; 842 843 if ((rc = _nsc_alloc_iodev(dev, fd->sf_type, &iodev)) != 0) 844 return (rc); 845 846 mutex_enter(&dev->nsc_lock); 847 848 if (iodev->si_pend) { 849 rc = _nsc_wait_dev(dev, flag); 850 mutex_exit(&dev->nsc_lock); 851 _nsc_free_iodev(iodev); 852 return (rc); 853 } 854 855 iodev->si_pend = _NSC_OPEN; 856 mutex_exit(&dev->nsc_lock); 857 858 rc = (*iodev->si_io->open)(dev->nsc_path, 859 (fd->sf_flag & ~NSC_RDWR), &fd->sf_cd, iodev); 860 861 if (rc) { 862 iodev->si_pend = 0; 863 _nsc_free_iodev(iodev); 864 return (rc); 865 } 866 867 /* save away the DevMaj and DevMin values */ 868 if (iodev->si_io->id == NSC_RAW_ID) { 869 rc = _nsc_setval(dev, NULL, NSC_DEVMAJ, 870 (int)getmajor((dev_t)fd->sf_cd), FALSE); 871 #ifdef DEBUG 872 if (rc != 1) { 873 cmn_err(CE_NOTE, "!nsctl: could not set DevMaj (%s:%x)", 874 dev->nsc_path, (int)getmajor((dev_t)fd->sf_cd)); 875 } 876 #endif 877 878 rc = _nsc_setval(dev, NULL, NSC_DEVMIN, 879 (int)getminor((dev_t)fd->sf_cd), FALSE); 880 #ifdef DEBUG 881 if (rc != 1) { 882 cmn_err(CE_NOTE, "!nsctl: could not set DevMin (%s:%x)", 883 dev->nsc_path, (int)getminor((dev_t)fd->sf_cd)); 884 } 885 #endif 886 } 887 888 fd->sf_iodev = iodev; 889 _nsc_relink_fd(fd, &dev->nsc_close, &iodev->si_open, iodev); 890 891 return (0); 892 } 893 894 895 /* 896 * int 897 * nsc_close (nsc_fd_t *fd) 898 * Close file descriptor for pathname. 899 * 900 * Calling/Exit State: 901 * Returns 0 if close succeeds, otherwise returns error 902 * code. 903 * 904 * Description: 905 * Close the specified file descriptor. It is assumed 906 * that all other users of this file descriptor have 907 * finished. Any reserve will be discarded before the 908 * close is performed. 909 */ 910 int 911 nsc_close(fd) 912 nsc_fd_t *fd; 913 { 914 int rc; 915 916 if (!fd) 917 return (0); 918 919 while (fd->sf_reserve) 920 nsc_release(fd); 921 922 mutex_enter(&fd->sf_dev->nsc_lock); 923 924 fd->sf_owner = NULL; 925 926 while ((rc = _nsc_close_fd(fd, 0)) != 0) 927 if (rc != ERESTART) 928 break; 929 930 nsc_decode_param(_nsc_fd_def, _nsc_fd_def, (long *)fd); 931 932 mutex_exit(&fd->sf_dev->nsc_lock); 933 934 if (!rc) 935 _nsc_free_fd(fd); 936 return (rc); 937 } 938 939 940 /* 941 * int 942 * _nsc_close_fd (nsc_fd_t *fd, int flag) 943 * Close file descriptor. 944 * 945 * Calling/Exit State: 946 * The device lock must be held across calls to 947 * this function. 948 * 949 * Returns 0 if the close succeeds, otherwise 950 * returns an error code. 951 * 952 * Description: 953 * Close the specified file descriptor. 954 */ 955 int 956 _nsc_close_fd(fd, flag) 957 nsc_fd_t *fd; 958 int flag; 959 { 960 nsc_dev_t *dev = fd->sf_dev; 961 nsc_iodev_t *iodev; 962 int rc; 963 964 if (fd->sf_pend) { 965 if (fd->sf_pend == _NSC_CLOSE && dev->nsc_reopen != 0) 966 return (-ERESTART); 967 968 return (_nsc_wait_dev(dev, flag)); 969 } 970 971 flag |= NSC_RDWR; 972 iodev = fd->sf_iodev; 973 974 if (!iodev) 975 return (0); 976 977 if ((rc = _nsc_detach_fd(fd, flag)) != 0) 978 return (rc); 979 980 if (iodev->si_pend) 981 return (_nsc_wait_dev(dev, flag)); 982 983 if (iodev->si_open == fd && !fd->sf_next) { 984 if ((rc = _nsc_detach_iodev(iodev, NULL, flag)) != 0) 985 return (rc); 986 987 if (dev->nsc_list == iodev && !iodev->si_next) 988 if ((rc = _nsc_detach_dev(dev, NULL, flag)) != 0) 989 return (rc); 990 } 991 992 if (flag & NSC_NOBLOCK) 993 return (EAGAIN); 994 995 fd->sf_pend = _NSC_CLOSE; 996 iodev->si_pend = _NSC_CLOSE; 997 mutex_exit(&dev->nsc_lock); 998 999 rc = _nsc_close_fn(fd); 1000 1001 mutex_enter(&dev->nsc_lock); 1002 fd->sf_pend = 0; 1003 1004 fd->sf_reopen = 0; 1005 if (rc) 1006 iodev->si_pend = 0; 1007 1008 if (dev->nsc_wait || dev->nsc_refcnt <= 0) 1009 cv_broadcast(&dev->nsc_cv); 1010 1011 return (rc ? rc : ERESTART); 1012 } 1013 1014 1015 /* 1016 * static int 1017 * _nsc_close_fn (nsc_fd_t *fd) 1018 * Close file descriptor and free I/O device. 1019 * 1020 * Calling/Exit State: 1021 * No locks may be held across this function. 1022 * 1023 * Returns 0 if the close succeeds, otherwise 1024 * returns an error code. 1025 * 1026 * If the close succeeds the I/O device will be 1027 * detached from the file descriptor, released 1028 * and 0 returned. Otherwise, returns an error 1029 * code. 1030 * 1031 * Description: 1032 * Close the specified file descriptor and free 1033 * the I/O device. 1034 */ 1035 static int 1036 _nsc_close_fn(fd) 1037 nsc_fd_t *fd; 1038 { 1039 nsc_iodev_t *iodev = fd->sf_iodev; 1040 nsc_dev_t *dev = fd->sf_dev; 1041 int last, rc; 1042 1043 last = (iodev->si_open == fd && !fd->sf_next); 1044 1045 if (last || (iodev->si_io->flag & NSC_REFCNT)) 1046 if ((rc = (*iodev->si_io->close)(fd->sf_cd)) != 0) 1047 return (rc); 1048 1049 fd->sf_iodev = NULL; 1050 _nsc_relink_fd(fd, &iodev->si_open, &dev->nsc_close, iodev); 1051 1052 iodev->si_pend = 0; 1053 _nsc_free_iodev(iodev); 1054 1055 return (0); 1056 } 1057 1058 1059 /* 1060 * void 1061 * nsc_set_owner (nsc_fd_t *fd, nsc_iodev_t *iodev) 1062 * Set owner associated with file descriptor. 1063 * 1064 * Calling/Exit State: 1065 * Sets the owner field in the file descriptor. 1066 */ 1067 void 1068 nsc_set_owner(nsc_fd_t *fd, nsc_iodev_t *iodev) 1069 { 1070 if (fd) { 1071 mutex_enter(&fd->sf_dev->nsc_lock); 1072 fd->sf_owner = iodev; 1073 mutex_exit(&fd->sf_dev->nsc_lock); 1074 } 1075 } 1076 1077 1078 /* 1079 * char * 1080 * nsc_pathname (nsc_fd_t *fd) 1081 * Pathname associated with file descriptor. 1082 * 1083 * Calling/Exit State: 1084 * Returns a pointer to the pathname associated 1085 * with the given file descriptor. 1086 */ 1087 char * 1088 nsc_pathname(fd) 1089 nsc_fd_t *fd; 1090 { 1091 return ((fd) ? (fd->sf_dev->nsc_path) : 0); 1092 } 1093 1094 1095 /* 1096 * int 1097 * nsc_fdpathcmp(nsc_fd_t *fd, uint64_t phash, char *path) 1098 * Compare fd to pathname and hash 1099 * 1100 * Calling/Exit State: 1101 * Returns comparison value like strcmp(3C). 1102 * 1103 * Description: 1104 * Does an optimised comparison of the pathname and associated hash 1105 * value (as returned from nsc_strhash()) against the pathname of 1106 * the filedescriptor, fd. 1107 */ 1108 int 1109 nsc_fdpathcmp(nsc_fd_t *fd, uint64_t phash, char *path) 1110 { 1111 int rc = -1; 1112 1113 if (fd != NULL && fd->sf_dev->nsc_phash == phash) 1114 rc = strcmp(fd->sf_dev->nsc_path, path); 1115 1116 return (rc); 1117 } 1118 1119 1120 static int 1121 _nsc_setval(nsc_dev_t *dev, char *path, char *name, int val, int do_ncall) 1122 { 1123 nsc_devval_t *dv; 1124 nsc_rval_t *rval; 1125 ncall_t *ncall; 1126 nsc_val_t *vp; 1127 uint64_t phash; 1128 char *pp; 1129 int rc; 1130 1131 ASSERT(dev != NULL || path != NULL); 1132 #ifdef DEBUG 1133 if (dev != NULL && path != NULL) { 1134 ASSERT(strcmp(dev->nsc_path, path) == 0); 1135 } 1136 #endif 1137 1138 pp = (dev != NULL) ? dev->nsc_path : path; 1139 1140 if (strlen(name) >= NSC_SETVAL_MAX) { 1141 #ifdef DEBUG 1142 cmn_err(CE_WARN, "!nsc_setval: max name size(%d) exceeded(%d)", 1143 NSC_SETVAL_MAX-1, (int)strlen(name)); 1144 #endif 1145 return (0); 1146 } 1147 1148 phash = nsc_strhash(pp); 1149 1150 mutex_enter(&_nsc_devval_lock); 1151 1152 if (dev != NULL) 1153 dv = dev->nsc_values; 1154 else { 1155 for (dv = _nsc_devval_top; dv != NULL; dv = dv->dv_next) { 1156 if (phash == dv->dv_phash && 1157 strcmp(pp, dv->dv_path) == 0) 1158 /* found dv for device */ 1159 break; 1160 } 1161 } 1162 1163 if (dv == NULL) { 1164 dv = nsc_kmem_zalloc(sizeof (*dv), KM_SLEEP, _nsc_local_mem); 1165 if (dv == NULL) { 1166 mutex_exit(&_nsc_devval_lock); 1167 return (0); 1168 } 1169 1170 (void) strncpy(dv->dv_path, pp, sizeof (dv->dv_path)); 1171 dv->dv_phash = phash; 1172 1173 dv->dv_next = _nsc_devval_top; 1174 _nsc_devval_top = dv; 1175 if (dev != NULL) 1176 dev->nsc_values = dv; 1177 } 1178 1179 for (vp = dv->dv_values; vp; vp = vp->sv_next) { 1180 if (strcmp(vp->sv_name, name) == 0) { 1181 vp->sv_value = val; 1182 break; 1183 } 1184 } 1185 1186 if (vp == NULL) { 1187 vp = nsc_kmem_zalloc(sizeof (*vp), KM_SLEEP, _nsc_local_mem); 1188 if (vp != NULL) { 1189 (void) strncpy(vp->sv_name, name, sizeof (vp->sv_name)); 1190 vp->sv_value = val; 1191 vp->sv_next = dv->dv_values; 1192 dv->dv_values = vp; 1193 } 1194 } 1195 1196 mutex_exit(&_nsc_devval_lock); 1197 1198 /* 1199 * phoenix: ncall the new value to the other node now. 1200 */ 1201 1202 if (vp && do_ncall) { 1203 /* CONSTCOND */ 1204 ASSERT(sizeof (nsc_rval_t) <= NCALL_DATA_SZ); 1205 1206 rval = nsc_kmem_zalloc(sizeof (*rval), KM_SLEEP, 1207 _nsc_local_mem); 1208 if (rval == NULL) { 1209 goto out; 1210 } 1211 1212 rc = ncall_alloc(ncall_mirror(ncall_self()), 0, 0, &ncall); 1213 if (rc == 0) { 1214 (void) strncpy(rval->path, pp, sizeof (rval->path)); 1215 (void) strncpy(rval->name, name, sizeof (rval->name)); 1216 rval->value = val; 1217 1218 rc = ncall_put_data(ncall, rval, sizeof (*rval)); 1219 if (rc == 0) { 1220 /* 1221 * Send synchronously and read a reply 1222 * so that we know that the remote 1223 * setval has completed before this 1224 * function returns and hence whilst 1225 * the device is still reserved on this 1226 * node. 1227 */ 1228 if (ncall_send(ncall, 0, NSC_SETVAL) == 0) 1229 (void) ncall_read_reply(ncall, 1, &rc); 1230 } 1231 1232 ncall_free(ncall); 1233 } 1234 1235 nsc_kmem_free(rval, sizeof (*rval)); 1236 } 1237 1238 out: 1239 return (vp ? 1 : 0); 1240 } 1241 1242 1243 /* ARGSUSED */ 1244 1245 static void 1246 r_nsc_setval(ncall_t *ncall, int *ap) 1247 { 1248 nsc_rval_t *rval; 1249 int rc; 1250 1251 rval = nsc_kmem_zalloc(sizeof (*rval), KM_SLEEP, _nsc_local_mem); 1252 if (rval == NULL) { 1253 ncall_reply(ncall, ENOMEM); 1254 return; 1255 } 1256 1257 rc = ncall_get_data(ncall, rval, sizeof (*rval)); 1258 if (rc != 0) { 1259 ncall_reply(ncall, EFAULT); 1260 return; 1261 } 1262 1263 if (_nsc_setval(NULL, rval->path, rval->name, rval->value, FALSE)) 1264 rc = 0; 1265 else 1266 rc = ENOMEM; 1267 1268 ncall_reply(ncall, rc); 1269 nsc_kmem_free(rval, sizeof (*rval)); 1270 } 1271 1272 1273 /* ARGSUSED */ 1274 1275 static void 1276 r_nsc_setval_all(ncall_t *ncall, int *ap) 1277 { 1278 nsc_rval_t *in = NULL, *out = NULL; 1279 nsc_devval_t *dv; 1280 nsc_val_t *vp; 1281 ncall_t *np; 1282 uint64_t phash; 1283 int rc; 1284 1285 /* CONSTCOND */ 1286 ASSERT(sizeof (nsc_rval_t) <= NCALL_DATA_SZ); 1287 1288 in = nsc_kmem_zalloc(sizeof (*in), KM_SLEEP, _nsc_local_mem); 1289 out = nsc_kmem_zalloc(sizeof (*out), KM_SLEEP, _nsc_local_mem); 1290 if (in == NULL || out == NULL) { 1291 if (in != NULL) { 1292 nsc_kmem_free(in, sizeof (*in)); 1293 in = NULL; 1294 } 1295 if (out != NULL) { 1296 nsc_kmem_free(out, sizeof (*out)); 1297 out = NULL; 1298 } 1299 ncall_reply(ncall, ENOMEM); 1300 } 1301 1302 rc = ncall_get_data(ncall, in, sizeof (*in)); 1303 if (rc != 0) { 1304 ncall_reply(ncall, EFAULT); 1305 return; 1306 } 1307 1308 phash = nsc_strhash(in->path); 1309 1310 (void) strncpy(out->path, in->path, sizeof (out->path)); 1311 1312 rc = ncall_alloc(ncall_mirror(ncall_self()), 0, 0, &np); 1313 if (rc != 0) { 1314 ncall_reply(ncall, ENOMEM); 1315 return; 1316 } 1317 1318 mutex_enter(&_nsc_devval_lock); 1319 1320 for (dv = _nsc_devval_top; dv; dv = dv->dv_next) { 1321 if (dv->dv_phash == phash && 1322 strcmp(dv->dv_path, in->path) == 0) 1323 break; 1324 } 1325 1326 if (dv) { 1327 for (vp = dv->dv_values; vp; vp = vp->sv_next) { 1328 if (strcmp(vp->sv_name, NSC_DEVMIN) == 0 || 1329 strcmp(vp->sv_name, NSC_DEVMAJ) == 0) { 1330 /* ignore the implicit DevMin/DevMaj values */ 1331 continue; 1332 } 1333 1334 (void) strncpy(out->name, vp->sv_name, 1335 sizeof (out->name)); 1336 out->value = vp->sv_value; 1337 1338 rc = ncall_put_data(np, out, sizeof (*out)); 1339 if (rc == 0) { 1340 /* 1341 * Send synchronously and read a reply 1342 * so that we know that the remote 1343 * setval has completed before this 1344 * function returns. 1345 */ 1346 if (ncall_send(np, 0, NSC_SETVAL) == 0) 1347 (void) ncall_read_reply(np, 1, &rc); 1348 } 1349 1350 ncall_reset(np); 1351 } 1352 1353 ncall_free(np); 1354 rc = 0; 1355 } else { 1356 rc = ENODEV; 1357 } 1358 1359 mutex_exit(&_nsc_devval_lock); 1360 1361 ncall_reply(ncall, rc); 1362 1363 nsc_kmem_free(out, sizeof (*out)); 1364 nsc_kmem_free(in, sizeof (*in)); 1365 } 1366 1367 1368 /* 1369 * int 1370 * nsc_setval (nsc_fd_t *fd, char *name, int val) 1371 * Set value for device. 1372 * 1373 * Calling/Exit State: 1374 * Returns 1 if the value has been set, otherwise 0. 1375 * Must be called with the fd reserved. 1376 * 1377 * Description: 1378 * Sets the specified global variable for the device 1379 * to the value provided. 1380 */ 1381 int 1382 nsc_setval(nsc_fd_t *fd, char *name, int val) 1383 { 1384 if (!fd) 1385 return (0); 1386 1387 if (!nsc_held(fd)) 1388 return (0); 1389 1390 return (_nsc_setval(fd->sf_dev, NULL, name, val, TRUE)); 1391 } 1392 1393 1394 /* 1395 * int 1396 * nsc_getval (nsc_fd_t *fd, char *name, int *vp) 1397 * Get value from device. 1398 * 1399 * Calling/Exit State: 1400 * Returns 1 if the value has been found, otherwise 0. 1401 * Must be called with the fd reserved, except for "DevMaj" / "DevMin". 1402 * 1403 * Description: 1404 * Finds the value of the specified device variable for 1405 * the device and returns it in the location pointed to 1406 * by vp. 1407 */ 1408 int 1409 nsc_getval(nsc_fd_t *fd, char *name, int *vp) 1410 { 1411 nsc_devval_t *dv; 1412 nsc_val_t *val; 1413 1414 if (!fd) 1415 return (0); 1416 1417 /* 1418 * Don't check for nsc_held() for the device number values 1419 * since these are magically created and cannot change when 1420 * the fd is not reserved. 1421 */ 1422 1423 if (strcmp(name, NSC_DEVMAJ) != 0 && 1424 strcmp(name, NSC_DEVMIN) != 0 && 1425 !nsc_held(fd)) 1426 return (0); 1427 1428 mutex_enter(&_nsc_devval_lock); 1429 1430 dv = fd->sf_dev->nsc_values; 1431 val = NULL; 1432 1433 if (dv != NULL) { 1434 for (val = dv->dv_values; val; val = val->sv_next) { 1435 if (strcmp(val->sv_name, name) == 0) { 1436 *vp = val->sv_value; 1437 break; 1438 } 1439 } 1440 } 1441 1442 mutex_exit(&_nsc_devval_lock); 1443 1444 return (val ? 1 : 0); 1445 } 1446 1447 1448 /* 1449 * char * 1450 * nsc_shared (nsc_fd_t *fd) 1451 * Device is currently shared. 1452 * 1453 * Calling/Exit State: 1454 * The device lock must be held across calls to this 1455 * this function. 1456 * 1457 * Returns an indication of whether the device accessed 1458 * by the file descriptor is currently referenced by more 1459 * than one user. 1460 * 1461 * This is only intended for use in performance critical 1462 * situations. 1463 */ 1464 int 1465 nsc_shared(fd) 1466 nsc_fd_t *fd; 1467 { 1468 nsc_iodev_t *iodev; 1469 int cnt = 0; 1470 1471 if (!fd) 1472 return (0); 1473 if (!fd->sf_iodev) 1474 return (1); 1475 1476 for (iodev = fd->sf_dev->nsc_list; iodev; iodev = iodev->si_next) 1477 for (fd = iodev->si_open; fd; fd = fd->sf_next) 1478 if (!fd->sf_owner && cnt++) 1479 return (1); 1480 1481 return (0); 1482 } 1483 1484 1485 /* 1486 * kmutex_t * 1487 * nsc_lock_addr (nsc_fd_t *fd) 1488 * Address of device lock. 1489 * 1490 * Calling/Exit State: 1491 * Returns a pointer to the spin lock associated with the 1492 * device. 1493 * 1494 * Description: 1495 * This is only intended for use in performance critical 1496 * situations in conjunction with nsc_reserve_lk. 1497 */ 1498 kmutex_t * 1499 nsc_lock_addr(fd) 1500 nsc_fd_t *fd; 1501 { 1502 return (&fd->sf_dev->nsc_lock); 1503 } 1504 1505 1506 /* 1507 * int 1508 * _nsc_call_io (long f, blind_t a, blind_t b, blind_t c) 1509 * Call information function. 1510 * 1511 * Calling/Exit State: 1512 * Returns result from function or 0 if not available. 1513 * f represents the offset into the I/O structure at which 1514 * the required function can be found and a, b, c are the 1515 * desired arguments. 1516 * 1517 * Description: 1518 * Calls the requested function for the first available 1519 * cache interface. 1520 */ 1521 int 1522 _nsc_call_io(long f, blind_t a, blind_t b, blind_t c) 1523 { 1524 nsc_io_t *io; 1525 int (*fn)(); 1526 int rc; 1527 1528 io = _nsc_reserve_io(NULL, NSC_SDBC_ID); 1529 if (!io) 1530 io = _nsc_reserve_io(NULL, NSC_NULL); 1531 1532 fn = (blindfn_t)(((long *)io)[f]); 1533 rc = (*fn)(a, b, c); 1534 1535 _nsc_release_io(io); 1536 return (rc); 1537 } 1538 1539 1540 /* 1541 * nsc_io_t * 1542 * _nsc_reserve_io (char *, int type) 1543 * Reserve I/O module. 1544 * 1545 * Calling/Exit State: 1546 * Returns address of I/O structure matching specified 1547 * type, or NULL. 1548 * 1549 * Description: 1550 * Searches for an appropriate I/O module and increments 1551 * the reference count to prevent it being unregistered. 1552 */ 1553 nsc_io_t * 1554 _nsc_reserve_io(path, type) 1555 char *path; 1556 int type; 1557 { 1558 nsc_io_t *io; 1559 1560 mutex_enter(&_nsc_io_lock); 1561 1562 if ((io = _nsc_find_io(path, type, NULL)) != 0) 1563 io->refcnt++; 1564 1565 mutex_exit(&_nsc_io_lock); 1566 return (io); 1567 } 1568 1569 1570 /* 1571 * static nsc_io_t * 1572 * _nsc_find_io (char *path, int type, int *changed) 1573 * Find I/O module. 1574 * 1575 * Calling/Exit State: 1576 * The _nsc_io_lock must be held across calls to 1577 * this function. 1578 * 1579 * Returns address of I/O structure matching specified 1580 * type, or NULL. 1581 * 1582 * 'changed' will be set to non-zero if there is a pending 1583 * nsc_path_t that matches the criteria for the requested type. 1584 * This allows nsctl to distinguish between multiple 1585 * nsc_register_path's done by the same I/O provider. 1586 * 1587 * Description: 1588 * Searches for an appropriate I/O module. 1589 * 1590 * 1. If <type> is a single module id find the specified I/O 1591 * module by module id. 1592 * 1593 * 2. Find the highest module that provides any of the I/O types 1594 * included in <type>, taking into account any modules 1595 * registered via the nsc_register_path() interface if <path> 1596 * is non-NULL. 1597 * 1598 * 3. Find an I/O module following the rules in (2), but whose 1599 * module id is less than the id OR'd into <type>. 1600 * 1601 * If no module is found by the above algorithms and NSC_NULL was 1602 * included in <type>, return the _nsc_null_io module. Otherwise 1603 * return NULL. 1604 */ 1605 static nsc_io_t * 1606 _nsc_find_io(char *path, int type, int *changed) 1607 { 1608 nsc_path_t *sp = NULL; 1609 nsc_path_t *pp = NULL; 1610 nsc_io_t *io; 1611 1612 type &= NSC_TYPES; 1613 1614 if (path) { 1615 for (sp = _nsc_path_top; sp; sp = sp->sp_next) { 1616 if ((type & NSC_ID) && 1617 sp->sp_io->id >= (type & NSC_IDS)) 1618 continue; 1619 1620 if (sp->sp_pend || (type & sp->sp_type) == 0) 1621 continue; 1622 1623 if (nsc_strmatch(path, sp->sp_path)) 1624 break; 1625 } 1626 1627 if (sp) { 1628 /* look for matching pending paths */ 1629 for (pp = _nsc_path_top; pp; pp = pp->sp_next) { 1630 if (pp->sp_pend && 1631 (type & pp->sp_type) && 1632 nsc_strmatch(path, pp->sp_path)) { 1633 break; 1634 } 1635 } 1636 } 1637 } 1638 1639 for (io = _nsc_io_top; io; io = io->next) { 1640 if (io->pend) 1641 continue; 1642 1643 if (type & NSC_ID) { 1644 if ((type & ~NSC_IDS) == 0) { 1645 if (io->id == type) 1646 break; 1647 continue; 1648 } 1649 1650 if (io->id >= (type & NSC_IDS)) 1651 continue; 1652 } 1653 1654 if (io->provide & type) 1655 break; 1656 } 1657 1658 if (pp && (!io || pp->sp_io->id >= io->id)) { 1659 /* 1660 * Mark this as a path change. 1661 */ 1662 if (changed) { 1663 *changed = 1; 1664 } 1665 } 1666 1667 if (sp && (!io || sp->sp_io->id >= io->id)) 1668 io = sp->sp_io; 1669 1670 if (!io && !(type & NSC_NULL)) 1671 return (NULL); 1672 1673 if (!io) 1674 io = _nsc_null_io; 1675 1676 return (io); 1677 } 1678 1679 1680 /* 1681 * void 1682 * _nsc_release_io (nsc_io_t *) 1683 * Release I/O module. 1684 * 1685 * Description: 1686 * Releases reference to I/O structure and wakes up 1687 * anybody waiting on it. 1688 */ 1689 void 1690 _nsc_release_io(io) 1691 nsc_io_t *io; 1692 { 1693 mutex_enter(&_nsc_io_lock); 1694 1695 io->refcnt--; 1696 cv_broadcast(&io->cv); 1697 1698 mutex_exit(&_nsc_io_lock); 1699 } 1700 1701 1702 /* 1703 * static int 1704 * _nsc_alloc_fd (char *path, int type, int flag, nsc_fd_t **fdp) 1705 * Allocate file descriptor structure. 1706 * 1707 * Calling/Exit State: 1708 * Stores address of file descriptor through fdp and 1709 * returns 0 on success, otherwise returns error code. 1710 * 1711 * Description: 1712 * A new file descriptor is allocated and linked in to 1713 * the file descriptor chain which is protected by the 1714 * device lock. 1715 * 1716 * On return the file descriptor must contain all the 1717 * information necessary to perform an open. Details 1718 * specific to user callbacks are not required yet. 1719 */ 1720 static int 1721 _nsc_alloc_fd(path, type, flag, fdp) 1722 char *path; 1723 int type, flag; 1724 nsc_fd_t **fdp; 1725 { 1726 nsc_dev_t *dev; 1727 nsc_fd_t *fd; 1728 int rc; 1729 1730 if (!(fd = (nsc_fd_t *)nsc_kmem_zalloc( 1731 sizeof (*fd), KM_SLEEP, _nsc_local_mem))) 1732 return (ENOMEM); 1733 1734 if ((rc = _nsc_alloc_dev(path, &dev)) != 0) { 1735 nsc_kmem_free(fd, sizeof (*fd)); 1736 return (rc); 1737 } 1738 1739 mutex_enter(&dev->nsc_lock); 1740 1741 fd->sf_type = type; 1742 fd->sf_flag = flag; 1743 fd->sf_dev = dev; 1744 fd->sf_next = dev->nsc_close; 1745 dev->nsc_close = fd; 1746 1747 mutex_exit(&dev->nsc_lock); 1748 1749 *fdp = fd; 1750 return (0); 1751 } 1752 1753 1754 /* 1755 * static int 1756 * _nsc_free_fd (nsc_fd_t *) 1757 * Free file descriptor. 1758 * 1759 * Description: 1760 * The file descriptor is removed from the chain and free'd 1761 * once pending activity has completed. 1762 */ 1763 static void 1764 _nsc_free_fd(fd) 1765 nsc_fd_t *fd; 1766 { 1767 nsc_dev_t *dev = fd->sf_dev; 1768 nsc_fd_t **fdp; 1769 1770 if (!fd) 1771 return; 1772 1773 mutex_enter(&dev->nsc_lock); 1774 1775 for (fdp = &dev->nsc_close; *fdp; fdp = &(*fdp)->sf_next) 1776 if (*fdp == fd) { 1777 *fdp = fd->sf_next; 1778 break; 1779 } 1780 1781 if (dev->nsc_wait || dev->nsc_refcnt <= 0) 1782 cv_broadcast(&dev->nsc_cv); 1783 1784 while (fd->sf_pend) 1785 (void) _nsc_wait_dev(dev, 0); 1786 1787 mutex_exit(&dev->nsc_lock); 1788 1789 _nsc_free_dev(dev); 1790 1791 nsc_kmem_free(fd, sizeof (*fd)); 1792 } 1793 1794 1795 /* 1796 * static void 1797 * _nsc_relink_fd (nsc_fd_t *fd, nsc_fd_t **from, 1798 * nsc_fd_t **to, nsc_iodev_t *iodev) 1799 * Relink file descriptor. 1800 * 1801 * Description: 1802 * Remove the file descriptor from the 'from' chain and 1803 * add it to the 'to' chain. The busy flag in iodev is 1804 * used to prevent modifications to the chain whilst a 1805 * callback is in progress. 1806 */ 1807 static void 1808 _nsc_relink_fd(nsc_fd_t *fd, nsc_fd_t **from, nsc_fd_t **to, nsc_iodev_t *iodev) 1809 { 1810 nsc_dev_t *dev = fd->sf_dev; 1811 nsc_fd_t **fdp; 1812 1813 mutex_enter(&dev->nsc_lock); 1814 1815 while (iodev->si_busy) 1816 (void) _nsc_wait_dev(dev, 0); 1817 1818 for (fdp = from; *fdp; fdp = &(*fdp)->sf_next) 1819 if (*fdp == fd) { 1820 *fdp = fd->sf_next; 1821 break; 1822 } 1823 1824 fd->sf_next = (*to); 1825 (*to) = fd; 1826 1827 mutex_exit(&dev->nsc_lock); 1828 } 1829 1830 1831 /* 1832 * static int 1833 * _nsc_alloc_iodev (nsc_dev_t *dev, int type, nsc_iodev_t **iodevp) 1834 * Allocate I/O device structure. 1835 * 1836 * Calling/Exit State: 1837 * Stores address of I/O device structure through iodevp 1838 * and returns 0 on success, otherwise returns error code. 1839 * 1840 * Description: 1841 * If an entry for the I/O device already exists increment 1842 * the reference count and return the address, otherwise 1843 * allocate a new structure. 1844 * 1845 * A new structure is allocated before scanning the chain 1846 * to avoid calling the memory allocator with a spin lock 1847 * held. If an entry is found the new structure is free'd. 1848 * 1849 * The I/O device chain is protected by the device lock. 1850 */ 1851 static int 1852 _nsc_alloc_iodev(dev, type, iodevp) 1853 nsc_dev_t *dev; 1854 int type; 1855 nsc_iodev_t **iodevp; 1856 { 1857 nsc_iodev_t *iodev, *ip; 1858 nsc_io_t *io; 1859 1860 if (!(iodev = (nsc_iodev_t *)nsc_kmem_zalloc( 1861 sizeof (*iodev), KM_SLEEP, _nsc_local_mem))) 1862 return (ENOMEM); 1863 1864 mutex_init(&iodev->si_lock, NULL, MUTEX_DRIVER, NULL); 1865 cv_init(&iodev->si_cv, NULL, CV_DRIVER, NULL); 1866 1867 if (!(io = _nsc_reserve_io(dev->nsc_path, type))) { 1868 mutex_destroy(&iodev->si_lock); 1869 cv_destroy(&iodev->si_cv); 1870 nsc_kmem_free(iodev, sizeof (*iodev)); 1871 return (ENXIO); 1872 } 1873 1874 iodev->si_refcnt++; 1875 iodev->si_io = io; 1876 iodev->si_dev = dev; 1877 1878 mutex_enter(&_nsc_io_lock); 1879 dev->nsc_refcnt++; 1880 mutex_exit(&_nsc_io_lock); 1881 1882 mutex_enter(&dev->nsc_lock); 1883 1884 for (ip = dev->nsc_list; ip; ip = ip->si_next) 1885 if (ip->si_io == io) { 1886 ip->si_refcnt++; 1887 break; 1888 } 1889 1890 if (!ip) { 1891 iodev->si_next = dev->nsc_list; 1892 dev->nsc_list = iodev; 1893 } 1894 1895 mutex_exit(&dev->nsc_lock); 1896 1897 if (ip) { 1898 _nsc_free_iodev(iodev); 1899 iodev = ip; 1900 } 1901 1902 *iodevp = iodev; 1903 return (0); 1904 } 1905 1906 1907 /* 1908 * static int 1909 * _nsc_free_iodev (nsc_iodev_t *iodev) 1910 * Free I/O device structure. 1911 * 1912 * Description: 1913 * Decrements the reference count of a previously allocated 1914 * I/O device structure. If this is the last reference it 1915 * is removed from the device chain and free'd once pending 1916 * activity has completed. 1917 */ 1918 static void 1919 _nsc_free_iodev(nsc_iodev_t *iodev) 1920 { 1921 nsc_iodev_t **ipp; 1922 nsc_dev_t *dev; 1923 1924 if (!iodev) 1925 return; 1926 1927 dev = iodev->si_dev; 1928 1929 mutex_enter(&dev->nsc_lock); 1930 1931 if (--iodev->si_refcnt > 0) { 1932 mutex_exit(&dev->nsc_lock); 1933 return; 1934 } 1935 1936 for (ipp = &dev->nsc_list; *ipp; ipp = &(*ipp)->si_next) 1937 if (*ipp == iodev) { 1938 *ipp = iodev->si_next; 1939 break; 1940 } 1941 1942 if (dev->nsc_wait || dev->nsc_refcnt <= 0) 1943 cv_broadcast(&dev->nsc_cv); 1944 1945 while (iodev->si_pend || iodev->si_rpend || iodev->si_busy) 1946 (void) _nsc_wait_dev(dev, 0); 1947 1948 mutex_exit(&dev->nsc_lock); 1949 1950 _nsc_release_io(iodev->si_io); 1951 _nsc_free_dev(dev); 1952 1953 mutex_destroy(&iodev->si_lock); 1954 cv_destroy(&iodev->si_cv); 1955 1956 nsc_kmem_free(iodev, sizeof (*iodev)); 1957 } 1958 1959 1960 /* 1961 * static int 1962 * _nsc_alloc_dev (char *path, nsc_dev_t **devp) 1963 * Allocate device structure. 1964 * 1965 * Calling/Exit State: 1966 * Stores address of device structure through devp 1967 * and returns 0 on success, otherwise returns error 1968 * code. 1969 * 1970 * Description: 1971 * If an entry for the device already exists increment 1972 * the reference count and return the address, otherwise 1973 * allocate a new structure. 1974 * 1975 * A new structure is allocated before scanning the device 1976 * chain to avoid calling the memory allocator with a spin 1977 * lock held. If the device is found the new structure is 1978 * free'd. 1979 * 1980 * The device chain is protected by _nsc_io_lock. 1981 */ 1982 static int 1983 _nsc_alloc_dev(char *path, nsc_dev_t **devp) 1984 { 1985 nsc_dev_t *dev, *dp, **ddp; 1986 nsc_devval_t *dv; 1987 nsc_rval_t *rval; 1988 ncall_t *ncall; 1989 int rc; 1990 1991 if (!(dev = (nsc_dev_t *)nsc_kmem_zalloc( 1992 sizeof (*dev), KM_SLEEP, _nsc_local_mem))) 1993 return (ENOMEM); 1994 1995 dev->nsc_refcnt++; 1996 1997 mutex_init(&dev->nsc_lock, NULL, MUTEX_DRIVER, NULL); 1998 cv_init(&dev->nsc_cv, NULL, CV_DRIVER, NULL); 1999 2000 dev->nsc_phash = nsc_strhash(path); 2001 dev->nsc_path = nsc_strdup(path); 2002 2003 mutex_enter(&_nsc_io_lock); 2004 2005 dev->nsc_next = _nsc_dev_pend; 2006 _nsc_dev_pend = dev; 2007 2008 mutex_exit(&_nsc_io_lock); 2009 2010 mutex_enter(&_nsc_io_lock); 2011 2012 for (dp = _nsc_dev_top; dp; dp = dp->nsc_next) 2013 if (dp->nsc_phash == dev->nsc_phash && 2014 strcmp(dp->nsc_path, dev->nsc_path) == 0) { 2015 dp->nsc_refcnt++; 2016 break; 2017 } 2018 2019 if (!dp) { 2020 for (ddp = &_nsc_dev_pend; *ddp; ddp = &(*ddp)->nsc_next) 2021 if (*ddp == dev) { 2022 *ddp = dev->nsc_next; 2023 break; 2024 } 2025 2026 dev->nsc_next = _nsc_dev_top; 2027 _nsc_dev_top = dev; 2028 } 2029 2030 mutex_exit(&_nsc_io_lock); 2031 2032 if (dp) { 2033 _nsc_free_dev(dev); 2034 dev = dp; 2035 } 2036 2037 /* 2038 * Try and find the device/values header for this device 2039 * and link it back to the device structure. 2040 */ 2041 2042 mutex_enter(&_nsc_devval_lock); 2043 2044 if (dev->nsc_values == NULL) { 2045 for (dv = _nsc_devval_top; dv; dv = dv->dv_next) { 2046 if (dv->dv_phash == dev->nsc_phash && 2047 strcmp(dv->dv_path, dev->nsc_path) == 0) { 2048 dev->nsc_values = dv; 2049 break; 2050 } 2051 } 2052 } 2053 2054 mutex_exit(&_nsc_devval_lock); 2055 2056 /* 2057 * Refresh the device/values from the other node 2058 */ 2059 2060 rval = nsc_kmem_zalloc(sizeof (*rval), KM_SLEEP, _nsc_local_mem); 2061 if (rval == NULL) { 2062 goto out; 2063 } 2064 2065 rc = ncall_alloc(ncall_mirror(ncall_self()), 0, 0, &ncall); 2066 if (rc == 0) { 2067 (void) strncpy(rval->path, path, sizeof (rval->path)); 2068 2069 rc = ncall_put_data(ncall, rval, sizeof (*rval)); 2070 if (rc == 0) { 2071 /* 2072 * Send synchronously and read a reply 2073 * so that we know that the updates 2074 * have completed before this 2075 * function returns. 2076 */ 2077 if (ncall_send(ncall, 0, NSC_SETVAL_ALL) == 0) 2078 (void) ncall_read_reply(ncall, 1, &rc); 2079 } 2080 2081 ncall_free(ncall); 2082 } 2083 2084 nsc_kmem_free(rval, sizeof (*rval)); 2085 2086 out: 2087 *devp = dev; 2088 return (0); 2089 } 2090 2091 2092 /* 2093 * static void 2094 * _nsc_free_dev (nsc_dev_t *dev) 2095 * Free device structure. 2096 * 2097 * Description: 2098 * Decrements the reference count of a previously allocated 2099 * device structure. If this is the last reference it is 2100 * removed from the device chain and free'd once pending 2101 * activity has completed. 2102 * 2103 * Whilst waiting for pending activity to cease the device is 2104 * relinked onto the pending chain. 2105 */ 2106 static void 2107 _nsc_free_dev(dev) 2108 nsc_dev_t *dev; 2109 { 2110 nsc_dev_t **ddp; 2111 2112 if (!dev) 2113 return; 2114 2115 mutex_enter(&_nsc_io_lock); 2116 2117 if (--dev->nsc_refcnt > 0) { 2118 mutex_exit(&_nsc_io_lock); 2119 return; 2120 } 2121 2122 for (ddp = &_nsc_dev_top; *ddp; ddp = &(*ddp)->nsc_next) 2123 if (*ddp == dev) { 2124 *ddp = dev->nsc_next; 2125 dev->nsc_next = _nsc_dev_pend; 2126 _nsc_dev_pend = dev; 2127 break; 2128 } 2129 2130 mutex_exit(&_nsc_io_lock); 2131 2132 mutex_enter(&dev->nsc_lock); 2133 2134 while (dev->nsc_pend || dev->nsc_rpend || dev->nsc_wait) { 2135 cv_wait(&dev->nsc_cv, &dev->nsc_lock); 2136 } 2137 2138 mutex_exit(&dev->nsc_lock); 2139 2140 mutex_enter(&_nsc_io_lock); 2141 2142 for (ddp = &_nsc_dev_pend; *ddp; ddp = &(*ddp)->nsc_next) 2143 if (*ddp == dev) { 2144 *ddp = dev->nsc_next; 2145 break; 2146 } 2147 2148 mutex_exit(&_nsc_io_lock); 2149 2150 mutex_destroy(&dev->nsc_lock); 2151 cv_destroy(&dev->nsc_cv); 2152 nsc_strfree(dev->nsc_path); 2153 2154 nsc_kmem_free(dev, sizeof (*dev)); 2155 } 2156 2157 2158 /* 2159 * static nsc_io_t * 2160 * _nsc_alloc_io (int id, char *name, int flag) 2161 * Allocate an I/O structure. 2162 * 2163 * Calling/Exit State: 2164 * Returns the address of the I/O structure, or NULL. 2165 */ 2166 static nsc_io_t * 2167 _nsc_alloc_io(id, name, flag) 2168 int id; 2169 char *name; 2170 int flag; 2171 { 2172 nsc_io_t *io; 2173 2174 if (!(io = (nsc_io_t *)nsc_kmem_zalloc( 2175 sizeof (*io), KM_NOSLEEP, _nsc_local_mem))) 2176 return (NULL); 2177 2178 cv_init(&io->cv, NULL, CV_DRIVER, NULL); 2179 2180 io->id = id; 2181 io->name = name; 2182 io->flag = flag; 2183 2184 return (io); 2185 } 2186 2187 2188 /* 2189 * static void 2190 * _nsc_free_io (int id, char *name, int flag) 2191 * Free an I/O structure. 2192 * 2193 * Calling/Exit State: 2194 * Free the I/O structure and remove it from the chain. 2195 */ 2196 static void 2197 _nsc_free_io(io) 2198 nsc_io_t *io; 2199 { 2200 nsc_io_t **iop; 2201 2202 mutex_enter(&_nsc_io_lock); 2203 2204 for (iop = &_nsc_io_top; *iop; iop = &(*iop)->next) 2205 if (*iop == io) 2206 break; 2207 2208 if (*iop) 2209 (*iop) = io->next; 2210 2211 mutex_exit(&_nsc_io_lock); 2212 2213 cv_destroy(&io->cv); 2214 nsc_kmem_free(io, sizeof (*io)); 2215 }