1 /*- 2 * Copyright (c) 1989, 1993, 1995 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Poul-Henning Kamp of the FreeBSD Project. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 4. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 * 32 * @(#)vfs_cache.c 8.5 (Berkeley) 3/22/95 33 */ 34 35 #include <sys/cdefs.h> 36 __FBSDID("$FreeBSD$"); 37 38 #include "opt_kdtrace.h" 39 #include "opt_ktrace.h" 40 41 #include <sys/param.h> 42 #include <sys/filedesc.h> 43 #include <sys/fnv_hash.h> 44 #include <sys/kernel.h> 45 #include <sys/lock.h> 46 #include <sys/malloc.h> 47 #include <sys/mount.h> 48 #include <sys/namei.h> 49 #include <sys/proc.h> 50 #include <sys/rwlock.h> 51 #include <sys/sdt.h> 52 #include <sys/syscallsubr.h> 53 #include <sys/sysctl.h> 54 #include <sys/sysproto.h> 55 #include <sys/systm.h> 56 #include <sys/vnode.h> 57 #ifdef KTRACE 58 #include <sys/ktrace.h> 59 #endif 60 61 #include <vm/uma.h> 62 63 SDT_PROVIDER_DECLARE(vfs); 64 SDT_PROBE_DEFINE3(vfs, namecache, enter, done, done, "struct vnode *", "char *", 65 "struct vnode *"); 66 SDT_PROBE_DEFINE2(vfs, namecache, enter_negative, done, done, "struct vnode *", 67 "char *"); 68 SDT_PROBE_DEFINE1(vfs, namecache, fullpath, entry, entry, "struct vnode *"); 69 SDT_PROBE_DEFINE3(vfs, namecache, fullpath, hit, hit, "struct vnode *", 70 "struct char *", "struct vnode *"); 71 SDT_PROBE_DEFINE1(vfs, namecache, fullpath, miss, miss, "struct vnode *"); 72 SDT_PROBE_DEFINE3(vfs, namecache, fullpath, return, return, "int", 73 "struct vnode *", "struct char *"); 74 SDT_PROBE_DEFINE3(vfs, namecache, lookup, hit, hit, "struct vnode *", "char *", 75 "struct vnode *"); 76 SDT_PROBE_DEFINE2(vfs, namecache, lookup, hit_negative, hit-negative, 77 "struct vnode *", "char *"); 78 SDT_PROBE_DEFINE2(vfs, namecache, lookup, miss, miss, "struct vnode *", 79 "char *"); 80 SDT_PROBE_DEFINE1(vfs, namecache, purge, done, done, "struct vnode *"); 81 SDT_PROBE_DEFINE1(vfs, namecache, purge_negative, done, done, "struct vnode *"); 82 SDT_PROBE_DEFINE1(vfs, namecache, purgevfs, done, done, "struct mount *"); 83 SDT_PROBE_DEFINE3(vfs, namecache, zap, done, done, "struct vnode *", "char *", 84 "struct vnode *"); 85 SDT_PROBE_DEFINE2(vfs, namecache, zap_negative, done, done, "struct vnode *", 86 "char *"); 87 88 /* 89 * This structure describes the elements in the cache of recent 90 * names looked up by namei. 91 */ 92 93 struct namecache { 94 LIST_ENTRY(namecache) nc_hash; /* hash chain */ 95 LIST_ENTRY(namecache) nc_src; /* source vnode list */ 96 TAILQ_ENTRY(namecache) nc_dst; /* destination vnode list */ 97 struct vnode *nc_dvp; /* vnode of parent of name */ 98 struct vnode *nc_vp; /* vnode the name refers to */ 99 u_char nc_flag; /* flag bits */ 100 u_char nc_nlen; /* length of name */ 101 char nc_name[0]; /* segment name + nul */ 102 }; 103 104 /* 105 * Name caching works as follows: 106 * 107 * Names found by directory scans are retained in a cache 108 * for future reference. It is managed LRU, so frequently 109 * used names will hang around. Cache is indexed by hash value 110 * obtained from (vp, name) where vp refers to the directory 111 * containing name. 112 * 113 * If it is a "negative" entry, (i.e. for a name that is known NOT to 114 * exist) the vnode pointer will be NULL. 115 * 116 * Upon reaching the last segment of a path, if the reference 117 * is for DELETE, or NOCACHE is set (rewrite), and the 118 * name is located in the cache, it will be dropped. 119 */ 120 121 /* 122 * Structures associated with name cacheing. 123 */ 124 #define NCHHASH(hash) \ 125 (&nchashtbl[(hash) & nchash]) 126 static LIST_HEAD(nchashhead, namecache) *nchashtbl; /* Hash Table */ 127 static TAILQ_HEAD(, namecache) ncneg; /* Hash Table */ 128 static u_long nchash; /* size of hash table */ 129 SYSCTL_ULONG(_debug, OID_AUTO, nchash, CTLFLAG_RD, &nchash, 0, 130 "Size of namecache hash table"); 131 static u_long ncnegfactor = 16; /* ratio of negative entries */ 132 SYSCTL_ULONG(_vfs, OID_AUTO, ncnegfactor, CTLFLAG_RW, &ncnegfactor, 0, 133 "Ratio of negative namecache entries"); 134 static u_long numneg; /* number of negative entries allocated */ 135 SYSCTL_ULONG(_debug, OID_AUTO, numneg, CTLFLAG_RD, &numneg, 0, 136 "Number of negative entries in namecache"); 137 static u_long numcache; /* number of cache entries allocated */ 138 SYSCTL_ULONG(_debug, OID_AUTO, numcache, CTLFLAG_RD, &numcache, 0, 139 "Number of namecache entries"); 140 static u_long numcachehv; /* number of cache entries with vnodes held */ 141 SYSCTL_ULONG(_debug, OID_AUTO, numcachehv, CTLFLAG_RD, &numcachehv, 0, 142 "Number of namecache entries with vnodes held"); 143 static u_int ncsizefactor = 2; 144 SYSCTL_UINT(_vfs, OID_AUTO, ncsizefactor, CTLFLAG_RW, &ncsizefactor, 0, 145 "Size factor for namecache"); 146 147 struct nchstats nchstats; /* cache effectiveness statistics */ 148 149 static struct rwlock cache_lock; 150 RW_SYSINIT(vfscache, &cache_lock, "Name Cache"); 151 152 #define CACHE_UPGRADE_LOCK() rw_try_upgrade(&cache_lock) 153 #define CACHE_RLOCK() rw_rlock(&cache_lock) 154 #define CACHE_RUNLOCK() rw_runlock(&cache_lock) 155 #define CACHE_WLOCK() rw_wlock(&cache_lock) 156 #define CACHE_WUNLOCK() rw_wunlock(&cache_lock) 157 158 /* 159 * UMA zones for the VFS cache. 160 * 161 * The small cache is used for entries with short names, which are the 162 * most common. The large cache is used for entries which are too big to 163 * fit in the small cache. 164 */ 165 static uma_zone_t cache_zone_small; 166 static uma_zone_t cache_zone_large; 167 168 #define CACHE_PATH_CUTOFF 35 169 #define CACHE_ZONE_SMALL (sizeof(struct namecache) + CACHE_PATH_CUTOFF \ 170 + 1) 171 #define CACHE_ZONE_LARGE (sizeof(struct namecache) + NAME_MAX + 1) 172 173 #define cache_alloc(len) uma_zalloc(((len) <= CACHE_PATH_CUTOFF) ? \ 174 cache_zone_small : cache_zone_large, M_WAITOK) 175 #define cache_free(ncp) do { \ 176 if (ncp != NULL) \ 177 uma_zfree(((ncp)->nc_nlen <= CACHE_PATH_CUTOFF) ? \ 178 cache_zone_small : cache_zone_large, (ncp)); \ 179 } while (0) 180 181 static int doingcache = 1; /* 1 => enable the cache */ 182 SYSCTL_INT(_debug, OID_AUTO, vfscache, CTLFLAG_RW, &doingcache, 0, 183 "VFS namecache enabled"); 184 185 /* Export size information to userland */ 186 SYSCTL_INT(_debug_sizeof, OID_AUTO, namecache, CTLFLAG_RD, 0, 187 sizeof(struct namecache), "sizeof(struct namecache)"); 188 189 /* 190 * The new name cache statistics 191 */ 192 static SYSCTL_NODE(_vfs, OID_AUTO, cache, CTLFLAG_RW, 0, 193 "Name cache statistics"); 194 #define STATNODE(mode, name, var, descr) \ 195 SYSCTL_ULONG(_vfs_cache, OID_AUTO, name, mode, var, 0, descr); 196 STATNODE(CTLFLAG_RD, numneg, &numneg, "Number of negative cache entries"); 197 STATNODE(CTLFLAG_RD, numcache, &numcache, "Number of cache entries"); 198 static u_long numcalls; STATNODE(CTLFLAG_RD, numcalls, &numcalls, 199 "Number of cache lookups"); 200 static u_long dothits; STATNODE(CTLFLAG_RD, dothits, &dothits, 201 "Number of '.' hits"); 202 static u_long dotdothits; STATNODE(CTLFLAG_RD, dotdothits, &dotdothits, 203 "Number of '..' hits"); 204 static u_long numchecks; STATNODE(CTLFLAG_RD, numchecks, &numchecks, 205 "Number of checks in lookup"); 206 static u_long nummiss; STATNODE(CTLFLAG_RD, nummiss, &nummiss, 207 "Number of cache misses"); 208 static u_long nummisszap; STATNODE(CTLFLAG_RD, nummisszap, &nummisszap, 209 "Number of cache misses we do not want to cache"); 210 static u_long numposzaps; STATNODE(CTLFLAG_RD, numposzaps, &numposzaps, 211 "Number of cache hits (positive) we do not want to cache"); 212 static u_long numposhits; STATNODE(CTLFLAG_RD, numposhits, &numposhits, 213 "Number of cache hits (positive)"); 214 static u_long numnegzaps; STATNODE(CTLFLAG_RD, numnegzaps, &numnegzaps, 215 "Number of cache hits (negative) we do not want to cache"); 216 static u_long numneghits; STATNODE(CTLFLAG_RD, numneghits, &numneghits, 217 "Number of cache hits (negative)"); 218 static u_long numupgrades; STATNODE(CTLFLAG_RD, numupgrades, &numupgrades, 219 "Number of updates of the cache after lookup (write lock + retry)"); 220 221 SYSCTL_OPAQUE(_vfs_cache, OID_AUTO, nchstats, CTLFLAG_RD | CTLFLAG_MPSAFE, 222 &nchstats, sizeof(nchstats), "LU", 223 "VFS cache effectiveness statistics"); 224 225 226 227 static void cache_zap(struct namecache *ncp); 228 static int vn_vptocnp_locked(struct vnode **vp, struct ucred *cred, char *buf, 229 u_int *buflen); 230 static int vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, 231 char *buf, char **retbuf, u_int buflen); 232 233 static MALLOC_DEFINE(M_VFSCACHE, "vfscache", "VFS name cache entries"); 234 235 /* 236 * Flags in namecache.nc_flag 237 */ 238 #define NCF_WHITE 0x01 239 #define NCF_ISDOTDOT 0x02 240 241 #ifdef DIAGNOSTIC 242 /* 243 * Grab an atomic snapshot of the name cache hash chain lengths 244 */ 245 static SYSCTL_NODE(_debug, OID_AUTO, hashstat, CTLFLAG_RW, NULL, 246 "hash table stats"); 247 248 static int 249 sysctl_debug_hashstat_rawnchash(SYSCTL_HANDLER_ARGS) 250 { 251 int error; 252 struct nchashhead *ncpp; 253 struct namecache *ncp; 254 int n_nchash; 255 int count; 256 257 n_nchash = nchash + 1; /* nchash is max index, not count */ 258 if (!req->oldptr) 259 return SYSCTL_OUT(req, 0, n_nchash * sizeof(int)); 260 261 /* Scan hash tables for applicable entries */ 262 for (ncpp = nchashtbl; n_nchash > 0; n_nchash--, ncpp++) { 263 CACHE_RLOCK(); 264 count = 0; 265 LIST_FOREACH(ncp, ncpp, nc_hash) { 266 count++; 267 } 268 CACHE_RUNLOCK(); 269 error = SYSCTL_OUT(req, &count, sizeof(count)); 270 if (error) 271 return (error); 272 } 273 return (0); 274 } 275 SYSCTL_PROC(_debug_hashstat, OID_AUTO, rawnchash, CTLTYPE_INT|CTLFLAG_RD| 276 CTLFLAG_MPSAFE, 0, 0, sysctl_debug_hashstat_rawnchash, "S,int", 277 "nchash chain lengths"); 278 279 static int 280 sysctl_debug_hashstat_nchash(SYSCTL_HANDLER_ARGS) 281 { 282 int error; 283 struct nchashhead *ncpp; 284 struct namecache *ncp; 285 int n_nchash; 286 int count, maxlength, used, pct; 287 288 if (!req->oldptr) 289 return SYSCTL_OUT(req, 0, 4 * sizeof(int)); 290 291 n_nchash = nchash + 1; /* nchash is max index, not count */ 292 used = 0; 293 maxlength = 0; 294 295 /* Scan hash tables for applicable entries */ 296 for (ncpp = nchashtbl; n_nchash > 0; n_nchash--, ncpp++) { 297 count = 0; 298 CACHE_RLOCK(); 299 LIST_FOREACH(ncp, ncpp, nc_hash) { 300 count++; 301 } 302 CACHE_RUNLOCK(); 303 if (count) 304 used++; 305 if (maxlength < count) 306 maxlength = count; 307 } 308 n_nchash = nchash + 1; 309 pct = (used * 100 * 100) / n_nchash; 310 error = SYSCTL_OUT(req, &n_nchash, sizeof(n_nchash)); 311 if (error) 312 return (error); 313 error = SYSCTL_OUT(req, &used, sizeof(used)); 314 if (error) 315 return (error); 316 error = SYSCTL_OUT(req, &maxlength, sizeof(maxlength)); 317 if (error) 318 return (error); 319 error = SYSCTL_OUT(req, &pct, sizeof(pct)); 320 if (error) 321 return (error); 322 return (0); 323 } 324 SYSCTL_PROC(_debug_hashstat, OID_AUTO, nchash, CTLTYPE_INT|CTLFLAG_RD| 325 CTLFLAG_MPSAFE, 0, 0, sysctl_debug_hashstat_nchash, "I", 326 "nchash chain lengths"); 327 #endif 328 329 /* 330 * cache_zap(): 331 * 332 * Removes a namecache entry from cache, whether it contains an actual 333 * pointer to a vnode or if it is just a negative cache entry. 334 */ 335 static void 336 cache_zap(ncp) 337 struct namecache *ncp; 338 { 339 struct vnode *vp; 340 341 rw_assert(&cache_lock, RA_WLOCKED); 342 CTR2(KTR_VFS, "cache_zap(%p) vp %p", ncp, ncp->nc_vp); 343 #ifdef KDTRACE_HOOKS 344 if (ncp->nc_vp != NULL) { 345 SDT_PROBE(vfs, namecache, zap, done, ncp->nc_dvp, 346 ncp->nc_name, ncp->nc_vp, 0, 0); 347 } else { 348 SDT_PROBE(vfs, namecache, zap_negative, done, ncp->nc_dvp, 349 ncp->nc_name, 0, 0, 0); 350 } 351 #endif 352 vp = NULL; 353 LIST_REMOVE(ncp, nc_hash); 354 if (ncp->nc_flag & NCF_ISDOTDOT) { 355 if (ncp == ncp->nc_dvp->v_cache_dd) 356 ncp->nc_dvp->v_cache_dd = NULL; 357 } else { 358 LIST_REMOVE(ncp, nc_src); 359 if (LIST_EMPTY(&ncp->nc_dvp->v_cache_src)) { 360 vp = ncp->nc_dvp; 361 numcachehv--; 362 } 363 } 364 if (ncp->nc_vp) { 365 TAILQ_REMOVE(&ncp->nc_vp->v_cache_dst, ncp, nc_dst); 366 if (ncp == ncp->nc_vp->v_cache_dd) 367 ncp->nc_vp->v_cache_dd = NULL; 368 } else { 369 TAILQ_REMOVE(&ncneg, ncp, nc_dst); 370 numneg--; 371 } 372 numcache--; 373 cache_free(ncp); 374 if (vp) 375 vdrop(vp); 376 } 377 378 /* 379 * Lookup an entry in the cache 380 * 381 * Lookup is called with dvp pointing to the directory to search, 382 * cnp pointing to the name of the entry being sought. If the lookup 383 * succeeds, the vnode is returned in *vpp, and a status of -1 is 384 * returned. If the lookup determines that the name does not exist 385 * (negative cacheing), a status of ENOENT is returned. If the lookup 386 * fails, a status of zero is returned. If the directory vnode is 387 * recycled out from under us due to a forced unmount, a status of 388 * ENOENT is returned. 389 * 390 * vpp is locked and ref'd on return. If we're looking up DOTDOT, dvp is 391 * unlocked. If we're looking up . an extra ref is taken, but the lock is 392 * not recursively acquired. 393 */ 394 395 int 396 cache_lookup(dvp, vpp, cnp) 397 struct vnode *dvp; 398 struct vnode **vpp; 399 struct componentname *cnp; 400 { 401 struct namecache *ncp; 402 uint32_t hash; 403 int error, ltype, wlocked; 404 405 if (!doingcache) { 406 cnp->cn_flags &= ~MAKEENTRY; 407 return (0); 408 } 409 retry: 410 CACHE_RLOCK(); 411 wlocked = 0; 412 numcalls++; 413 error = 0; 414 415 retry_wlocked: 416 if (cnp->cn_nameptr[0] == '.') { 417 if (cnp->cn_namelen == 1) { 418 *vpp = dvp; 419 CTR2(KTR_VFS, "cache_lookup(%p, %s) found via .", 420 dvp, cnp->cn_nameptr); 421 dothits++; 422 SDT_PROBE(vfs, namecache, lookup, hit, dvp, ".", 423 *vpp, 0, 0); 424 goto success; 425 } 426 if (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.') { 427 dotdothits++; 428 if (dvp->v_cache_dd == NULL) { 429 SDT_PROBE(vfs, namecache, lookup, miss, dvp, 430 "..", NULL, 0, 0); 431 goto unlock; 432 } 433 if ((cnp->cn_flags & MAKEENTRY) == 0) { 434 if (!wlocked && !CACHE_UPGRADE_LOCK()) 435 goto wlock; 436 if (dvp->v_cache_dd->nc_flag & NCF_ISDOTDOT) 437 cache_zap(dvp->v_cache_dd); 438 dvp->v_cache_dd = NULL; 439 CACHE_WUNLOCK(); 440 return (0); 441 } 442 if (dvp->v_cache_dd->nc_flag & NCF_ISDOTDOT) 443 *vpp = dvp->v_cache_dd->nc_vp; 444 else 445 *vpp = dvp->v_cache_dd->nc_dvp; 446 /* Return failure if negative entry was found. */ 447 if (*vpp == NULL) { 448 ncp = dvp->v_cache_dd; 449 goto negative_success; 450 } 451 CTR3(KTR_VFS, "cache_lookup(%p, %s) found %p via ..", 452 dvp, cnp->cn_nameptr, *vpp); 453 SDT_PROBE(vfs, namecache, lookup, hit, dvp, "..", 454 *vpp, 0, 0); 455 goto success; 456 } 457 } 458 459 hash = fnv_32_buf(cnp->cn_nameptr, cnp->cn_namelen, FNV1_32_INIT); 460 hash = fnv_32_buf(&dvp, sizeof(dvp), hash); 461 LIST_FOREACH(ncp, (NCHHASH(hash)), nc_hash) { 462 numchecks++; 463 if (ncp->nc_dvp == dvp && ncp->nc_nlen == cnp->cn_namelen && 464 !bcmp(ncp->nc_name, cnp->cn_nameptr, ncp->nc_nlen)) 465 break; 466 } 467 468 /* We failed to find an entry */ 469 if (ncp == NULL) { 470 SDT_PROBE(vfs, namecache, lookup, miss, dvp, cnp->cn_nameptr, 471 NULL, 0, 0); 472 if ((cnp->cn_flags & MAKEENTRY) == 0) { 473 nummisszap++; 474 } else { 475 nummiss++; 476 } 477 nchstats.ncs_miss++; 478 goto unlock; 479 } 480 481 /* We don't want to have an entry, so dump it */ 482 if ((cnp->cn_flags & MAKEENTRY) == 0) { 483 numposzaps++; 484 nchstats.ncs_badhits++; 485 if (!wlocked && !CACHE_UPGRADE_LOCK()) 486 goto wlock; 487 cache_zap(ncp); 488 CACHE_WUNLOCK(); 489 return (0); 490 } 491 492 /* We found a "positive" match, return the vnode */ 493 if (ncp->nc_vp) { 494 numposhits++; 495 nchstats.ncs_goodhits++; 496 *vpp = ncp->nc_vp; 497 CTR4(KTR_VFS, "cache_lookup(%p, %s) found %p via ncp %p", 498 dvp, cnp->cn_nameptr, *vpp, ncp); 499 SDT_PROBE(vfs, namecache, lookup, hit, dvp, ncp->nc_name, 500 *vpp, 0, 0); 501 goto success; 502 } 503 504 negative_success: 505 /* We found a negative match, and want to create it, so purge */ 506 if (cnp->cn_nameiop == CREATE) { 507 numnegzaps++; 508 nchstats.ncs_badhits++; 509 if (!wlocked && !CACHE_UPGRADE_LOCK()) 510 goto wlock; 511 cache_zap(ncp); 512 CACHE_WUNLOCK(); 513 return (0); 514 } 515 516 if (!wlocked && !CACHE_UPGRADE_LOCK()) 517 goto wlock; 518 numneghits++; 519 /* 520 * We found a "negative" match, so we shift it to the end of 521 * the "negative" cache entries queue to satisfy LRU. Also, 522 * check to see if the entry is a whiteout; indicate this to 523 * the componentname, if so. 524 */ 525 TAILQ_REMOVE(&ncneg, ncp, nc_dst); 526 TAILQ_INSERT_TAIL(&ncneg, ncp, nc_dst); 527 nchstats.ncs_neghits++; 528 if (ncp->nc_flag & NCF_WHITE) 529 cnp->cn_flags |= ISWHITEOUT; 530 SDT_PROBE(vfs, namecache, lookup, hit_negative, dvp, ncp->nc_name, 531 0, 0, 0); 532 CACHE_WUNLOCK(); 533 return (ENOENT); 534 535 wlock: 536 /* 537 * We need to update the cache after our lookup, so upgrade to 538 * a write lock and retry the operation. 539 */ 540 CACHE_RUNLOCK(); 541 CACHE_WLOCK(); 542 numupgrades++; 543 wlocked = 1; 544 goto retry_wlocked; 545 546 success: 547 /* 548 * On success we return a locked and ref'd vnode as per the lookup 549 * protocol. 550 */ 551 if (dvp == *vpp) { /* lookup on "." */ 552 VREF(*vpp); 553 if (wlocked) 554 CACHE_WUNLOCK(); 555 else 556 CACHE_RUNLOCK(); 557 /* 558 * When we lookup "." we still can be asked to lock it 559 * differently... 560 */ 561 ltype = cnp->cn_lkflags & LK_TYPE_MASK; 562 if (ltype != VOP_ISLOCKED(*vpp)) { 563 if (ltype == LK_EXCLUSIVE) { 564 vn_lock(*vpp, LK_UPGRADE | LK_RETRY); 565 if ((*vpp)->v_iflag & VI_DOOMED) { 566 /* forced unmount */ 567 vrele(*vpp); 568 *vpp = NULL; 569 return (ENOENT); 570 } 571 } else 572 vn_lock(*vpp, LK_DOWNGRADE | LK_RETRY); 573 } 574 return (-1); 575 } 576 ltype = 0; /* silence gcc warning */ 577 if (cnp->cn_flags & ISDOTDOT) { 578 ltype = VOP_ISLOCKED(dvp); 579 VOP_UNLOCK(dvp, 0); 580 } 581 VI_LOCK(*vpp); 582 if (wlocked) 583 CACHE_WUNLOCK(); 584 else 585 CACHE_RUNLOCK(); 586 error = vget(*vpp, cnp->cn_lkflags | LK_INTERLOCK, cnp->cn_thread); 587 if (cnp->cn_flags & ISDOTDOT) { 588 vn_lock(dvp, ltype | LK_RETRY); 589 if (dvp->v_iflag & VI_DOOMED) { 590 if (error == 0) 591 vput(*vpp); 592 *vpp = NULL; 593 return (ENOENT); 594 } 595 } 596 if (error) { 597 *vpp = NULL; 598 goto retry; 599 } 600 if ((cnp->cn_flags & ISLASTCN) && 601 (cnp->cn_lkflags & LK_TYPE_MASK) == LK_EXCLUSIVE) { 602 ASSERT_VOP_ELOCKED(*vpp, "cache_lookup"); 603 } 604 return (-1); 605 606 unlock: 607 if (wlocked) 608 CACHE_WUNLOCK(); 609 else 610 CACHE_RUNLOCK(); 611 return (0); 612 } 613 614 /* 615 * Add an entry to the cache. 616 */ 617 void 618 cache_enter(dvp, vp, cnp) 619 struct vnode *dvp; 620 struct vnode *vp; 621 struct componentname *cnp; 622 { 623 struct namecache *ncp, *n2; 624 struct nchashhead *ncpp; 625 uint32_t hash; 626 int flag; 627 int hold; 628 int zap; 629 int len; 630 631 CTR3(KTR_VFS, "cache_enter(%p, %p, %s)", dvp, vp, cnp->cn_nameptr); 632 VNASSERT(vp == NULL || (vp->v_iflag & VI_DOOMED) == 0, vp, 633 ("cache_enter: Adding a doomed vnode")); 634 VNASSERT(dvp == NULL || (dvp->v_iflag & VI_DOOMED) == 0, dvp, 635 ("cache_enter: Doomed vnode used as src")); 636 637 if (!doingcache) 638 return; 639 640 /* 641 * Avoid blowout in namecache entries. 642 */ 643 if (numcache >= desiredvnodes * ncsizefactor) 644 return; 645 646 flag = 0; 647 if (cnp->cn_nameptr[0] == '.') { 648 if (cnp->cn_namelen == 1) 649 return; 650 if (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.') { 651 CACHE_WLOCK(); 652 /* 653 * If dotdot entry already exists, just retarget it 654 * to new parent vnode, otherwise continue with new 655 * namecache entry allocation. 656 */ 657 if ((ncp = dvp->v_cache_dd) != NULL && 658 ncp->nc_flag & NCF_ISDOTDOT) { 659 KASSERT(ncp->nc_dvp == dvp, 660 ("wrong isdotdot parent")); 661 if (ncp->nc_vp != NULL) 662 TAILQ_REMOVE(&ncp->nc_vp->v_cache_dst, 663 ncp, nc_dst); 664 else 665 TAILQ_REMOVE(&ncneg, ncp, nc_dst); 666 if (vp != NULL) 667 TAILQ_INSERT_HEAD(&vp->v_cache_dst, 668 ncp, nc_dst); 669 else 670 TAILQ_INSERT_TAIL(&ncneg, ncp, nc_dst); 671 ncp->nc_vp = vp; 672 CACHE_WUNLOCK(); 673 return; 674 } 675 dvp->v_cache_dd = NULL; 676 SDT_PROBE(vfs, namecache, enter, done, dvp, "..", vp, 677 0, 0); 678 CACHE_WUNLOCK(); 679 flag = NCF_ISDOTDOT; 680 } 681 } 682 683 hold = 0; 684 zap = 0; 685 686 /* 687 * Calculate the hash key and setup as much of the new 688 * namecache entry as possible before acquiring the lock. 689 */ 690 ncp = cache_alloc(cnp->cn_namelen); 691 ncp->nc_vp = vp; 692 ncp->nc_dvp = dvp; 693 ncp->nc_flag = flag; 694 len = ncp->nc_nlen = cnp->cn_namelen; 695 hash = fnv_32_buf(cnp->cn_nameptr, len, FNV1_32_INIT); 696 strlcpy(ncp->nc_name, cnp->cn_nameptr, len + 1); 697 hash = fnv_32_buf(&dvp, sizeof(dvp), hash); 698 CACHE_WLOCK(); 699 700 /* 701 * See if this vnode or negative entry is already in the cache 702 * with this name. This can happen with concurrent lookups of 703 * the same path name. 704 */ 705 ncpp = NCHHASH(hash); 706 LIST_FOREACH(n2, ncpp, nc_hash) { 707 if (n2->nc_dvp == dvp && 708 n2->nc_nlen == cnp->cn_namelen && 709 !bcmp(n2->nc_name, cnp->cn_nameptr, n2->nc_nlen)) { 710 CACHE_WUNLOCK(); 711 cache_free(ncp); 712 return; 713 } 714 } 715 716 if (flag == NCF_ISDOTDOT) { 717 /* 718 * See if we are trying to add .. entry, but some other lookup 719 * has populated v_cache_dd pointer already. 720 */ 721 if (dvp->v_cache_dd != NULL) { 722 CACHE_WUNLOCK(); 723 cache_free(ncp); 724 return; 725 } 726 KASSERT(vp == NULL || vp->v_type == VDIR, 727 ("wrong vnode type %p", vp)); 728 dvp->v_cache_dd = ncp; 729 } 730 731 numcache++; 732 if (!vp) { 733 numneg++; 734 if (cnp->cn_flags & ISWHITEOUT) 735 ncp->nc_flag |= NCF_WHITE; 736 } else if (vp->v_type == VDIR) { 737 if (flag != NCF_ISDOTDOT) { 738 if ((n2 = vp->v_cache_dd) != NULL && 739 (n2->nc_flag & NCF_ISDOTDOT) != 0) 740 cache_zap(n2); 741 vp->v_cache_dd = ncp; 742 } 743 } else { 744 vp->v_cache_dd = NULL; 745 } 746 747 /* 748 * Insert the new namecache entry into the appropriate chain 749 * within the cache entries table. 750 */ 751 LIST_INSERT_HEAD(ncpp, ncp, nc_hash); 752 if (flag != NCF_ISDOTDOT) { 753 if (LIST_EMPTY(&dvp->v_cache_src)) { 754 hold = 1; 755 numcachehv++; 756 } 757 LIST_INSERT_HEAD(&dvp->v_cache_src, ncp, nc_src); 758 } 759 760 /* 761 * If the entry is "negative", we place it into the 762 * "negative" cache queue, otherwise, we place it into the 763 * destination vnode's cache entries queue. 764 */ 765 if (vp) { 766 TAILQ_INSERT_HEAD(&vp->v_cache_dst, ncp, nc_dst); 767 SDT_PROBE(vfs, namecache, enter, done, dvp, ncp->nc_name, vp, 768 0, 0); 769 } else { 770 TAILQ_INSERT_TAIL(&ncneg, ncp, nc_dst); 771 SDT_PROBE(vfs, namecache, enter_negative, done, dvp, 772 ncp->nc_name, 0, 0, 0); 773 } 774 if (numneg * ncnegfactor > numcache) { 775 ncp = TAILQ_FIRST(&ncneg); 776 zap = 1; 777 } 778 if (hold) 779 vhold(dvp); 780 if (zap) 781 cache_zap(ncp); 782 CACHE_WUNLOCK(); 783 } 784 785 /* 786 * Name cache initialization, from vfs_init() when we are booting 787 */ 788 static void 789 nchinit(void *dummy __unused) 790 { 791 792 TAILQ_INIT(&ncneg); 793 794 cache_zone_small = uma_zcreate("S VFS Cache", CACHE_ZONE_SMALL, NULL, 795 NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_ZINIT); 796 cache_zone_large = uma_zcreate("L VFS Cache", CACHE_ZONE_LARGE, NULL, 797 NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_ZINIT); 798 799 nchashtbl = hashinit(desiredvnodes * 2, M_VFSCACHE, &nchash); 800 } 801 SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_SECOND, nchinit, NULL); 802 803 804 /* 805 * Invalidate all entries to a particular vnode. 806 */ 807 void 808 cache_purge(vp) 809 struct vnode *vp; 810 { 811 812 CTR1(KTR_VFS, "cache_purge(%p)", vp); 813 SDT_PROBE(vfs, namecache, purge, done, vp, 0, 0, 0, 0); 814 CACHE_WLOCK(); 815 while (!LIST_EMPTY(&vp->v_cache_src)) 816 cache_zap(LIST_FIRST(&vp->v_cache_src)); 817 while (!TAILQ_EMPTY(&vp->v_cache_dst)) 818 cache_zap(TAILQ_FIRST(&vp->v_cache_dst)); 819 if (vp->v_cache_dd != NULL) { 820 KASSERT(vp->v_cache_dd->nc_flag & NCF_ISDOTDOT, 821 ("lost dotdot link")); 822 cache_zap(vp->v_cache_dd); 823 } 824 KASSERT(vp->v_cache_dd == NULL, ("incomplete purge")); 825 CACHE_WUNLOCK(); 826 } 827 828 /* 829 * Invalidate all negative entries for a particular directory vnode. 830 */ 831 void 832 cache_purge_negative(vp) 833 struct vnode *vp; 834 { 835 struct namecache *cp, *ncp; 836 837 CTR1(KTR_VFS, "cache_purge_negative(%p)", vp); 838 SDT_PROBE(vfs, namecache, purge_negative, done, vp, 0, 0, 0, 0); 839 CACHE_WLOCK(); 840 LIST_FOREACH_SAFE(cp, &vp->v_cache_src, nc_src, ncp) { 841 if (cp->nc_vp == NULL) 842 cache_zap(cp); 843 } 844 CACHE_WUNLOCK(); 845 } 846 847 /* 848 * Flush all entries referencing a particular filesystem. 849 */ 850 void 851 cache_purgevfs(mp) 852 struct mount *mp; 853 { 854 struct nchashhead *ncpp; 855 struct namecache *ncp, *nnp; 856 857 /* Scan hash tables for applicable entries */ 858 SDT_PROBE(vfs, namecache, purgevfs, done, mp, 0, 0, 0, 0); 859 CACHE_WLOCK(); 860 for (ncpp = &nchashtbl[nchash]; ncpp >= nchashtbl; ncpp--) { 861 LIST_FOREACH_SAFE(ncp, ncpp, nc_hash, nnp) { 862 if (ncp->nc_dvp->v_mount == mp) 863 cache_zap(ncp); 864 } 865 } 866 CACHE_WUNLOCK(); 867 } 868 869 /* 870 * Perform canonical checks and cache lookup and pass on to filesystem 871 * through the vop_cachedlookup only if needed. 872 */ 873 874 int 875 vfs_cache_lookup(ap) 876 struct vop_lookup_args /* { 877 struct vnode *a_dvp; 878 struct vnode **a_vpp; 879 struct componentname *a_cnp; 880 } */ *ap; 881 { 882 struct vnode *dvp; 883 int error; 884 struct vnode **vpp = ap->a_vpp; 885 struct componentname *cnp = ap->a_cnp; 886 struct ucred *cred = cnp->cn_cred; 887 int flags = cnp->cn_flags; 888 struct thread *td = cnp->cn_thread; 889 890 *vpp = NULL; 891 dvp = ap->a_dvp; 892 893 if (dvp->v_type != VDIR) 894 return (ENOTDIR); 895 896 if ((flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) && 897 (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) 898 return (EROFS); 899 900 error = VOP_ACCESS(dvp, VEXEC, cred, td); 901 if (error) 902 return (error); 903 904 error = cache_lookup(dvp, vpp, cnp); 905 if (error == 0) 906 return (VOP_CACHEDLOOKUP(dvp, vpp, cnp)); 907 if (error == -1) 908 return (0); 909 return (error); 910 } 911 912 913 #ifndef _SYS_SYSPROTO_H_ 914 struct __getcwd_args { 915 u_char *buf; 916 u_int buflen; 917 }; 918 #endif 919 920 /* 921 * XXX All of these sysctls would probably be more productive dead. 922 */ 923 static int disablecwd; 924 SYSCTL_INT(_debug, OID_AUTO, disablecwd, CTLFLAG_RW, &disablecwd, 0, 925 "Disable the getcwd syscall"); 926 927 /* Implementation of the getcwd syscall. */ 928 int 929 sys___getcwd(td, uap) 930 struct thread *td; 931 struct __getcwd_args *uap; 932 { 933 934 return (kern___getcwd(td, uap->buf, UIO_USERSPACE, uap->buflen)); 935 } 936 937 int 938 kern___getcwd(struct thread *td, u_char *buf, enum uio_seg bufseg, u_int buflen) 939 { 940 char *bp, *tmpbuf; 941 struct filedesc *fdp; 942 struct vnode *cdir, *rdir; 943 int error, vfslocked; 944 945 if (disablecwd) 946 return (ENODEV); 947 if (buflen < 2) 948 return (EINVAL); 949 if (buflen > MAXPATHLEN) 950 buflen = MAXPATHLEN; 951 952 tmpbuf = malloc(buflen, M_TEMP, M_WAITOK); 953 fdp = td->td_proc->p_fd; 954 FILEDESC_SLOCK(fdp); 955 cdir = fdp->fd_cdir; 956 VREF(cdir); 957 rdir = fdp->fd_rdir; 958 VREF(rdir); 959 FILEDESC_SUNLOCK(fdp); 960 error = vn_fullpath1(td, cdir, rdir, tmpbuf, &bp, buflen); 961 vfslocked = VFS_LOCK_GIANT(rdir->v_mount); 962 vrele(rdir); 963 VFS_UNLOCK_GIANT(vfslocked); 964 vfslocked = VFS_LOCK_GIANT(cdir->v_mount); 965 vrele(cdir); 966 VFS_UNLOCK_GIANT(vfslocked); 967 968 if (!error) { 969 if (bufseg == UIO_SYSSPACE) 970 bcopy(bp, buf, strlen(bp) + 1); 971 else 972 error = copyout(bp, buf, strlen(bp) + 1); 973 #ifdef KTRACE 974 if (KTRPOINT(curthread, KTR_NAMEI)) 975 ktrnamei(bp); 976 #endif 977 } 978 free(tmpbuf, M_TEMP); 979 return (error); 980 } 981 982 /* 983 * Thus begins the fullpath magic. 984 */ 985 986 #undef STATNODE 987 #define STATNODE(name, descr) \ 988 static u_int name; \ 989 SYSCTL_UINT(_vfs_cache, OID_AUTO, name, CTLFLAG_RD, &name, 0, descr) 990 991 static int disablefullpath; 992 SYSCTL_INT(_debug, OID_AUTO, disablefullpath, CTLFLAG_RW, &disablefullpath, 0, 993 "Disable the vn_fullpath function"); 994 995 /* These count for kern___getcwd(), too. */ 996 STATNODE(numfullpathcalls, "Number of fullpath search calls"); 997 STATNODE(numfullpathfail1, "Number of fullpath search errors (ENOTDIR)"); 998 STATNODE(numfullpathfail2, 999 "Number of fullpath search errors (VOP_VPTOCNP failures)"); 1000 STATNODE(numfullpathfail4, "Number of fullpath search errors (ENOMEM)"); 1001 STATNODE(numfullpathfound, "Number of successful fullpath calls"); 1002 1003 /* 1004 * Retrieve the full filesystem path that correspond to a vnode from the name 1005 * cache (if available) 1006 */ 1007 int 1008 vn_fullpath(struct thread *td, struct vnode *vn, char **retbuf, char **freebuf) 1009 { 1010 char *buf; 1011 struct filedesc *fdp; 1012 struct vnode *rdir; 1013 int error, vfslocked; 1014 1015 if (disablefullpath) 1016 return (ENODEV); 1017 if (vn == NULL) 1018 return (EINVAL); 1019 1020 buf = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 1021 fdp = td->td_proc->p_fd; 1022 FILEDESC_SLOCK(fdp); 1023 rdir = fdp->fd_rdir; 1024 VREF(rdir); 1025 FILEDESC_SUNLOCK(fdp); 1026 error = vn_fullpath1(td, vn, rdir, buf, retbuf, MAXPATHLEN); 1027 vfslocked = VFS_LOCK_GIANT(rdir->v_mount); 1028 vrele(rdir); 1029 VFS_UNLOCK_GIANT(vfslocked); 1030 1031 if (!error) 1032 *freebuf = buf; 1033 else 1034 free(buf, M_TEMP); 1035 return (error); 1036 } 1037 1038 /* 1039 * This function is similar to vn_fullpath, but it attempts to lookup the 1040 * pathname relative to the global root mount point. This is required for the 1041 * auditing sub-system, as audited pathnames must be absolute, relative to the 1042 * global root mount point. 1043 */ 1044 int 1045 vn_fullpath_global(struct thread *td, struct vnode *vn, 1046 char **retbuf, char **freebuf) 1047 { 1048 char *buf; 1049 int error; 1050 1051 if (disablefullpath) 1052 return (ENODEV); 1053 if (vn == NULL) 1054 return (EINVAL); 1055 buf = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 1056 error = vn_fullpath1(td, vn, rootvnode, buf, retbuf, MAXPATHLEN); 1057 if (!error) 1058 *freebuf = buf; 1059 else 1060 free(buf, M_TEMP); 1061 return (error); 1062 } 1063 1064 int 1065 vn_vptocnp(struct vnode **vp, struct ucred *cred, char *buf, u_int *buflen) 1066 { 1067 int error; 1068 1069 CACHE_RLOCK(); 1070 error = vn_vptocnp_locked(vp, cred, buf, buflen); 1071 if (error == 0) { 1072 /* 1073 * vn_vptocnp_locked() dropped hold acquired by 1074 * VOP_VPTOCNP immediately after locking the 1075 * cache. Since we are going to drop the cache rlock, 1076 * re-hold the result. 1077 */ 1078 vhold(*vp); 1079 CACHE_RUNLOCK(); 1080 } 1081 return (error); 1082 } 1083 1084 static int 1085 vn_vptocnp_locked(struct vnode **vp, struct ucred *cred, char *buf, 1086 u_int *buflen) 1087 { 1088 struct vnode *dvp; 1089 struct namecache *ncp; 1090 int error, vfslocked; 1091 1092 TAILQ_FOREACH(ncp, &((*vp)->v_cache_dst), nc_dst) { 1093 if ((ncp->nc_flag & NCF_ISDOTDOT) == 0) 1094 break; 1095 } 1096 if (ncp != NULL) { 1097 if (*buflen < ncp->nc_nlen) { 1098 CACHE_RUNLOCK(); 1099 numfullpathfail4++; 1100 error = ENOMEM; 1101 SDT_PROBE(vfs, namecache, fullpath, return, error, 1102 vp, NULL, 0, 0); 1103 return (error); 1104 } 1105 *buflen -= ncp->nc_nlen; 1106 memcpy(buf + *buflen, ncp->nc_name, ncp->nc_nlen); 1107 SDT_PROBE(vfs, namecache, fullpath, hit, ncp->nc_dvp, 1108 ncp->nc_name, vp, 0, 0); 1109 *vp = ncp->nc_dvp; 1110 return (0); 1111 } 1112 SDT_PROBE(vfs, namecache, fullpath, miss, vp, 0, 0, 0, 0); 1113 1114 vhold(*vp); 1115 CACHE_RUNLOCK(); 1116 vfslocked = VFS_LOCK_GIANT((*vp)->v_mount); 1117 vn_lock(*vp, LK_SHARED | LK_RETRY); 1118 error = VOP_VPTOCNP(*vp, &dvp, cred, buf, buflen); 1119 VOP_UNLOCK(*vp, 0); 1120 vdrop(*vp); 1121 VFS_UNLOCK_GIANT(vfslocked); 1122 if (error) { 1123 numfullpathfail2++; 1124 SDT_PROBE(vfs, namecache, fullpath, return, error, vp, 1125 NULL, 0, 0); 1126 return (error); 1127 } 1128 1129 *vp = dvp; 1130 CACHE_RLOCK(); 1131 if ((*vp)->v_iflag & VI_DOOMED) { 1132 /* forced unmount */ 1133 CACHE_RUNLOCK(); 1134 vdrop(*vp); 1135 error = ENOENT; 1136 SDT_PROBE(vfs, namecache, fullpath, return, error, vp, 1137 NULL, 0, 0); 1138 return (error); 1139 } 1140 vdrop(*vp); 1141 1142 return (0); 1143 } 1144 1145 /* 1146 * The magic behind kern___getcwd() and vn_fullpath(). 1147 */ 1148 static int 1149 vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, 1150 char *buf, char **retbuf, u_int buflen) 1151 { 1152 int error, slash_prefixed; 1153 #ifdef KDTRACE_HOOKS 1154 struct vnode *startvp = vp; 1155 #endif 1156 1157 buflen--; 1158 buf[buflen] = '\0'; 1159 error = 0; 1160 slash_prefixed = 0; 1161 1162 SDT_PROBE(vfs, namecache, fullpath, entry, vp, 0, 0, 0, 0); 1163 numfullpathcalls++; 1164 CACHE_RLOCK(); 1165 if (vp->v_type != VDIR) { 1166 error = vn_vptocnp_locked(&vp, td->td_ucred, buf, &buflen); 1167 if (error) 1168 return (error); 1169 if (buflen == 0) { 1170 CACHE_RUNLOCK(); 1171 return (ENOMEM); 1172 } 1173 buf[--buflen] = '/'; 1174 slash_prefixed = 1; 1175 } 1176 while (vp != rdir && vp != rootvnode) { 1177 if (vp->v_vflag & VV_ROOT) { 1178 if (vp->v_iflag & VI_DOOMED) { /* forced unmount */ 1179 CACHE_RUNLOCK(); 1180 error = ENOENT; 1181 SDT_PROBE(vfs, namecache, fullpath, return, 1182 error, vp, NULL, 0, 0); 1183 break; 1184 } 1185 vp = vp->v_mount->mnt_vnodecovered; 1186 continue; 1187 } 1188 if (vp->v_type != VDIR) { 1189 CACHE_RUNLOCK(); 1190 numfullpathfail1++; 1191 error = ENOTDIR; 1192 SDT_PROBE(vfs, namecache, fullpath, return, 1193 error, vp, NULL, 0, 0); 1194 break; 1195 } 1196 error = vn_vptocnp_locked(&vp, td->td_ucred, buf, &buflen); 1197 if (error) 1198 break; 1199 if (buflen == 0) { 1200 CACHE_RUNLOCK(); 1201 error = ENOMEM; 1202 SDT_PROBE(vfs, namecache, fullpath, return, error, 1203 startvp, NULL, 0, 0); 1204 break; 1205 } 1206 buf[--buflen] = '/'; 1207 slash_prefixed = 1; 1208 } 1209 if (error) 1210 return (error); 1211 if (!slash_prefixed) { 1212 if (buflen == 0) { 1213 CACHE_RUNLOCK(); 1214 numfullpathfail4++; 1215 SDT_PROBE(vfs, namecache, fullpath, return, ENOMEM, 1216 startvp, NULL, 0, 0); 1217 return (ENOMEM); 1218 } 1219 buf[--buflen] = '/'; 1220 } 1221 numfullpathfound++; 1222 CACHE_RUNLOCK(); 1223 1224 SDT_PROBE(vfs, namecache, fullpath, return, 0, startvp, buf + buflen, 1225 0, 0); 1226 *retbuf = buf + buflen; 1227 return (0); 1228 } 1229 1230 int 1231 vn_commname(struct vnode *vp, char *buf, u_int buflen) 1232 { 1233 struct namecache *ncp; 1234 int l; 1235 1236 CACHE_RLOCK(); 1237 TAILQ_FOREACH(ncp, &vp->v_cache_dst, nc_dst) 1238 if ((ncp->nc_flag & NCF_ISDOTDOT) == 0) 1239 break; 1240 if (ncp == NULL) { 1241 CACHE_RUNLOCK(); 1242 return (ENOENT); 1243 } 1244 l = min(ncp->nc_nlen, buflen - 1); 1245 memcpy(buf, ncp->nc_name, l); 1246 CACHE_RUNLOCK(); 1247 buf[l] = '\0'; 1248 return (0); 1249 } 1250