1 /* $NetBSD: vfs_cache.c,v 1.66 2006/10/25 18:56:38 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1989, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * @(#)vfs_cache.c 8.3 (Berkeley) 8/22/94 32 */ 33 34 #include <sys/cdefs.h> 35 __KERNEL_RCSID(0, "$NetBSD: vfs_cache.c,v 1.66 2006/10/25 18:56:38 christos Exp $"); 36 37 #include "opt_ddb.h" 38 #include "opt_revcache.h" 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/time.h> 43 #include <sys/mount.h> 44 #include <sys/vnode.h> 45 #include <sys/namei.h> 46 #include <sys/errno.h> 47 #include <sys/malloc.h> 48 #include <sys/pool.h> 49 #include <sys/lock.h> 50 51 #define NAMECACHE_ENTER_REVERSE 52 /* 53 * Name caching works as follows: 54 * 55 * Names found by directory scans are retained in a cache 56 * for future reference. It is managed LRU, so frequently 57 * used names will hang around. Cache is indexed by hash value 58 * obtained from (dvp, name) where dvp refers to the directory 59 * containing name. 60 * 61 * For simplicity (and economy of storage), names longer than 62 * a maximum length of NCHNAMLEN are not cached; they occur 63 * infrequently in any case, and are almost never of interest. 64 * 65 * Upon reaching the last segment of a path, if the reference 66 * is for DELETE, or NOCACHE is set (rewrite), and the 67 * name is located in the cache, it will be dropped. 68 * The entry is dropped also when it was not possible to lock 69 * the cached vnode, either because vget() failed or the generation 70 * number has changed while waiting for the lock. 71 */ 72 73 /* 74 * Structures associated with name cacheing. 75 */ 76 LIST_HEAD(nchashhead, namecache) *nchashtbl; 77 u_long nchash; /* size of hash table - 1 */ 78 long numcache; /* number of cache entries allocated */ 79 #define NCHASH(cnp, dvp) \ 80 (((cnp)->cn_hash ^ ((uintptr_t)(dvp) >> 3)) & nchash) 81 82 LIST_HEAD(ncvhashhead, namecache) *ncvhashtbl; 83 u_long ncvhash; /* size of hash table - 1 */ 84 #define NCVHASH(vp) (((uintptr_t)(vp) >> 3) & ncvhash) 85 86 TAILQ_HEAD(, namecache) nclruhead; /* LRU chain */ 87 struct nchstats nchstats; /* cache effectiveness statistics */ 88 89 POOL_INIT(namecache_pool, sizeof(struct namecache), 0, 0, 0, "ncachepl", 90 &pool_allocator_nointr); 91 92 MALLOC_DEFINE(M_CACHE, "namecache", "Dynamically allocated cache entries"); 93 94 int doingcache = 1; /* 1 => enable the cache */ 95 96 /* A single lock to protect cache insertion, removal and lookup */ 97 static struct simplelock namecache_slock = SIMPLELOCK_INITIALIZER; 98 99 static void cache_remove(struct namecache *); 100 static void cache_free(struct namecache *); 101 static inline struct namecache *cache_lookup_entry( 102 const struct vnode *, const struct componentname *); 103 104 static void 105 cache_remove(struct namecache *ncp) 106 { 107 108 LOCK_ASSERT(simple_lock_held(&namecache_slock)); 109 110 ncp->nc_dvp = NULL; 111 ncp->nc_vp = NULL; 112 113 TAILQ_REMOVE(&nclruhead, ncp, nc_lru); 114 if (ncp->nc_hash.le_prev != NULL) { 115 LIST_REMOVE(ncp, nc_hash); 116 ncp->nc_hash.le_prev = NULL; 117 } 118 if (ncp->nc_vhash.le_prev != NULL) { 119 LIST_REMOVE(ncp, nc_vhash); 120 ncp->nc_vhash.le_prev = NULL; 121 } 122 if (ncp->nc_vlist.le_prev != NULL) { 123 LIST_REMOVE(ncp, nc_vlist); 124 ncp->nc_vlist.le_prev = NULL; 125 } 126 if (ncp->nc_dvlist.le_prev != NULL) { 127 LIST_REMOVE(ncp, nc_dvlist); 128 ncp->nc_dvlist.le_prev = NULL; 129 } 130 } 131 132 static void 133 cache_free(struct namecache *ncp) 134 { 135 136 pool_put(&namecache_pool, ncp); 137 numcache--; 138 } 139 140 static inline struct namecache * 141 cache_lookup_entry(const struct vnode *dvp, const struct componentname *cnp) 142 { 143 struct nchashhead *ncpp; 144 struct namecache *ncp; 145 146 LOCK_ASSERT(simple_lock_held(&namecache_slock)); 147 148 ncpp = &nchashtbl[NCHASH(cnp, dvp)]; 149 150 LIST_FOREACH(ncp, ncpp, nc_hash) { 151 if (ncp->nc_dvp == dvp && 152 ncp->nc_nlen == cnp->cn_namelen && 153 !memcmp(ncp->nc_name, cnp->cn_nameptr, (u_int)ncp->nc_nlen)) 154 break; 155 } 156 157 return ncp; 158 } 159 160 /* 161 * Look for a the name in the cache. We don't do this 162 * if the segment name is long, simply so the cache can avoid 163 * holding long names (which would either waste space, or 164 * add greatly to the complexity). 165 * 166 * Lookup is called with ni_dvp pointing to the directory to search, 167 * ni_ptr pointing to the name of the entry being sought, ni_namelen 168 * tells the length of the name, and ni_hash contains a hash of 169 * the name. If the lookup succeeds, the vnode is locked, stored in ni_vp 170 * and a status of zero is returned. If the locking fails for whatever 171 * reason, the vnode is unlocked and the error is returned to caller. 172 * If the lookup determines that the name does not exist (negative cacheing), 173 * a status of ENOENT is returned. If the lookup fails, a status of -1 174 * is returned. 175 */ 176 int 177 cache_lookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp) 178 { 179 struct namecache *ncp; 180 struct vnode *vp; 181 int error; 182 183 if (!doingcache) { 184 cnp->cn_flags &= ~MAKEENTRY; 185 *vpp = NULL; 186 return (-1); 187 } 188 189 if (cnp->cn_namelen > NCHNAMLEN) { 190 /* XXXSMP - updating stats without lock; do we care? */ 191 nchstats.ncs_long++; 192 cnp->cn_flags &= ~MAKEENTRY; 193 goto fail; 194 } 195 simple_lock(&namecache_slock); 196 ncp = cache_lookup_entry(dvp, cnp); 197 if (ncp == NULL) { 198 nchstats.ncs_miss++; 199 goto fail_wlock; 200 } 201 if ((cnp->cn_flags & MAKEENTRY) == 0) { 202 nchstats.ncs_badhits++; 203 goto remove; 204 } else if (ncp->nc_vp == NULL) { 205 /* 206 * Restore the ISWHITEOUT flag saved earlier. 207 */ 208 cnp->cn_flags |= ncp->nc_flags; 209 if (cnp->cn_nameiop != CREATE || 210 (cnp->cn_flags & ISLASTCN) == 0) { 211 nchstats.ncs_neghits++; 212 /* 213 * Move this slot to end of LRU chain, 214 * if not already there. 215 */ 216 if (TAILQ_NEXT(ncp, nc_lru) != 0) { 217 TAILQ_REMOVE(&nclruhead, ncp, nc_lru); 218 TAILQ_INSERT_TAIL(&nclruhead, ncp, nc_lru); 219 } 220 simple_unlock(&namecache_slock); 221 return (ENOENT); 222 } else { 223 nchstats.ncs_badhits++; 224 goto remove; 225 } 226 } 227 228 vp = ncp->nc_vp; 229 230 /* 231 * Move this slot to end of LRU chain, if not already there. 232 */ 233 if (TAILQ_NEXT(ncp, nc_lru) != 0) { 234 TAILQ_REMOVE(&nclruhead, ncp, nc_lru); 235 TAILQ_INSERT_TAIL(&nclruhead, ncp, nc_lru); 236 } 237 238 error = vget(vp, LK_NOWAIT); 239 240 /* Release the name cache mutex while we get reference to the vnode */ 241 simple_unlock(&namecache_slock); 242 243 #ifdef DEBUG 244 /* 245 * since we released namecache_slock, 246 * we can't use this pointer any more. 247 */ 248 ncp = NULL; 249 #endif /* DEBUG */ 250 251 if (error) { 252 KASSERT(error == EBUSY); 253 /* 254 * this vnode is being cleaned out. 255 */ 256 nchstats.ncs_falsehits++; /* XXX badhits? */ 257 goto fail; 258 } 259 260 if (vp == dvp) { /* lookup on "." */ 261 error = 0; 262 } else if (cnp->cn_flags & ISDOTDOT) { 263 VOP_UNLOCK(dvp, 0); 264 cnp->cn_flags |= PDIRUNLOCK; 265 error = vn_lock(vp, LK_EXCLUSIVE); 266 /* 267 * If the above vn_lock() succeeded and both LOCKPARENT and 268 * ISLASTCN is set, lock the directory vnode as well. 269 */ 270 if (!error && (~cnp->cn_flags & (LOCKPARENT|ISLASTCN)) == 0) { 271 if ((error = vn_lock(dvp, LK_EXCLUSIVE)) != 0) { 272 vput(vp); 273 return (error); 274 } 275 cnp->cn_flags &= ~PDIRUNLOCK; 276 } 277 } else { 278 error = vn_lock(vp, LK_EXCLUSIVE); 279 /* 280 * If the above vn_lock() failed or either of LOCKPARENT or 281 * ISLASTCN is not set, unlock the directory vnode. 282 */ 283 if (error || (~cnp->cn_flags & (LOCKPARENT|ISLASTCN)) != 0) { 284 VOP_UNLOCK(dvp, 0); 285 cnp->cn_flags |= PDIRUNLOCK; 286 } 287 } 288 289 /* 290 * Check that the lock succeeded. 291 */ 292 if (error) { 293 /* XXXSMP - updating stats without lock; do we care? */ 294 nchstats.ncs_badhits++; 295 296 /* 297 * The parent needs to be locked when we return to VOP_LOOKUP(). 298 * The `.' case here should be extremely rare (if it can happen 299 * at all), so we don't bother optimizing out the unlock/relock. 300 */ 301 if ((error = vn_lock(dvp, LK_EXCLUSIVE)) != 0) 302 return (error); 303 cnp->cn_flags &= ~PDIRUNLOCK; 304 *vpp = NULL; 305 return (-1); 306 } 307 308 /* XXXSMP - updating stats without lock; do we care? */ 309 nchstats.ncs_goodhits++; 310 *vpp = vp; 311 return (0); 312 313 remove: 314 /* 315 * Last component and we are renaming or deleting, 316 * the cache entry is invalid, or otherwise don't 317 * want cache entry to exist. 318 */ 319 cache_remove(ncp); 320 cache_free(ncp); 321 322 fail_wlock: 323 simple_unlock(&namecache_slock); 324 fail: 325 *vpp = NULL; 326 return (-1); 327 } 328 329 int 330 cache_lookup_raw(struct vnode *dvp, struct vnode **vpp, 331 struct componentname *cnp) 332 { 333 struct namecache *ncp; 334 struct vnode *vp; 335 int error; 336 337 if (!doingcache) { 338 cnp->cn_flags &= ~MAKEENTRY; 339 *vpp = NULL; 340 return (-1); 341 } 342 343 if (cnp->cn_namelen > NCHNAMLEN) { 344 /* XXXSMP - updating stats without lock; do we care? */ 345 nchstats.ncs_long++; 346 cnp->cn_flags &= ~MAKEENTRY; 347 goto fail; 348 } 349 simple_lock(&namecache_slock); 350 ncp = cache_lookup_entry(dvp, cnp); 351 if (ncp == NULL) { 352 nchstats.ncs_miss++; 353 goto fail_wlock; 354 } 355 /* 356 * Move this slot to end of LRU chain, 357 * if not already there. 358 */ 359 if (TAILQ_NEXT(ncp, nc_lru) != 0) { 360 TAILQ_REMOVE(&nclruhead, ncp, nc_lru); 361 TAILQ_INSERT_TAIL(&nclruhead, ncp, nc_lru); 362 } 363 364 vp = ncp->nc_vp; 365 if (vp == NULL) { 366 /* 367 * Restore the ISWHITEOUT flag saved earlier. 368 */ 369 cnp->cn_flags |= ncp->nc_flags; 370 nchstats.ncs_neghits++; 371 simple_unlock(&namecache_slock); 372 return (ENOENT); 373 } 374 375 error = vget(vp, LK_NOWAIT); 376 377 /* Release the name cache mutex while we get reference to the vnode */ 378 simple_unlock(&namecache_slock); 379 380 if (error) { 381 KASSERT(error == EBUSY); 382 /* 383 * this vnode is being cleaned out. 384 */ 385 nchstats.ncs_falsehits++; /* XXX badhits? */ 386 goto fail; 387 } 388 389 *vpp = vp; 390 391 return 0; 392 393 fail_wlock: 394 simple_unlock(&namecache_slock); 395 fail: 396 *vpp = NULL; 397 return -1; 398 } 399 400 /* 401 * Scan cache looking for name of directory entry pointing at vp. 402 * 403 * Fill in dvpp. 404 * 405 * If bufp is non-NULL, also place the name in the buffer which starts 406 * at bufp, immediately before *bpp, and move bpp backwards to point 407 * at the start of it. (Yes, this is a little baroque, but it's done 408 * this way to cater to the whims of getcwd). 409 * 410 * Returns 0 on success, -1 on cache miss, positive errno on failure. 411 */ 412 int 413 cache_revlookup(struct vnode *vp, struct vnode **dvpp, char **bpp, char *bufp) 414 { 415 struct namecache *ncp; 416 struct vnode *dvp; 417 struct ncvhashhead *nvcpp; 418 char *bp; 419 420 if (!doingcache) 421 goto out; 422 423 nvcpp = &ncvhashtbl[NCVHASH(vp)]; 424 425 simple_lock(&namecache_slock); 426 LIST_FOREACH(ncp, nvcpp, nc_vhash) { 427 if (ncp->nc_vp == vp && 428 (dvp = ncp->nc_dvp) != NULL && 429 dvp != vp) { /* avoid pesky . entries.. */ 430 431 #ifdef DIAGNOSTIC 432 if (ncp->nc_nlen == 1 && 433 ncp->nc_name[0] == '.') 434 panic("cache_revlookup: found entry for ."); 435 436 if (ncp->nc_nlen == 2 && 437 ncp->nc_name[0] == '.' && 438 ncp->nc_name[1] == '.') 439 panic("cache_revlookup: found entry for .."); 440 #endif 441 nchstats.ncs_revhits++; 442 443 if (bufp) { 444 bp = *bpp; 445 bp -= ncp->nc_nlen; 446 if (bp <= bufp) { 447 *dvpp = NULL; 448 simple_unlock(&namecache_slock); 449 return (ERANGE); 450 } 451 memcpy(bp, ncp->nc_name, ncp->nc_nlen); 452 *bpp = bp; 453 } 454 455 /* XXX MP: how do we know dvp won't evaporate? */ 456 *dvpp = dvp; 457 simple_unlock(&namecache_slock); 458 return (0); 459 } 460 } 461 nchstats.ncs_revmiss++; 462 simple_unlock(&namecache_slock); 463 out: 464 *dvpp = NULL; 465 return (-1); 466 } 467 468 /* 469 * Add an entry to the cache 470 */ 471 void 472 cache_enter(struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 473 { 474 struct namecache *ncp; 475 struct namecache *oncp; 476 struct nchashhead *ncpp; 477 struct ncvhashhead *nvcpp; 478 479 #ifdef DIAGNOSTIC 480 if (cnp->cn_namelen > NCHNAMLEN) 481 panic("cache_enter: name too long"); 482 #endif 483 if (!doingcache) 484 return; 485 /* 486 * Free the cache slot at head of lru chain. 487 */ 488 simple_lock(&namecache_slock); 489 490 if (numcache < numvnodes) { 491 numcache++; 492 simple_unlock(&namecache_slock); 493 ncp = pool_get(&namecache_pool, PR_WAITOK); 494 memset(ncp, 0, sizeof(*ncp)); 495 simple_lock(&namecache_slock); 496 } else if ((ncp = TAILQ_FIRST(&nclruhead)) != NULL) { 497 cache_remove(ncp); 498 } else { 499 simple_unlock(&namecache_slock); 500 return; 501 } 502 503 /* 504 * Concurrent lookups in the same directory may race for a 505 * cache entry. if there's a duplicated entry, free it. 506 */ 507 oncp = cache_lookup_entry(dvp, cnp); 508 if (oncp) { 509 cache_remove(oncp); 510 cache_free(oncp); 511 } 512 KASSERT(cache_lookup_entry(dvp, cnp) == NULL); 513 514 /* Grab the vnode we just found. */ 515 ncp->nc_vp = vp; 516 if (vp == NULL) { 517 /* 518 * For negative hits, save the ISWHITEOUT flag so we can 519 * restore it later when the cache entry is used again. 520 */ 521 ncp->nc_flags = cnp->cn_flags & ISWHITEOUT; 522 } 523 /* Fill in cache info. */ 524 ncp->nc_dvp = dvp; 525 LIST_INSERT_HEAD(&dvp->v_dnclist, ncp, nc_dvlist); 526 if (vp) 527 LIST_INSERT_HEAD(&vp->v_nclist, ncp, nc_vlist); 528 ncp->nc_nlen = cnp->cn_namelen; 529 memcpy(ncp->nc_name, cnp->cn_nameptr, (unsigned)ncp->nc_nlen); 530 TAILQ_INSERT_TAIL(&nclruhead, ncp, nc_lru); 531 ncpp = &nchashtbl[NCHASH(cnp, dvp)]; 532 LIST_INSERT_HEAD(ncpp, ncp, nc_hash); 533 534 ncp->nc_vhash.le_prev = NULL; 535 ncp->nc_vhash.le_next = NULL; 536 537 /* 538 * Create reverse-cache entries (used in getcwd) for directories. 539 * (and in linux procfs exe node) 540 */ 541 if (vp != NULL && 542 vp != dvp && 543 #ifndef NAMECACHE_ENTER_REVERSE 544 vp->v_type == VDIR && 545 #endif 546 (ncp->nc_nlen > 2 || 547 (ncp->nc_nlen > 1 && ncp->nc_name[1] != '.') || 548 (/* ncp->nc_nlen > 0 && */ ncp->nc_name[0] != '.'))) { 549 nvcpp = &ncvhashtbl[NCVHASH(vp)]; 550 LIST_INSERT_HEAD(nvcpp, ncp, nc_vhash); 551 } 552 simple_unlock(&namecache_slock); 553 } 554 555 /* 556 * Name cache initialization, from vfs_init() when we are booting 557 */ 558 void 559 nchinit(void) 560 { 561 562 TAILQ_INIT(&nclruhead); 563 nchashtbl = 564 hashinit(desiredvnodes, HASH_LIST, M_CACHE, M_WAITOK, &nchash); 565 ncvhashtbl = 566 #ifdef NAMECACHE_ENTER_REVERSE 567 hashinit(desiredvnodes, HASH_LIST, M_CACHE, M_WAITOK, &ncvhash); 568 #else 569 hashinit(desiredvnodes/8, HASH_LIST, M_CACHE, M_WAITOK, &ncvhash); 570 #endif 571 } 572 573 /* 574 * Name cache reinitialization, for when the maximum number of vnodes increases. 575 */ 576 void 577 nchreinit(void) 578 { 579 struct namecache *ncp; 580 struct nchashhead *oldhash1, *hash1; 581 struct ncvhashhead *oldhash2, *hash2; 582 u_long i, oldmask1, oldmask2, mask1, mask2; 583 584 hash1 = hashinit(desiredvnodes, HASH_LIST, M_CACHE, M_WAITOK, &mask1); 585 hash2 = 586 #ifdef NAMECACHE_ENTER_REVERSE 587 hashinit(desiredvnodes, HASH_LIST, M_CACHE, M_WAITOK, &mask2); 588 #else 589 hashinit(desiredvnodes/8, HASH_LIST, M_CACHE, M_WAITOK, &mask2); 590 #endif 591 simple_lock(&namecache_slock); 592 oldhash1 = nchashtbl; 593 oldmask1 = nchash; 594 nchashtbl = hash1; 595 nchash = mask1; 596 oldhash2 = ncvhashtbl; 597 oldmask2 = ncvhash; 598 ncvhashtbl = hash2; 599 ncvhash = mask2; 600 for (i = 0; i <= oldmask1; i++) { 601 while ((ncp = LIST_FIRST(&oldhash1[i])) != NULL) { 602 LIST_REMOVE(ncp, nc_hash); 603 ncp->nc_hash.le_prev = NULL; 604 } 605 } 606 for (i = 0; i <= oldmask2; i++) { 607 while ((ncp = LIST_FIRST(&oldhash2[i])) != NULL) { 608 LIST_REMOVE(ncp, nc_vhash); 609 ncp->nc_vhash.le_prev = NULL; 610 } 611 } 612 simple_unlock(&namecache_slock); 613 hashdone(oldhash1, M_CACHE); 614 hashdone(oldhash2, M_CACHE); 615 } 616 617 /* 618 * Cache flush, a particular vnode; called when a vnode is renamed to 619 * hide entries that would now be invalid 620 */ 621 void 622 cache_purge1(struct vnode *vp, const struct componentname *cnp, int flags) 623 { 624 struct namecache *ncp, *ncnext; 625 626 simple_lock(&namecache_slock); 627 if (flags & PURGE_PARENTS) { 628 for (ncp = LIST_FIRST(&vp->v_nclist); ncp != NULL; 629 ncp = ncnext) { 630 ncnext = LIST_NEXT(ncp, nc_vlist); 631 cache_remove(ncp); 632 cache_free(ncp); 633 } 634 } 635 if (flags & PURGE_CHILDREN) { 636 for (ncp = LIST_FIRST(&vp->v_dnclist); ncp != NULL; 637 ncp = ncnext) { 638 ncnext = LIST_NEXT(ncp, nc_dvlist); 639 cache_remove(ncp); 640 cache_free(ncp); 641 } 642 } 643 if (cnp != NULL) { 644 ncp = cache_lookup_entry(vp, cnp); 645 if (ncp) { 646 cache_remove(ncp); 647 cache_free(ncp); 648 } 649 } 650 simple_unlock(&namecache_slock); 651 } 652 653 /* 654 * Cache flush, a whole filesystem; called when filesys is umounted to 655 * remove entries that would now be invalid. 656 */ 657 void 658 cache_purgevfs(struct mount *mp) 659 { 660 struct namecache *ncp, *nxtcp; 661 662 simple_lock(&namecache_slock); 663 for (ncp = TAILQ_FIRST(&nclruhead); ncp != NULL; ncp = nxtcp) { 664 nxtcp = TAILQ_NEXT(ncp, nc_lru); 665 if (ncp->nc_dvp == NULL || ncp->nc_dvp->v_mount != mp) { 666 continue; 667 } 668 /* Free the resources we had. */ 669 cache_remove(ncp); 670 cache_free(ncp); 671 } 672 simple_unlock(&namecache_slock); 673 } 674 675 #ifdef DDB 676 void 677 namecache_print(struct vnode *vp, void (*pr)(const char *, ...)) 678 { 679 struct vnode *dvp = NULL; 680 struct namecache *ncp; 681 682 TAILQ_FOREACH(ncp, &nclruhead, nc_lru) { 683 if (ncp->nc_vp == vp) { 684 (*pr)("name %.*s\n", ncp->nc_nlen, ncp->nc_name); 685 dvp = ncp->nc_dvp; 686 } 687 } 688 if (dvp == NULL) { 689 (*pr)("name not found\n"); 690 return; 691 } 692 vp = dvp; 693 TAILQ_FOREACH(ncp, &nclruhead, nc_lru) { 694 if (ncp->nc_vp == vp) { 695 (*pr)("parent %.*s\n", ncp->nc_nlen, ncp->nc_name); 696 } 697 } 698 } 699 #endif 700