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