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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* 26 * Copyright (c) 2017 by Delphix. All rights reserved. 27 */ 28 29 /* 30 * The idea behind composition-based stacked filesystems is to add a 31 * vnode to the stack of vnodes for each mount. These vnodes have their 32 * own set of mount options and filesystem-specific functions, so they 33 * can modify data or operations before they are passed along. Such a 34 * filesystem must maintain a mapping from the underlying vnodes to its 35 * interposing vnodes. 36 * 37 * In lofs, this mapping is implemented by a hashtable. Each bucket 38 * contains a count of the number of nodes currently contained, the 39 * chain of vnodes, and a lock to protect the list of vnodes. The 40 * hashtable dynamically grows if the number of vnodes in the table as a 41 * whole exceeds the size of the table left-shifted by 42 * lo_resize_threshold. In order to minimize lock contention, there is 43 * no global lock protecting the hashtable, hence obtaining the 44 * per-bucket locks consists of a dance to make sure we've actually 45 * locked the correct bucket. Acquiring a bucket lock doesn't involve 46 * locking the hashtable itself, so we refrain from freeing old 47 * hashtables, and store them in a linked list of retired hashtables; 48 * the list is freed when the filesystem is unmounted. 49 */ 50 51 #include <sys/param.h> 52 #include <sys/kmem.h> 53 #include <sys/vfs.h> 54 #include <sys/vnode.h> 55 #include <sys/cmn_err.h> 56 #include <sys/systm.h> 57 #include <sys/t_lock.h> 58 #include <sys/debug.h> 59 #include <sys/atomic.h> 60 61 #include <sys/fs/lofs_node.h> 62 #include <sys/fs/lofs_info.h> 63 /* 64 * Due to the hashing algorithm, the size of the hash table needs to be a 65 * power of 2. 66 */ 67 #define LOFS_DEFAULT_HTSIZE (1 << 6) 68 69 #define ltablehash(vp, tblsz) ((((intptr_t)(vp))>>10) & ((tblsz)-1)) 70 71 /* 72 * The following macros can only be safely used when the desired bucket 73 * is already locked. 74 */ 75 /* 76 * The lock in the hashtable associated with the given vnode. 77 */ 78 #define TABLE_LOCK(vp, li) \ 79 (&(li)->li_hashtable[ltablehash((vp), (li)->li_htsize)].lh_lock) 80 81 /* 82 * The bucket in the hashtable that the given vnode hashes to. 83 */ 84 #define TABLE_BUCKET(vp, li) \ 85 ((li)->li_hashtable[ltablehash((vp), (li)->li_htsize)].lh_chain) 86 87 /* 88 * Number of elements currently in the bucket that the vnode hashes to. 89 */ 90 #define TABLE_COUNT(vp, li) \ 91 ((li)->li_hashtable[ltablehash((vp), (li)->li_htsize)].lh_count) 92 93 /* 94 * Grab/Drop the lock for the bucket this vnode hashes to. 95 */ 96 #define TABLE_LOCK_ENTER(vp, li) table_lock_enter(vp, li) 97 #define TABLE_LOCK_EXIT(vp, li) \ 98 mutex_exit(&(li)->li_hashtable[ltablehash((vp), \ 99 (li)->li_htsize)].lh_lock) 100 101 static lnode_t *lfind(struct vnode *, struct loinfo *); 102 static void lsave(lnode_t *, struct loinfo *); 103 static struct vfs *makelfsnode(struct vfs *, struct loinfo *); 104 static struct lfsnode *lfsfind(struct vfs *, struct loinfo *); 105 106 uint_t lo_resize_threshold = 1; 107 uint_t lo_resize_factor = 2; 108 109 static kmem_cache_t *lnode_cache; 110 111 /* 112 * Since the hashtable itself isn't protected by a lock, obtaining a 113 * per-bucket lock proceeds as follows: 114 * 115 * (a) li->li_htlock protects li->li_hashtable, li->li_htsize, and 116 * li->li_retired. 117 * 118 * (b) Per-bucket locks (lh_lock) protect the contents of the bucket. 119 * 120 * (c) Locking order for resizing the hashtable is li_htlock then 121 * lh_lock. 122 * 123 * To grab the bucket lock we: 124 * 125 * (1) Stash away the htsize and the pointer to the hashtable to make 126 * sure neither change while we're using them. 127 * 128 * (2) lgrow() updates the pointer to the hashtable before it updates 129 * the size: the worst case scenario is that we have the wrong size (but 130 * the correct table), so we hash to the wrong bucket, grab the wrong 131 * lock, and then realize that things have changed, rewind and start 132 * again. If both the size and the table changed since we loaded them, 133 * we'll realize that too and restart. 134 * 135 * (3) The protocol for growing the hashtable involves holding *all* the 136 * locks in the table, hence the unlocking code (TABLE_LOCK_EXIT()) 137 * doesn't need to do any dances, since neither the table nor the size 138 * can change while any bucket lock is held. 139 * 140 * (4) If the hashtable is growing (by thread t1) while another thread 141 * (t2) is trying to grab a bucket lock, t2 might have a stale reference 142 * to li->li_htsize: 143 * 144 * - t1 grabs all locks in lgrow() 145 * - t2 loads li->li_htsize and li->li_hashtable 146 * - t1 changes li->hashtable 147 * - t2 loads from an offset in the "stale" hashtable and tries to grab 148 * the relevant mutex. 149 * 150 * If t1 had free'd the stale hashtable, t2 would be in trouble. Hence, 151 * stale hashtables are not freed but stored in a list of "retired" 152 * hashtables, which is emptied when the filesystem is unmounted. 153 */ 154 static void 155 table_lock_enter(vnode_t *vp, struct loinfo *li) 156 { 157 struct lobucket *chain; 158 uint_t htsize; 159 uint_t hash; 160 161 for (;;) { 162 htsize = li->li_htsize; 163 membar_consumer(); 164 chain = (struct lobucket *)li->li_hashtable; 165 hash = ltablehash(vp, htsize); 166 mutex_enter(&chain[hash].lh_lock); 167 if (li->li_hashtable == chain && li->li_htsize == htsize) 168 break; 169 mutex_exit(&chain[hash].lh_lock); 170 } 171 } 172 173 void 174 lofs_subrinit(void) 175 { 176 /* 177 * Initialize the cache. 178 */ 179 lnode_cache = kmem_cache_create("lnode_cache", sizeof (lnode_t), 180 0, NULL, NULL, NULL, NULL, NULL, 0); 181 } 182 183 void 184 lofs_subrfini(void) 185 { 186 kmem_cache_destroy(lnode_cache); 187 } 188 189 /* 190 * Initialize a (struct loinfo), and initialize the hashtable to have 191 * htsize buckets. 192 */ 193 void 194 lsetup(struct loinfo *li, uint_t htsize) 195 { 196 li->li_refct = 0; 197 li->li_lfs = NULL; 198 if (htsize == 0) 199 htsize = LOFS_DEFAULT_HTSIZE; 200 li->li_htsize = htsize; 201 li->li_hashtable = kmem_zalloc(htsize * sizeof (*li->li_hashtable), 202 KM_SLEEP); 203 mutex_init(&li->li_lfslock, NULL, MUTEX_DEFAULT, NULL); 204 mutex_init(&li->li_htlock, NULL, MUTEX_DEFAULT, NULL); 205 li->li_retired = NULL; 206 } 207 208 /* 209 * Destroy a (struct loinfo) 210 */ 211 void 212 ldestroy(struct loinfo *li) 213 { 214 uint_t i, htsize; 215 struct lobucket *table; 216 struct lo_retired_ht *lrhp, *trhp; 217 218 mutex_destroy(&li->li_htlock); 219 mutex_destroy(&li->li_lfslock); 220 htsize = li->li_htsize; 221 table = li->li_hashtable; 222 for (i = 0; i < htsize; i++) 223 mutex_destroy(&table[i].lh_lock); 224 kmem_free(table, htsize * sizeof (*li->li_hashtable)); 225 226 /* 227 * Free the retired hashtables. 228 */ 229 lrhp = li->li_retired; 230 while (lrhp != NULL) { 231 trhp = lrhp; 232 lrhp = lrhp->lrh_next; 233 kmem_free(trhp->lrh_table, 234 trhp->lrh_size * sizeof (*li->li_hashtable)); 235 kmem_free(trhp, sizeof (*trhp)); 236 } 237 li->li_retired = NULL; 238 } 239 240 /* 241 * Return a looped back vnode for the given vnode. 242 * If no lnode exists for this vnode create one and put it 243 * in a table hashed by vnode. If the lnode for 244 * this vnode is already in the table return it (ref count is 245 * incremented by lfind). The lnode will be flushed from the 246 * table when lo_inactive calls freelonode. The creation of 247 * a new lnode can be forced via the LOF_FORCE flag even if 248 * the vnode exists in the table. This is used in the creation 249 * of a terminating lnode when looping is detected. A unique 250 * lnode is required for the correct evaluation of the current 251 * working directory. 252 * NOTE: vp is assumed to be a held vnode. 253 */ 254 struct vnode * 255 makelonode(struct vnode *vp, struct loinfo *li, int flag) 256 { 257 lnode_t *lp, *tlp; 258 struct vfs *vfsp; 259 vnode_t *nvp; 260 261 lp = NULL; 262 TABLE_LOCK_ENTER(vp, li); 263 if (flag != LOF_FORCE) 264 lp = lfind(vp, li); 265 if ((flag == LOF_FORCE) || (lp == NULL)) { 266 /* 267 * Optimistically assume that we won't need to sleep. 268 */ 269 lp = kmem_cache_alloc(lnode_cache, KM_NOSLEEP); 270 nvp = vn_alloc(KM_NOSLEEP); 271 if (lp == NULL || nvp == NULL) { 272 TABLE_LOCK_EXIT(vp, li); 273 /* The lnode allocation may have succeeded, save it */ 274 tlp = lp; 275 if (tlp == NULL) { 276 tlp = kmem_cache_alloc(lnode_cache, KM_SLEEP); 277 } 278 if (nvp == NULL) { 279 nvp = vn_alloc(KM_SLEEP); 280 } 281 lp = NULL; 282 TABLE_LOCK_ENTER(vp, li); 283 if (flag != LOF_FORCE) 284 lp = lfind(vp, li); 285 if (lp != NULL) { 286 kmem_cache_free(lnode_cache, tlp); 287 vn_free(nvp); 288 VN_RELE(vp); 289 goto found_lnode; 290 } 291 lp = tlp; 292 } 293 atomic_inc_32(&li->li_refct); 294 vfsp = makelfsnode(vp->v_vfsp, li); 295 lp->lo_vnode = nvp; 296 VN_SET_VFS_TYPE_DEV(nvp, vfsp, vp->v_type, vp->v_rdev); 297 nvp->v_flag |= (vp->v_flag & (VNOMOUNT|VNOMAP|VDIROPEN)); 298 vn_setops(nvp, lo_vnodeops); 299 nvp->v_data = (caddr_t)lp; 300 lp->lo_vp = vp; 301 lp->lo_looping = 0; 302 lsave(lp, li); 303 vn_exists(vp); 304 } else { 305 VN_RELE(vp); 306 } 307 308 found_lnode: 309 TABLE_LOCK_EXIT(vp, li); 310 return (ltov(lp)); 311 } 312 313 /* 314 * Get/Make vfs structure for given real vfs 315 */ 316 static struct vfs * 317 makelfsnode(struct vfs *vfsp, struct loinfo *li) 318 { 319 struct lfsnode *lfs; 320 struct lfsnode *tlfs; 321 322 /* 323 * Don't grab any locks for the fast (common) case. 324 */ 325 if (vfsp == li->li_realvfs) 326 return (li->li_mountvfs); 327 ASSERT(li->li_refct > 0); 328 mutex_enter(&li->li_lfslock); 329 if ((lfs = lfsfind(vfsp, li)) == NULL) { 330 mutex_exit(&li->li_lfslock); 331 lfs = kmem_zalloc(sizeof (*lfs), KM_SLEEP); 332 mutex_enter(&li->li_lfslock); 333 if ((tlfs = lfsfind(vfsp, li)) != NULL) { 334 kmem_free(lfs, sizeof (*lfs)); 335 lfs = tlfs; 336 goto found_lfs; 337 } 338 lfs->lfs_realvfs = vfsp; 339 340 /* 341 * Even though the lfsnode is strictly speaking a private 342 * implementation detail of lofs, it should behave as a regular 343 * vfs_t for the benefit of the rest of the kernel. 344 */ 345 VFS_INIT(&lfs->lfs_vfs, lo_vfsops, (caddr_t)li); 346 lfs->lfs_vfs.vfs_fstype = li->li_mountvfs->vfs_fstype; 347 lfs->lfs_vfs.vfs_flag = 348 ((vfsp->vfs_flag | li->li_mflag) & ~li->li_dflag) & 349 INHERIT_VFS_FLAG; 350 lfs->lfs_vfs.vfs_bsize = vfsp->vfs_bsize; 351 lfs->lfs_vfs.vfs_dev = vfsp->vfs_dev; 352 lfs->lfs_vfs.vfs_fsid = vfsp->vfs_fsid; 353 354 if (vfsp->vfs_mntpt != NULL) { 355 lfs->lfs_vfs.vfs_mntpt = vfs_getmntpoint(vfsp); 356 /* Leave a reference to the mountpoint */ 357 } 358 359 (void) VFS_ROOT(vfsp, &lfs->lfs_realrootvp); 360 361 /* 362 * We use 1 instead of 0 as the value to associate with 363 * an idle lfs_vfs. This is to prevent VFS_RELE() 364 * trying to kmem_free() our lfs_t (which is the wrong 365 * size). 366 */ 367 VFS_HOLD(&lfs->lfs_vfs); 368 lfs->lfs_next = li->li_lfs; 369 li->li_lfs = lfs; 370 vfs_propagate_features(vfsp, &lfs->lfs_vfs); 371 } 372 373 found_lfs: 374 VFS_HOLD(&lfs->lfs_vfs); 375 mutex_exit(&li->li_lfslock); 376 return (&lfs->lfs_vfs); 377 } 378 379 /* 380 * Free lfs node since no longer in use 381 */ 382 static void 383 freelfsnode(struct lfsnode *lfs, struct loinfo *li) 384 { 385 struct lfsnode *prev = NULL; 386 struct lfsnode *this; 387 388 ASSERT(MUTEX_HELD(&li->li_lfslock)); 389 ASSERT(li->li_refct > 0); 390 for (this = li->li_lfs; this != NULL; this = this->lfs_next) { 391 if (this == lfs) { 392 ASSERT(lfs->lfs_vfs.vfs_count == 1); 393 if (prev == NULL) 394 li->li_lfs = lfs->lfs_next; 395 else 396 prev->lfs_next = lfs->lfs_next; 397 if (lfs->lfs_realrootvp != NULL) { 398 VN_RELE(lfs->lfs_realrootvp); 399 } 400 if (lfs->lfs_vfs.vfs_mntpt != NULL) 401 refstr_rele(lfs->lfs_vfs.vfs_mntpt); 402 if (lfs->lfs_vfs.vfs_implp != NULL) { 403 ASSERT(lfs->lfs_vfs.vfs_femhead == NULL); 404 ASSERT(lfs->lfs_vfs.vfs_vskap == NULL); 405 ASSERT(lfs->lfs_vfs.vfs_fstypevsp == NULL); 406 kmem_free(lfs->lfs_vfs.vfs_implp, 407 sizeof (vfs_impl_t)); 408 } 409 sema_destroy(&lfs->lfs_vfs.vfs_reflock); 410 kmem_free(lfs, sizeof (struct lfsnode)); 411 return; 412 } 413 prev = this; 414 } 415 panic("freelfsnode"); 416 /*NOTREACHED*/ 417 } 418 419 /* 420 * Find lfs given real vfs and mount instance(li) 421 */ 422 static struct lfsnode * 423 lfsfind(struct vfs *vfsp, struct loinfo *li) 424 { 425 struct lfsnode *lfs; 426 427 ASSERT(MUTEX_HELD(&li->li_lfslock)); 428 429 /* 430 * We need to handle the case where a UFS filesystem was forced 431 * unmounted and then a subsequent mount got the same vfs 432 * structure. If the new mount lies in the lofs hierarchy, then 433 * this will confuse lofs, because the original vfsp (of the 434 * forced unmounted filesystem) is still around. We check for 435 * this condition here. 436 * 437 * If we find a cache vfsp hit, then we check to see if the 438 * cached filesystem was forced unmounted. Skip all such 439 * entries. This should be safe to do since no 440 * makelonode()->makelfsnode()->lfsfind() calls should be 441 * generated for such force-unmounted filesystems (because (ufs) 442 * lookup would've returned an error). 443 */ 444 for (lfs = li->li_lfs; lfs != NULL; lfs = lfs->lfs_next) { 445 if (lfs->lfs_realvfs == vfsp) { 446 struct vnode *realvp; 447 448 realvp = lfs->lfs_realrootvp; 449 if (realvp == NULL) 450 continue; 451 if (realvp->v_vfsp == NULL || realvp->v_type == VBAD) 452 continue; 453 return (lfs); 454 } 455 } 456 return (NULL); 457 } 458 459 /* 460 * Find real vfs given loopback vfs 461 */ 462 struct vfs * 463 lo_realvfs(struct vfs *vfsp, struct vnode **realrootvpp) 464 { 465 struct loinfo *li = vtoli(vfsp); 466 struct lfsnode *lfs; 467 468 ASSERT(li->li_refct > 0); 469 if (vfsp == li->li_mountvfs) { 470 if (realrootvpp != NULL) 471 *realrootvpp = vtol(li->li_rootvp)->lo_vp; 472 return (li->li_realvfs); 473 } 474 mutex_enter(&li->li_lfslock); 475 for (lfs = li->li_lfs; lfs != NULL; lfs = lfs->lfs_next) { 476 if (vfsp == &lfs->lfs_vfs) { 477 if (realrootvpp != NULL) 478 *realrootvpp = lfs->lfs_realrootvp; 479 mutex_exit(&li->li_lfslock); 480 return (lfs->lfs_realvfs); 481 } 482 } 483 panic("lo_realvfs"); 484 /*NOTREACHED*/ 485 } 486 487 /* 488 * Lnode lookup stuff. 489 * These routines maintain a table of lnodes hashed by vp so 490 * that the lnode for a vp can be found if it already exists. 491 * 492 * NB: A lofs shadow vnode causes exactly one VN_HOLD() on the 493 * underlying vnode. 494 */ 495 496 /* 497 * Retire old hashtables. 498 */ 499 static void 500 lretire(struct loinfo *li, struct lobucket *table, uint_t size) 501 { 502 struct lo_retired_ht *lrhp; 503 504 lrhp = kmem_alloc(sizeof (*lrhp), KM_SLEEP); 505 lrhp->lrh_table = table; 506 lrhp->lrh_size = size; 507 508 mutex_enter(&li->li_htlock); 509 lrhp->lrh_next = li->li_retired; 510 li->li_retired = lrhp; 511 mutex_exit(&li->li_htlock); 512 } 513 514 /* 515 * Grow the hashtable. 516 */ 517 static void 518 lgrow(struct loinfo *li, uint_t newsize) 519 { 520 uint_t oldsize; 521 uint_t i; 522 struct lobucket *oldtable, *newtable; 523 524 /* 525 * It's OK to not have enough memory to resize the hashtable. 526 * We'll go down this path the next time we add something to the 527 * table, and retry the allocation then. 528 */ 529 if ((newtable = kmem_zalloc(newsize * sizeof (*li->li_hashtable), 530 KM_NOSLEEP)) == NULL) 531 return; 532 533 mutex_enter(&li->li_htlock); 534 if (newsize <= li->li_htsize) { 535 mutex_exit(&li->li_htlock); 536 kmem_free(newtable, newsize * sizeof (*li->li_hashtable)); 537 return; 538 } 539 oldsize = li->li_htsize; 540 oldtable = li->li_hashtable; 541 542 /* 543 * Grab all locks so TABLE_LOCK_ENTER() calls block until the 544 * resize is complete. 545 */ 546 for (i = 0; i < oldsize; i++) 547 mutex_enter(&oldtable[i].lh_lock); 548 /* 549 * li->li_hashtable gets set before li->li_htsize, so in the 550 * time between the two assignments, callers of 551 * TABLE_LOCK_ENTER() cannot hash to a bucket beyond oldsize, 552 * hence we only need to grab the locks up to oldsize. 553 */ 554 for (i = 0; i < oldsize; i++) 555 mutex_enter(&newtable[i].lh_lock); 556 /* 557 * Rehash. 558 */ 559 for (i = 0; i < oldsize; i++) { 560 lnode_t *tlp, *nlp; 561 562 for (tlp = oldtable[i].lh_chain; tlp != NULL; tlp = nlp) { 563 uint_t hash = ltablehash(tlp->lo_vp, newsize); 564 565 nlp = tlp->lo_next; 566 tlp->lo_next = newtable[hash].lh_chain; 567 newtable[hash].lh_chain = tlp; 568 newtable[hash].lh_count++; 569 } 570 } 571 572 /* 573 * As soon as we store the new hashtable, future locking operations 574 * will use it. Therefore, we must ensure that all the state we've 575 * just established reaches global visibility before the new hashtable 576 * does. 577 */ 578 membar_producer(); 579 li->li_hashtable = newtable; 580 581 /* 582 * table_lock_enter() relies on the fact that li->li_hashtable 583 * is set to its new value before li->li_htsize. 584 */ 585 membar_producer(); 586 li->li_htsize = newsize; 587 588 /* 589 * The new state is consistent now, so we can drop all the locks. 590 */ 591 for (i = 0; i < oldsize; i++) { 592 mutex_exit(&newtable[i].lh_lock); 593 mutex_exit(&oldtable[i].lh_lock); 594 } 595 mutex_exit(&li->li_htlock); 596 597 lretire(li, oldtable, oldsize); 598 } 599 600 /* 601 * Put a lnode in the table 602 */ 603 static void 604 lsave(lnode_t *lp, struct loinfo *li) 605 { 606 ASSERT(lp->lo_vp); 607 ASSERT(MUTEX_HELD(TABLE_LOCK(lp->lo_vp, li))); 608 609 #ifdef LODEBUG 610 lo_dprint(4, "lsave lp %p hash %d\n", 611 lp, ltablehash(lp->lo_vp, li)); 612 #endif 613 614 TABLE_COUNT(lp->lo_vp, li)++; 615 lp->lo_next = TABLE_BUCKET(lp->lo_vp, li); 616 TABLE_BUCKET(lp->lo_vp, li) = lp; 617 618 if (li->li_refct > (li->li_htsize << lo_resize_threshold)) { 619 TABLE_LOCK_EXIT(lp->lo_vp, li); 620 lgrow(li, li->li_htsize << lo_resize_factor); 621 TABLE_LOCK_ENTER(lp->lo_vp, li); 622 } 623 } 624 625 /* 626 * Our version of vfs_rele() that stops at 1 instead of 0, and calls 627 * freelfsnode() instead of kmem_free(). 628 */ 629 static void 630 lfs_rele(struct lfsnode *lfs, struct loinfo *li) 631 { 632 vfs_t *vfsp = &lfs->lfs_vfs; 633 634 ASSERT(MUTEX_HELD(&li->li_lfslock)); 635 ASSERT(vfsp->vfs_count > 1); 636 if (atomic_dec_32_nv(&vfsp->vfs_count) == 1) 637 freelfsnode(lfs, li); 638 } 639 640 /* 641 * Remove a lnode from the table 642 */ 643 void 644 freelonode(lnode_t *lp) 645 { 646 lnode_t *lt; 647 lnode_t *ltprev = NULL; 648 struct lfsnode *lfs, *nextlfs; 649 struct vfs *vfsp; 650 struct vnode *vp = ltov(lp); 651 struct vnode *realvp = realvp(vp); 652 struct loinfo *li = vtoli(vp->v_vfsp); 653 654 #ifdef LODEBUG 655 lo_dprint(4, "freelonode lp %p hash %d\n", 656 lp, ltablehash(lp->lo_vp, li)); 657 #endif 658 TABLE_LOCK_ENTER(lp->lo_vp, li); 659 660 mutex_enter(&vp->v_lock); 661 if (vp->v_count > 1) { 662 VN_RELE_LOCKED(vp); 663 mutex_exit(&vp->v_lock); 664 TABLE_LOCK_EXIT(lp->lo_vp, li); 665 return; 666 } 667 mutex_exit(&vp->v_lock); 668 669 for (lt = TABLE_BUCKET(lp->lo_vp, li); lt != NULL; 670 ltprev = lt, lt = lt->lo_next) { 671 if (lt == lp) { 672 #ifdef LODEBUG 673 lo_dprint(4, "freeing %p, vfsp %p\n", 674 vp, vp->v_vfsp); 675 #endif 676 atomic_dec_32(&li->li_refct); 677 vfsp = vp->v_vfsp; 678 vn_invalid(vp); 679 if (vfsp != li->li_mountvfs) { 680 mutex_enter(&li->li_lfslock); 681 /* 682 * Check for unused lfs 683 */ 684 lfs = li->li_lfs; 685 while (lfs != NULL) { 686 nextlfs = lfs->lfs_next; 687 if (vfsp == &lfs->lfs_vfs) { 688 lfs_rele(lfs, li); 689 break; 690 } 691 if (lfs->lfs_vfs.vfs_count == 1) { 692 /* 693 * Lfs is idle 694 */ 695 freelfsnode(lfs, li); 696 } 697 lfs = nextlfs; 698 } 699 mutex_exit(&li->li_lfslock); 700 } 701 if (ltprev == NULL) { 702 TABLE_BUCKET(lt->lo_vp, li) = lt->lo_next; 703 } else { 704 ltprev->lo_next = lt->lo_next; 705 } 706 TABLE_COUNT(lt->lo_vp, li)--; 707 TABLE_LOCK_EXIT(lt->lo_vp, li); 708 kmem_cache_free(lnode_cache, lt); 709 vn_free(vp); 710 VN_RELE(realvp); 711 return; 712 } 713 } 714 panic("freelonode"); 715 /*NOTREACHED*/ 716 } 717 718 /* 719 * Lookup a lnode by vp 720 */ 721 static lnode_t * 722 lfind(struct vnode *vp, struct loinfo *li) 723 { 724 lnode_t *lt; 725 726 ASSERT(MUTEX_HELD(TABLE_LOCK(vp, li))); 727 728 lt = TABLE_BUCKET(vp, li); 729 while (lt != NULL) { 730 if (lt->lo_vp == vp) { 731 VN_HOLD(ltov(lt)); 732 return (lt); 733 } 734 lt = lt->lo_next; 735 } 736 return (NULL); 737 } 738 739 #ifdef LODEBUG 740 static int lofsdebug; 741 #endif /* LODEBUG */ 742 743 /* 744 * Utilities used by both client and server 745 * Standard levels: 746 * 0) no debugging 747 * 1) hard failures 748 * 2) soft failures 749 * 3) current test software 750 * 4) main procedure entry points 751 * 5) main procedure exit points 752 * 6) utility procedure entry points 753 * 7) utility procedure exit points 754 * 8) obscure procedure entry points 755 * 9) obscure procedure exit points 756 * 10) random stuff 757 * 11) all <= 1 758 * 12) all <= 2 759 * 13) all <= 3 760 * ... 761 */ 762 763 #ifdef LODEBUG 764 /*VARARGS2*/ 765 lo_dprint(int level, char *str, int a1, int a2, int a3, int a4, int a5, int a6, 766 int a7, int a8, int a9) 767 { 768 769 if (lofsdebug == level || (lofsdebug > 10 && (lofsdebug - 10) >= level)) 770 printf(str, a1, a2, a3, a4, a5, a6, a7, a8, a9); 771 } 772 #endif 773