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