xref: /titanic_52/usr/src/uts/common/fs/lofs/lofs_subr.c (revision 1a5e258f5471356ca102c7176637cdce45bac147)
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