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
table_lock_enter(vnode_t * vp,struct loinfo * li)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
lofs_subrinit(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
lofs_subrfini(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
lsetup(struct loinfo * li,uint_t htsize)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
ldestroy(struct loinfo * li)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 *
makelonode(struct vnode * vp,struct loinfo * li,int flag)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 *
makelfsnode(struct vfs * vfsp,struct loinfo * li)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
freelfsnode(struct lfsnode * lfs,struct loinfo * li)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 *
lfsfind(struct vfs * vfsp,struct loinfo * li)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 *
lo_realvfs(struct vfs * vfsp,struct vnode ** realrootvpp)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
lretire(struct loinfo * li,struct lobucket * table,uint_t size)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
lgrow(struct loinfo * li,uint_t newsize)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
lsave(lnode_t * lp,struct loinfo * li)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
lfs_rele(struct lfsnode * lfs,struct loinfo * li)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
freelonode(lnode_t * lp)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 *
lfind(struct vnode * vp,struct loinfo * li)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*/
lo_dprint(int level,char * str,int a1,int a2,int a3,int a4,int a5,int a6,int a7,int a8,int a9)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