vfs_cache.c revision 321009
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: stable/10/sys/kern/vfs_cache.c 321009 2017-07-15 14:48:31Z dchagin $"); 37 38#include "opt_kdtrace.h" 39#include "opt_ktrace.h" 40 41#include <sys/param.h> 42#include <sys/systm.h> 43#include <sys/filedesc.h> 44#include <sys/fnv_hash.h> 45#include <sys/kernel.h> 46#include <sys/lock.h> 47#include <sys/malloc.h> 48#include <sys/fcntl.h> 49#include <sys/mount.h> 50#include <sys/namei.h> 51#include <sys/proc.h> 52#include <sys/rwlock.h> 53#include <sys/sdt.h> 54#include <sys/syscallsubr.h> 55#include <sys/sysctl.h> 56#include <sys/sysproto.h> 57#include <sys/vnode.h> 58#ifdef KTRACE 59#include <sys/ktrace.h> 60#endif 61 62#include <vm/uma.h> 63 64SDT_PROVIDER_DECLARE(vfs); 65SDT_PROBE_DEFINE3(vfs, namecache, enter, done, "struct vnode *", "char *", 66 "struct vnode *"); 67SDT_PROBE_DEFINE2(vfs, namecache, enter_negative, done, "struct vnode *", 68 "char *"); 69SDT_PROBE_DEFINE1(vfs, namecache, fullpath, entry, "struct vnode *"); 70SDT_PROBE_DEFINE3(vfs, namecache, fullpath, hit, "struct vnode *", 71 "char *", "struct vnode *"); 72SDT_PROBE_DEFINE1(vfs, namecache, fullpath, miss, "struct vnode *"); 73SDT_PROBE_DEFINE3(vfs, namecache, fullpath, return, "int", 74 "struct vnode *", "char *"); 75SDT_PROBE_DEFINE3(vfs, namecache, lookup, hit, "struct vnode *", "char *", 76 "struct vnode *"); 77SDT_PROBE_DEFINE2(vfs, namecache, lookup, hit__negative, 78 "struct vnode *", "char *"); 79SDT_PROBE_DEFINE2(vfs, namecache, lookup, miss, "struct vnode *", 80 "char *"); 81SDT_PROBE_DEFINE1(vfs, namecache, purge, done, "struct vnode *"); 82SDT_PROBE_DEFINE1(vfs, namecache, purge_negative, done, "struct vnode *"); 83SDT_PROBE_DEFINE1(vfs, namecache, purgevfs, done, "struct mount *"); 84SDT_PROBE_DEFINE3(vfs, namecache, zap, done, "struct vnode *", "char *", 85 "struct vnode *"); 86SDT_PROBE_DEFINE2(vfs, namecache, zap_negative, done, "struct vnode *", 87 "char *"); 88 89/* 90 * This structure describes the elements in the cache of recent 91 * names looked up by namei. 92 */ 93 94struct namecache { 95 LIST_ENTRY(namecache) nc_hash; /* hash chain */ 96 LIST_ENTRY(namecache) nc_src; /* source vnode list */ 97 TAILQ_ENTRY(namecache) nc_dst; /* destination vnode list */ 98 struct vnode *nc_dvp; /* vnode of parent of name */ 99 struct vnode *nc_vp; /* vnode the name refers to */ 100 u_char nc_flag; /* flag bits */ 101 u_char nc_nlen; /* length of name */ 102 char nc_name[0]; /* segment name + nul */ 103}; 104 105/* 106 * struct namecache_ts repeats struct namecache layout up to the 107 * nc_nlen member. 108 * struct namecache_ts is used in place of struct namecache when time(s) need 109 * to be stored. The nc_dotdottime field is used when a cache entry is mapping 110 * both a non-dotdot directory name plus dotdot for the directory's 111 * parent. 112 */ 113struct namecache_ts { 114 LIST_ENTRY(namecache) nc_hash; /* hash chain */ 115 LIST_ENTRY(namecache) nc_src; /* source vnode list */ 116 TAILQ_ENTRY(namecache) nc_dst; /* destination vnode list */ 117 struct vnode *nc_dvp; /* vnode of parent of name */ 118 struct vnode *nc_vp; /* vnode the name refers to */ 119 u_char nc_flag; /* flag bits */ 120 u_char nc_nlen; /* length of name */ 121 struct timespec nc_time; /* timespec provided by fs */ 122 struct timespec nc_dotdottime; /* dotdot timespec provided by fs */ 123 int nc_ticks; /* ticks value when entry was added */ 124 char nc_name[0]; /* segment name + nul */ 125}; 126 127/* 128 * Flags in namecache.nc_flag 129 */ 130#define NCF_WHITE 0x01 131#define NCF_ISDOTDOT 0x02 132#define NCF_TS 0x04 133#define NCF_DTS 0x08 134 135/* 136 * Name caching works as follows: 137 * 138 * Names found by directory scans are retained in a cache 139 * for future reference. It is managed LRU, so frequently 140 * used names will hang around. Cache is indexed by hash value 141 * obtained from (vp, name) where vp refers to the directory 142 * containing name. 143 * 144 * If it is a "negative" entry, (i.e. for a name that is known NOT to 145 * exist) the vnode pointer will be NULL. 146 * 147 * Upon reaching the last segment of a path, if the reference 148 * is for DELETE, or NOCACHE is set (rewrite), and the 149 * name is located in the cache, it will be dropped. 150 */ 151 152/* 153 * Structures associated with name caching. 154 */ 155#define NCHHASH(hash) \ 156 (&nchashtbl[(hash) & nchash]) 157static LIST_HEAD(nchashhead, namecache) *nchashtbl; /* Hash Table */ 158static TAILQ_HEAD(, namecache) ncneg; /* Hash Table */ 159static u_long nchash; /* size of hash table */ 160SYSCTL_ULONG(_debug, OID_AUTO, nchash, CTLFLAG_RD, &nchash, 0, 161 "Size of namecache hash table"); 162static u_long ncnegfactor = 16; /* ratio of negative entries */ 163SYSCTL_ULONG(_vfs, OID_AUTO, ncnegfactor, CTLFLAG_RW, &ncnegfactor, 0, 164 "Ratio of negative namecache entries"); 165static u_long numneg; /* number of negative entries allocated */ 166SYSCTL_ULONG(_debug, OID_AUTO, numneg, CTLFLAG_RD, &numneg, 0, 167 "Number of negative entries in namecache"); 168static u_long numcache; /* number of cache entries allocated */ 169SYSCTL_ULONG(_debug, OID_AUTO, numcache, CTLFLAG_RD, &numcache, 0, 170 "Number of namecache entries"); 171static u_long numcachehv; /* number of cache entries with vnodes held */ 172SYSCTL_ULONG(_debug, OID_AUTO, numcachehv, CTLFLAG_RD, &numcachehv, 0, 173 "Number of namecache entries with vnodes held"); 174static u_int ncsizefactor = 2; 175SYSCTL_UINT(_vfs, OID_AUTO, ncsizefactor, CTLFLAG_RW, &ncsizefactor, 0, 176 "Size factor for namecache"); 177 178struct nchstats nchstats; /* cache effectiveness statistics */ 179 180static struct rwlock cache_lock; 181RW_SYSINIT(vfscache, &cache_lock, "Name Cache"); 182 183#define CACHE_UPGRADE_LOCK() rw_try_upgrade(&cache_lock) 184#define CACHE_RLOCK() rw_rlock(&cache_lock) 185#define CACHE_RUNLOCK() rw_runlock(&cache_lock) 186#define CACHE_WLOCK() rw_wlock(&cache_lock) 187#define CACHE_WUNLOCK() rw_wunlock(&cache_lock) 188 189/* 190 * UMA zones for the VFS cache. 191 * 192 * The small cache is used for entries with short names, which are the 193 * most common. The large cache is used for entries which are too big to 194 * fit in the small cache. 195 */ 196static uma_zone_t cache_zone_small; 197static uma_zone_t cache_zone_small_ts; 198static uma_zone_t cache_zone_large; 199static uma_zone_t cache_zone_large_ts; 200 201#define CACHE_PATH_CUTOFF 35 202 203static struct namecache * 204cache_alloc(int len, int ts) 205{ 206 207 if (len > CACHE_PATH_CUTOFF) { 208 if (ts) 209 return (uma_zalloc(cache_zone_large_ts, M_WAITOK)); 210 else 211 return (uma_zalloc(cache_zone_large, M_WAITOK)); 212 } 213 if (ts) 214 return (uma_zalloc(cache_zone_small_ts, M_WAITOK)); 215 else 216 return (uma_zalloc(cache_zone_small, M_WAITOK)); 217} 218 219static void 220cache_free(struct namecache *ncp) 221{ 222 int ts; 223 224 if (ncp == NULL) 225 return; 226 ts = ncp->nc_flag & NCF_TS; 227 if (ncp->nc_nlen <= CACHE_PATH_CUTOFF) { 228 if (ts) 229 uma_zfree(cache_zone_small_ts, ncp); 230 else 231 uma_zfree(cache_zone_small, ncp); 232 } else if (ts) 233 uma_zfree(cache_zone_large_ts, ncp); 234 else 235 uma_zfree(cache_zone_large, ncp); 236} 237 238static char * 239nc_get_name(struct namecache *ncp) 240{ 241 struct namecache_ts *ncp_ts; 242 243 if ((ncp->nc_flag & NCF_TS) == 0) 244 return (ncp->nc_name); 245 ncp_ts = (struct namecache_ts *)ncp; 246 return (ncp_ts->nc_name); 247} 248 249static void 250cache_out_ts(struct namecache *ncp, struct timespec *tsp, int *ticksp) 251{ 252 253 KASSERT((ncp->nc_flag & NCF_TS) != 0 || 254 (tsp == NULL && ticksp == NULL), 255 ("No NCF_TS")); 256 257 if (tsp != NULL) 258 *tsp = ((struct namecache_ts *)ncp)->nc_time; 259 if (ticksp != NULL) 260 *ticksp = ((struct namecache_ts *)ncp)->nc_ticks; 261} 262 263static int doingcache = 1; /* 1 => enable the cache */ 264SYSCTL_INT(_debug, OID_AUTO, vfscache, CTLFLAG_RW, &doingcache, 0, 265 "VFS namecache enabled"); 266 267/* Export size information to userland */ 268SYSCTL_INT(_debug_sizeof, OID_AUTO, namecache, CTLFLAG_RD, SYSCTL_NULL_INT_PTR, 269 sizeof(struct namecache), "sizeof(struct namecache)"); 270 271/* 272 * The new name cache statistics 273 */ 274static SYSCTL_NODE(_vfs, OID_AUTO, cache, CTLFLAG_RW, 0, 275 "Name cache statistics"); 276#define STATNODE(mode, name, var, descr) \ 277 SYSCTL_ULONG(_vfs_cache, OID_AUTO, name, mode, var, 0, descr); 278STATNODE(CTLFLAG_RD, numneg, &numneg, "Number of negative cache entries"); 279STATNODE(CTLFLAG_RD, numcache, &numcache, "Number of cache entries"); 280static u_long numcalls; STATNODE(CTLFLAG_RD, numcalls, &numcalls, 281 "Number of cache lookups"); 282static u_long dothits; STATNODE(CTLFLAG_RD, dothits, &dothits, 283 "Number of '.' hits"); 284static u_long dotdothits; STATNODE(CTLFLAG_RD, dotdothits, &dotdothits, 285 "Number of '..' hits"); 286static u_long numchecks; STATNODE(CTLFLAG_RD, numchecks, &numchecks, 287 "Number of checks in lookup"); 288static u_long nummiss; STATNODE(CTLFLAG_RD, nummiss, &nummiss, 289 "Number of cache misses"); 290static u_long nummisszap; STATNODE(CTLFLAG_RD, nummisszap, &nummisszap, 291 "Number of cache misses we do not want to cache"); 292static u_long numposzaps; STATNODE(CTLFLAG_RD, numposzaps, &numposzaps, 293 "Number of cache hits (positive) we do not want to cache"); 294static u_long numposhits; STATNODE(CTLFLAG_RD, numposhits, &numposhits, 295 "Number of cache hits (positive)"); 296static u_long numnegzaps; STATNODE(CTLFLAG_RD, numnegzaps, &numnegzaps, 297 "Number of cache hits (negative) we do not want to cache"); 298static u_long numneghits; STATNODE(CTLFLAG_RD, numneghits, &numneghits, 299 "Number of cache hits (negative)"); 300static u_long numupgrades; STATNODE(CTLFLAG_RD, numupgrades, &numupgrades, 301 "Number of updates of the cache after lookup (write lock + retry)"); 302 303SYSCTL_OPAQUE(_vfs_cache, OID_AUTO, nchstats, CTLFLAG_RD | CTLFLAG_MPSAFE, 304 &nchstats, sizeof(nchstats), "LU", 305 "VFS cache effectiveness statistics"); 306 307static void cache_zap(struct namecache *ncp); 308static int vn_vptocnp_locked(struct vnode **vp, struct ucred *cred, char *buf, 309 u_int *buflen); 310static int vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, 311 char *buf, char **retbuf, u_int buflen); 312 313static MALLOC_DEFINE(M_VFSCACHE, "vfscache", "VFS name cache entries"); 314 315#ifdef DIAGNOSTIC 316/* 317 * Grab an atomic snapshot of the name cache hash chain lengths 318 */ 319static SYSCTL_NODE(_debug, OID_AUTO, hashstat, CTLFLAG_RW, NULL, 320 "hash table stats"); 321 322static int 323sysctl_debug_hashstat_rawnchash(SYSCTL_HANDLER_ARGS) 324{ 325 struct nchashhead *ncpp; 326 struct namecache *ncp; 327 int i, error, n_nchash, *cntbuf; 328 329retry: 330 n_nchash = nchash + 1; /* nchash is max index, not count */ 331 if (!req->oldptr) 332 return SYSCTL_OUT(req, 0, n_nchash * sizeof(int)); 333 cntbuf = malloc(n_nchash * sizeof(int), M_TEMP, M_ZERO | M_WAITOK); 334 CACHE_RLOCK(); 335 if (n_nchash != nchash + 1) { 336 CACHE_RUNLOCK(); 337 free(cntbuf, M_TEMP); 338 goto retry; 339 } 340 /* Scan hash tables counting entries */ 341 for (ncpp = nchashtbl, i = 0; i < n_nchash; ncpp++, i++) 342 LIST_FOREACH(ncp, ncpp, nc_hash) 343 cntbuf[i]++; 344 CACHE_RUNLOCK(); 345 for (error = 0, i = 0; i < n_nchash; i++) 346 if ((error = SYSCTL_OUT(req, &cntbuf[i], sizeof(int))) != 0) 347 break; 348 free(cntbuf, M_TEMP); 349 return (error); 350} 351SYSCTL_PROC(_debug_hashstat, OID_AUTO, rawnchash, CTLTYPE_INT|CTLFLAG_RD| 352 CTLFLAG_MPSAFE, 0, 0, sysctl_debug_hashstat_rawnchash, "S,int", 353 "nchash chain lengths"); 354 355static int 356sysctl_debug_hashstat_nchash(SYSCTL_HANDLER_ARGS) 357{ 358 int error; 359 struct nchashhead *ncpp; 360 struct namecache *ncp; 361 int n_nchash; 362 int count, maxlength, used, pct; 363 364 if (!req->oldptr) 365 return SYSCTL_OUT(req, 0, 4 * sizeof(int)); 366 367 n_nchash = nchash + 1; /* nchash is max index, not count */ 368 used = 0; 369 maxlength = 0; 370 371 /* Scan hash tables for applicable entries */ 372 for (ncpp = nchashtbl; n_nchash > 0; n_nchash--, ncpp++) { 373 count = 0; 374 CACHE_RLOCK(); 375 LIST_FOREACH(ncp, ncpp, nc_hash) { 376 count++; 377 } 378 CACHE_RUNLOCK(); 379 if (count) 380 used++; 381 if (maxlength < count) 382 maxlength = count; 383 } 384 n_nchash = nchash + 1; 385 pct = (used * 100) / (n_nchash / 100); 386 error = SYSCTL_OUT(req, &n_nchash, sizeof(n_nchash)); 387 if (error) 388 return (error); 389 error = SYSCTL_OUT(req, &used, sizeof(used)); 390 if (error) 391 return (error); 392 error = SYSCTL_OUT(req, &maxlength, sizeof(maxlength)); 393 if (error) 394 return (error); 395 error = SYSCTL_OUT(req, &pct, sizeof(pct)); 396 if (error) 397 return (error); 398 return (0); 399} 400SYSCTL_PROC(_debug_hashstat, OID_AUTO, nchash, CTLTYPE_INT|CTLFLAG_RD| 401 CTLFLAG_MPSAFE, 0, 0, sysctl_debug_hashstat_nchash, "I", 402 "nchash statistics (number of total/used buckets, maximum chain length, usage percentage)"); 403#endif 404 405/* 406 * cache_zap(): 407 * 408 * Removes a namecache entry from cache, whether it contains an actual 409 * pointer to a vnode or if it is just a negative cache entry. 410 */ 411static void 412cache_zap(struct namecache *ncp) 413{ 414 struct vnode *vp; 415 416 rw_assert(&cache_lock, RA_WLOCKED); 417 CTR2(KTR_VFS, "cache_zap(%p) vp %p", ncp, ncp->nc_vp); 418 if (ncp->nc_vp != NULL) { 419 SDT_PROBE3(vfs, namecache, zap, done, ncp->nc_dvp, 420 nc_get_name(ncp), ncp->nc_vp); 421 } else { 422 SDT_PROBE2(vfs, namecache, zap_negative, done, ncp->nc_dvp, 423 nc_get_name(ncp)); 424 } 425 vp = NULL; 426 LIST_REMOVE(ncp, nc_hash); 427 if (ncp->nc_flag & NCF_ISDOTDOT) { 428 if (ncp == ncp->nc_dvp->v_cache_dd) 429 ncp->nc_dvp->v_cache_dd = NULL; 430 } else { 431 LIST_REMOVE(ncp, nc_src); 432 if (LIST_EMPTY(&ncp->nc_dvp->v_cache_src)) { 433 vp = ncp->nc_dvp; 434 numcachehv--; 435 } 436 } 437 if (ncp->nc_vp) { 438 TAILQ_REMOVE(&ncp->nc_vp->v_cache_dst, ncp, nc_dst); 439 if (ncp == ncp->nc_vp->v_cache_dd) 440 ncp->nc_vp->v_cache_dd = NULL; 441 } else { 442 TAILQ_REMOVE(&ncneg, ncp, nc_dst); 443 numneg--; 444 } 445 numcache--; 446 cache_free(ncp); 447 if (vp != NULL) 448 vdrop(vp); 449} 450 451/* 452 * Lookup an entry in the cache 453 * 454 * Lookup is called with dvp pointing to the directory to search, 455 * cnp pointing to the name of the entry being sought. If the lookup 456 * succeeds, the vnode is returned in *vpp, and a status of -1 is 457 * returned. If the lookup determines that the name does not exist 458 * (negative caching), a status of ENOENT is returned. If the lookup 459 * fails, a status of zero is returned. If the directory vnode is 460 * recycled out from under us due to a forced unmount, a status of 461 * ENOENT is returned. 462 * 463 * vpp is locked and ref'd on return. If we're looking up DOTDOT, dvp is 464 * unlocked. If we're looking up . an extra ref is taken, but the lock is 465 * not recursively acquired. 466 */ 467 468int 469cache_lookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, 470 struct timespec *tsp, int *ticksp) 471{ 472 struct namecache *ncp; 473 uint32_t hash; 474 int error, ltype, wlocked; 475 476 if (!doingcache) { 477 cnp->cn_flags &= ~MAKEENTRY; 478 return (0); 479 } 480retry: 481 CACHE_RLOCK(); 482 wlocked = 0; 483 numcalls++; 484 error = 0; 485 486retry_wlocked: 487 if (cnp->cn_nameptr[0] == '.') { 488 if (cnp->cn_namelen == 1) { 489 *vpp = dvp; 490 CTR2(KTR_VFS, "cache_lookup(%p, %s) found via .", 491 dvp, cnp->cn_nameptr); 492 dothits++; 493 SDT_PROBE3(vfs, namecache, lookup, hit, dvp, ".", *vpp); 494 if (tsp != NULL) 495 timespecclear(tsp); 496 if (ticksp != NULL) 497 *ticksp = ticks; 498 goto success; 499 } 500 if (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.') { 501 dotdothits++; 502 if (dvp->v_cache_dd == NULL) { 503 SDT_PROBE3(vfs, namecache, lookup, miss, dvp, 504 "..", NULL); 505 goto unlock; 506 } 507 if ((cnp->cn_flags & MAKEENTRY) == 0) { 508 if (!wlocked && !CACHE_UPGRADE_LOCK()) 509 goto wlock; 510 if (dvp->v_cache_dd->nc_flag & NCF_ISDOTDOT) 511 cache_zap(dvp->v_cache_dd); 512 dvp->v_cache_dd = NULL; 513 CACHE_WUNLOCK(); 514 return (0); 515 } 516 ncp = dvp->v_cache_dd; 517 if (ncp->nc_flag & NCF_ISDOTDOT) 518 *vpp = ncp->nc_vp; 519 else 520 *vpp = ncp->nc_dvp; 521 /* Return failure if negative entry was found. */ 522 if (*vpp == NULL) 523 goto negative_success; 524 CTR3(KTR_VFS, "cache_lookup(%p, %s) found %p via ..", 525 dvp, cnp->cn_nameptr, *vpp); 526 SDT_PROBE3(vfs, namecache, lookup, hit, dvp, "..", 527 *vpp); 528 cache_out_ts(ncp, tsp, ticksp); 529 if ((ncp->nc_flag & (NCF_ISDOTDOT | NCF_DTS)) == 530 NCF_DTS && tsp != NULL) 531 *tsp = ((struct namecache_ts *)ncp)-> 532 nc_dotdottime; 533 goto success; 534 } 535 } 536 537 hash = fnv_32_buf(cnp->cn_nameptr, cnp->cn_namelen, FNV1_32_INIT); 538 hash = fnv_32_buf(&dvp, sizeof(dvp), hash); 539 LIST_FOREACH(ncp, (NCHHASH(hash)), nc_hash) { 540 numchecks++; 541 if (ncp->nc_dvp == dvp && ncp->nc_nlen == cnp->cn_namelen && 542 !bcmp(nc_get_name(ncp), cnp->cn_nameptr, ncp->nc_nlen)) 543 break; 544 } 545 546 /* We failed to find an entry */ 547 if (ncp == NULL) { 548 SDT_PROBE3(vfs, namecache, lookup, miss, dvp, cnp->cn_nameptr, 549 NULL); 550 if ((cnp->cn_flags & MAKEENTRY) == 0) { 551 nummisszap++; 552 } else { 553 nummiss++; 554 } 555 nchstats.ncs_miss++; 556 goto unlock; 557 } 558 559 /* We don't want to have an entry, so dump it */ 560 if ((cnp->cn_flags & MAKEENTRY) == 0) { 561 numposzaps++; 562 nchstats.ncs_badhits++; 563 if (!wlocked && !CACHE_UPGRADE_LOCK()) 564 goto wlock; 565 cache_zap(ncp); 566 CACHE_WUNLOCK(); 567 return (0); 568 } 569 570 /* We found a "positive" match, return the vnode */ 571 if (ncp->nc_vp) { 572 numposhits++; 573 nchstats.ncs_goodhits++; 574 *vpp = ncp->nc_vp; 575 CTR4(KTR_VFS, "cache_lookup(%p, %s) found %p via ncp %p", 576 dvp, cnp->cn_nameptr, *vpp, ncp); 577 SDT_PROBE3(vfs, namecache, lookup, hit, dvp, nc_get_name(ncp), 578 *vpp); 579 cache_out_ts(ncp, tsp, ticksp); 580 goto success; 581 } 582 583negative_success: 584 /* We found a negative match, and want to create it, so purge */ 585 if (cnp->cn_nameiop == CREATE) { 586 numnegzaps++; 587 nchstats.ncs_badhits++; 588 if (!wlocked && !CACHE_UPGRADE_LOCK()) 589 goto wlock; 590 cache_zap(ncp); 591 CACHE_WUNLOCK(); 592 return (0); 593 } 594 595 if (!wlocked && !CACHE_UPGRADE_LOCK()) 596 goto wlock; 597 numneghits++; 598 /* 599 * We found a "negative" match, so we shift it to the end of 600 * the "negative" cache entries queue to satisfy LRU. Also, 601 * check to see if the entry is a whiteout; indicate this to 602 * the componentname, if so. 603 */ 604 TAILQ_REMOVE(&ncneg, ncp, nc_dst); 605 TAILQ_INSERT_TAIL(&ncneg, ncp, nc_dst); 606 nchstats.ncs_neghits++; 607 if (ncp->nc_flag & NCF_WHITE) 608 cnp->cn_flags |= ISWHITEOUT; 609 SDT_PROBE2(vfs, namecache, lookup, hit__negative, dvp, 610 nc_get_name(ncp)); 611 cache_out_ts(ncp, tsp, ticksp); 612 CACHE_WUNLOCK(); 613 return (ENOENT); 614 615wlock: 616 /* 617 * We need to update the cache after our lookup, so upgrade to 618 * a write lock and retry the operation. 619 */ 620 CACHE_RUNLOCK(); 621 CACHE_WLOCK(); 622 numupgrades++; 623 wlocked = 1; 624 goto retry_wlocked; 625 626success: 627 /* 628 * On success we return a locked and ref'd vnode as per the lookup 629 * protocol. 630 */ 631 if (dvp == *vpp) { /* lookup on "." */ 632 VREF(*vpp); 633 if (wlocked) 634 CACHE_WUNLOCK(); 635 else 636 CACHE_RUNLOCK(); 637 /* 638 * When we lookup "." we still can be asked to lock it 639 * differently... 640 */ 641 ltype = cnp->cn_lkflags & LK_TYPE_MASK; 642 if (ltype != VOP_ISLOCKED(*vpp)) { 643 if (ltype == LK_EXCLUSIVE) { 644 vn_lock(*vpp, LK_UPGRADE | LK_RETRY); 645 if ((*vpp)->v_iflag & VI_DOOMED) { 646 /* forced unmount */ 647 vrele(*vpp); 648 *vpp = NULL; 649 return (ENOENT); 650 } 651 } else 652 vn_lock(*vpp, LK_DOWNGRADE | LK_RETRY); 653 } 654 return (-1); 655 } 656 ltype = 0; /* silence gcc warning */ 657 if (cnp->cn_flags & ISDOTDOT) { 658 ltype = VOP_ISLOCKED(dvp); 659 VOP_UNLOCK(dvp, 0); 660 } 661 VI_LOCK(*vpp); 662 if (wlocked) 663 CACHE_WUNLOCK(); 664 else 665 CACHE_RUNLOCK(); 666 error = vget(*vpp, cnp->cn_lkflags | LK_INTERLOCK, cnp->cn_thread); 667 if (cnp->cn_flags & ISDOTDOT) { 668 vn_lock(dvp, ltype | LK_RETRY); 669 if (dvp->v_iflag & VI_DOOMED) { 670 if (error == 0) 671 vput(*vpp); 672 *vpp = NULL; 673 return (ENOENT); 674 } 675 } 676 if (error) { 677 *vpp = NULL; 678 goto retry; 679 } 680 if ((cnp->cn_flags & ISLASTCN) && 681 (cnp->cn_lkflags & LK_TYPE_MASK) == LK_EXCLUSIVE) { 682 ASSERT_VOP_ELOCKED(*vpp, "cache_lookup"); 683 } 684 return (-1); 685 686unlock: 687 if (wlocked) 688 CACHE_WUNLOCK(); 689 else 690 CACHE_RUNLOCK(); 691 return (0); 692} 693 694/* 695 * Add an entry to the cache. 696 */ 697void 698cache_enter_time(struct vnode *dvp, struct vnode *vp, struct componentname *cnp, 699 struct timespec *tsp, struct timespec *dtsp) 700{ 701 struct namecache *ncp, *n2; 702 struct namecache_ts *n3; 703 struct nchashhead *ncpp; 704 uint32_t hash; 705 int flag; 706 int hold; 707 int zap; 708 int len; 709 710 CTR3(KTR_VFS, "cache_enter(%p, %p, %s)", dvp, vp, cnp->cn_nameptr); 711 VNASSERT(vp == NULL || (vp->v_iflag & VI_DOOMED) == 0, vp, 712 ("cache_enter: Adding a doomed vnode")); 713 VNASSERT(dvp == NULL || (dvp->v_iflag & VI_DOOMED) == 0, dvp, 714 ("cache_enter: Doomed vnode used as src")); 715 716 if (!doingcache) 717 return; 718 719 /* 720 * Avoid blowout in namecache entries. 721 */ 722 if (numcache >= desiredvnodes * ncsizefactor) 723 return; 724 725 flag = 0; 726 if (cnp->cn_nameptr[0] == '.') { 727 if (cnp->cn_namelen == 1) 728 return; 729 if (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.') { 730 CACHE_WLOCK(); 731 /* 732 * If dotdot entry already exists, just retarget it 733 * to new parent vnode, otherwise continue with new 734 * namecache entry allocation. 735 */ 736 if ((ncp = dvp->v_cache_dd) != NULL && 737 ncp->nc_flag & NCF_ISDOTDOT) { 738 KASSERT(ncp->nc_dvp == dvp, 739 ("wrong isdotdot parent")); 740 if (ncp->nc_vp != NULL) { 741 TAILQ_REMOVE(&ncp->nc_vp->v_cache_dst, 742 ncp, nc_dst); 743 } else { 744 TAILQ_REMOVE(&ncneg, ncp, nc_dst); 745 numneg--; 746 } 747 if (vp != NULL) { 748 TAILQ_INSERT_HEAD(&vp->v_cache_dst, 749 ncp, nc_dst); 750 } else { 751 TAILQ_INSERT_TAIL(&ncneg, ncp, nc_dst); 752 numneg++; 753 } 754 ncp->nc_vp = vp; 755 CACHE_WUNLOCK(); 756 return; 757 } 758 dvp->v_cache_dd = NULL; 759 SDT_PROBE3(vfs, namecache, enter, done, dvp, "..", vp); 760 CACHE_WUNLOCK(); 761 flag = NCF_ISDOTDOT; 762 } 763 } 764 765 hold = 0; 766 zap = 0; 767 768 /* 769 * Calculate the hash key and setup as much of the new 770 * namecache entry as possible before acquiring the lock. 771 */ 772 ncp = cache_alloc(cnp->cn_namelen, tsp != NULL); 773 ncp->nc_vp = vp; 774 ncp->nc_dvp = dvp; 775 ncp->nc_flag = flag; 776 if (tsp != NULL) { 777 n3 = (struct namecache_ts *)ncp; 778 n3->nc_time = *tsp; 779 n3->nc_ticks = ticks; 780 n3->nc_flag |= NCF_TS; 781 if (dtsp != NULL) { 782 n3->nc_dotdottime = *dtsp; 783 n3->nc_flag |= NCF_DTS; 784 } 785 } 786 len = ncp->nc_nlen = cnp->cn_namelen; 787 hash = fnv_32_buf(cnp->cn_nameptr, len, FNV1_32_INIT); 788 strlcpy(nc_get_name(ncp), cnp->cn_nameptr, len + 1); 789 hash = fnv_32_buf(&dvp, sizeof(dvp), hash); 790 CACHE_WLOCK(); 791 792 /* 793 * See if this vnode or negative entry is already in the cache 794 * with this name. This can happen with concurrent lookups of 795 * the same path name. 796 */ 797 ncpp = NCHHASH(hash); 798 LIST_FOREACH(n2, ncpp, nc_hash) { 799 if (n2->nc_dvp == dvp && 800 n2->nc_nlen == cnp->cn_namelen && 801 !bcmp(nc_get_name(n2), cnp->cn_nameptr, n2->nc_nlen)) { 802 if (tsp != NULL) { 803 KASSERT((n2->nc_flag & NCF_TS) != 0, 804 ("no NCF_TS")); 805 n3 = (struct namecache_ts *)n2; 806 n3->nc_time = 807 ((struct namecache_ts *)ncp)->nc_time; 808 n3->nc_ticks = 809 ((struct namecache_ts *)ncp)->nc_ticks; 810 if (dtsp != NULL) { 811 n3->nc_dotdottime = 812 ((struct namecache_ts *)ncp)-> 813 nc_dotdottime; 814 n3->nc_flag |= NCF_DTS; 815 } 816 } 817 CACHE_WUNLOCK(); 818 cache_free(ncp); 819 return; 820 } 821 } 822 823 if (flag == NCF_ISDOTDOT) { 824 /* 825 * See if we are trying to add .. entry, but some other lookup 826 * has populated v_cache_dd pointer already. 827 */ 828 if (dvp->v_cache_dd != NULL) { 829 CACHE_WUNLOCK(); 830 cache_free(ncp); 831 return; 832 } 833 KASSERT(vp == NULL || vp->v_type == VDIR, 834 ("wrong vnode type %p", vp)); 835 dvp->v_cache_dd = ncp; 836 } 837 838 numcache++; 839 if (vp == NULL) { 840 numneg++; 841 if (cnp->cn_flags & ISWHITEOUT) 842 ncp->nc_flag |= NCF_WHITE; 843 } else if (vp->v_type == VDIR) { 844 if (flag != NCF_ISDOTDOT) { 845 /* 846 * For this case, the cache entry maps both the 847 * directory name in it and the name ".." for the 848 * directory's parent. 849 */ 850 if ((n2 = vp->v_cache_dd) != NULL && 851 (n2->nc_flag & NCF_ISDOTDOT) != 0) 852 cache_zap(n2); 853 vp->v_cache_dd = ncp; 854 } 855 } else { 856 vp->v_cache_dd = NULL; 857 } 858 859 /* 860 * Insert the new namecache entry into the appropriate chain 861 * within the cache entries table. 862 */ 863 LIST_INSERT_HEAD(ncpp, ncp, nc_hash); 864 if (flag != NCF_ISDOTDOT) { 865 if (LIST_EMPTY(&dvp->v_cache_src)) { 866 hold = 1; 867 numcachehv++; 868 } 869 LIST_INSERT_HEAD(&dvp->v_cache_src, ncp, nc_src); 870 } 871 872 /* 873 * If the entry is "negative", we place it into the 874 * "negative" cache queue, otherwise, we place it into the 875 * destination vnode's cache entries queue. 876 */ 877 if (vp != NULL) { 878 TAILQ_INSERT_HEAD(&vp->v_cache_dst, ncp, nc_dst); 879 SDT_PROBE3(vfs, namecache, enter, done, dvp, nc_get_name(ncp), 880 vp); 881 } else { 882 TAILQ_INSERT_TAIL(&ncneg, ncp, nc_dst); 883 SDT_PROBE2(vfs, namecache, enter_negative, done, dvp, 884 nc_get_name(ncp)); 885 } 886 if (numneg * ncnegfactor > numcache) { 887 ncp = TAILQ_FIRST(&ncneg); 888 KASSERT(ncp->nc_vp == NULL, ("ncp %p vp %p on ncneg", 889 ncp, ncp->nc_vp)); 890 zap = 1; 891 } 892 if (hold) 893 vhold(dvp); 894 if (zap) 895 cache_zap(ncp); 896 CACHE_WUNLOCK(); 897} 898 899/* 900 * Name cache initialization, from vfs_init() when we are booting 901 */ 902static void 903nchinit(void *dummy __unused) 904{ 905 906 TAILQ_INIT(&ncneg); 907 908 cache_zone_small = uma_zcreate("S VFS Cache", 909 sizeof(struct namecache) + CACHE_PATH_CUTOFF + 1, 910 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_ZINIT); 911 cache_zone_small_ts = uma_zcreate("STS VFS Cache", 912 sizeof(struct namecache_ts) + CACHE_PATH_CUTOFF + 1, 913 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_ZINIT); 914 cache_zone_large = uma_zcreate("L VFS Cache", 915 sizeof(struct namecache) + NAME_MAX + 1, 916 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_ZINIT); 917 cache_zone_large_ts = uma_zcreate("LTS VFS Cache", 918 sizeof(struct namecache_ts) + NAME_MAX + 1, 919 NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_ZINIT); 920 921 nchashtbl = hashinit(desiredvnodes * 2, M_VFSCACHE, &nchash); 922} 923SYSINIT(vfs, SI_SUB_VFS, SI_ORDER_SECOND, nchinit, NULL); 924 925void 926cache_changesize(int newmaxvnodes) 927{ 928 struct nchashhead *new_nchashtbl, *old_nchashtbl; 929 u_long new_nchash, old_nchash; 930 struct namecache *ncp; 931 uint32_t hash; 932 int i; 933 934 new_nchashtbl = hashinit(newmaxvnodes * 2, M_VFSCACHE, &new_nchash); 935 /* If same hash table size, nothing to do */ 936 if (nchash == new_nchash) { 937 free(new_nchashtbl, M_VFSCACHE); 938 return; 939 } 940 /* 941 * Move everything from the old hash table to the new table. 942 * None of the namecache entries in the table can be removed 943 * because to do so, they have to be removed from the hash table. 944 */ 945 CACHE_WLOCK(); 946 old_nchashtbl = nchashtbl; 947 old_nchash = nchash; 948 nchashtbl = new_nchashtbl; 949 nchash = new_nchash; 950 for (i = 0; i <= old_nchash; i++) { 951 while ((ncp = LIST_FIRST(&old_nchashtbl[i])) != NULL) { 952 hash = fnv_32_buf(nc_get_name(ncp), ncp->nc_nlen, 953 FNV1_32_INIT); 954 hash = fnv_32_buf(&ncp->nc_dvp, sizeof(ncp->nc_dvp), 955 hash); 956 LIST_REMOVE(ncp, nc_hash); 957 LIST_INSERT_HEAD(NCHHASH(hash), ncp, nc_hash); 958 } 959 } 960 CACHE_WUNLOCK(); 961 free(old_nchashtbl, M_VFSCACHE); 962} 963 964/* 965 * Invalidate all entries to a particular vnode. 966 */ 967void 968cache_purge(struct vnode *vp) 969{ 970 971 CTR1(KTR_VFS, "cache_purge(%p)", vp); 972 SDT_PROBE1(vfs, namecache, purge, done, vp); 973 CACHE_WLOCK(); 974 while (!LIST_EMPTY(&vp->v_cache_src)) 975 cache_zap(LIST_FIRST(&vp->v_cache_src)); 976 while (!TAILQ_EMPTY(&vp->v_cache_dst)) 977 cache_zap(TAILQ_FIRST(&vp->v_cache_dst)); 978 if (vp->v_cache_dd != NULL) { 979 KASSERT(vp->v_cache_dd->nc_flag & NCF_ISDOTDOT, 980 ("lost dotdot link")); 981 cache_zap(vp->v_cache_dd); 982 } 983 KASSERT(vp->v_cache_dd == NULL, ("incomplete purge")); 984 CACHE_WUNLOCK(); 985} 986 987/* 988 * Invalidate all negative entries for a particular directory vnode. 989 */ 990void 991cache_purge_negative(struct vnode *vp) 992{ 993 struct namecache *cp, *ncp; 994 995 CTR1(KTR_VFS, "cache_purge_negative(%p)", vp); 996 SDT_PROBE1(vfs, namecache, purge_negative, done, vp); 997 CACHE_WLOCK(); 998 LIST_FOREACH_SAFE(cp, &vp->v_cache_src, nc_src, ncp) { 999 if (cp->nc_vp == NULL) 1000 cache_zap(cp); 1001 } 1002 CACHE_WUNLOCK(); 1003} 1004 1005/* 1006 * Flush all entries referencing a particular filesystem. 1007 */ 1008void 1009cache_purgevfs(struct mount *mp) 1010{ 1011 struct nchashhead *ncpp; 1012 struct namecache *ncp, *nnp; 1013 1014 /* Scan hash tables for applicable entries */ 1015 SDT_PROBE1(vfs, namecache, purgevfs, done, mp); 1016 CACHE_WLOCK(); 1017 for (ncpp = &nchashtbl[nchash]; ncpp >= nchashtbl; ncpp--) { 1018 LIST_FOREACH_SAFE(ncp, ncpp, nc_hash, nnp) { 1019 if (ncp->nc_dvp->v_mount == mp) 1020 cache_zap(ncp); 1021 } 1022 } 1023 CACHE_WUNLOCK(); 1024} 1025 1026/* 1027 * Perform canonical checks and cache lookup and pass on to filesystem 1028 * through the vop_cachedlookup only if needed. 1029 */ 1030 1031int 1032vfs_cache_lookup(struct vop_lookup_args *ap) 1033{ 1034 struct vnode *dvp; 1035 int error; 1036 struct vnode **vpp = ap->a_vpp; 1037 struct componentname *cnp = ap->a_cnp; 1038 struct ucred *cred = cnp->cn_cred; 1039 int flags = cnp->cn_flags; 1040 struct thread *td = cnp->cn_thread; 1041 1042 *vpp = NULL; 1043 dvp = ap->a_dvp; 1044 1045 if (dvp->v_type != VDIR) 1046 return (ENOTDIR); 1047 1048 if ((flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) && 1049 (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) 1050 return (EROFS); 1051 1052 error = VOP_ACCESS(dvp, VEXEC, cred, td); 1053 if (error) 1054 return (error); 1055 1056 error = cache_lookup(dvp, vpp, cnp, NULL, NULL); 1057 if (error == 0) 1058 return (VOP_CACHEDLOOKUP(dvp, vpp, cnp)); 1059 if (error == -1) 1060 return (0); 1061 return (error); 1062} 1063 1064/* 1065 * XXX All of these sysctls would probably be more productive dead. 1066 */ 1067static int disablecwd; 1068SYSCTL_INT(_debug, OID_AUTO, disablecwd, CTLFLAG_RW, &disablecwd, 0, 1069 "Disable the getcwd syscall"); 1070 1071/* Implementation of the getcwd syscall. */ 1072int 1073sys___getcwd(struct thread *td, struct __getcwd_args *uap) 1074{ 1075 1076 return (kern___getcwd(td, uap->buf, UIO_USERSPACE, uap->buflen, 1077 MAXPATHLEN)); 1078} 1079 1080int 1081kern___getcwd(struct thread *td, char *buf, enum uio_seg bufseg, u_int buflen, 1082 u_int path_max) 1083{ 1084 char *bp, *tmpbuf; 1085 struct filedesc *fdp; 1086 struct vnode *cdir, *rdir; 1087 int error; 1088 1089 if (disablecwd) 1090 return (ENODEV); 1091 if (buflen < 2) 1092 return (EINVAL); 1093 if (buflen > path_max) 1094 buflen = path_max; 1095 1096 tmpbuf = malloc(buflen, M_TEMP, M_WAITOK); 1097 fdp = td->td_proc->p_fd; 1098 FILEDESC_SLOCK(fdp); 1099 cdir = fdp->fd_cdir; 1100 VREF(cdir); 1101 rdir = fdp->fd_rdir; 1102 VREF(rdir); 1103 FILEDESC_SUNLOCK(fdp); 1104 error = vn_fullpath1(td, cdir, rdir, tmpbuf, &bp, buflen); 1105 vrele(rdir); 1106 vrele(cdir); 1107 1108 if (!error) { 1109 if (bufseg == UIO_SYSSPACE) 1110 bcopy(bp, buf, strlen(bp) + 1); 1111 else 1112 error = copyout(bp, buf, strlen(bp) + 1); 1113#ifdef KTRACE 1114 if (KTRPOINT(curthread, KTR_NAMEI)) 1115 ktrnamei(bp); 1116#endif 1117 } 1118 free(tmpbuf, M_TEMP); 1119 return (error); 1120} 1121 1122/* 1123 * Thus begins the fullpath magic. 1124 */ 1125 1126#undef STATNODE 1127#define STATNODE(name, descr) \ 1128 static u_int name; \ 1129 SYSCTL_UINT(_vfs_cache, OID_AUTO, name, CTLFLAG_RD, &name, 0, descr) 1130 1131static int disablefullpath; 1132SYSCTL_INT(_debug, OID_AUTO, disablefullpath, CTLFLAG_RW, &disablefullpath, 0, 1133 "Disable the vn_fullpath function"); 1134 1135/* These count for kern___getcwd(), too. */ 1136STATNODE(numfullpathcalls, "Number of fullpath search calls"); 1137STATNODE(numfullpathfail1, "Number of fullpath search errors (ENOTDIR)"); 1138STATNODE(numfullpathfail2, 1139 "Number of fullpath search errors (VOP_VPTOCNP failures)"); 1140STATNODE(numfullpathfail4, "Number of fullpath search errors (ENOMEM)"); 1141STATNODE(numfullpathfound, "Number of successful fullpath calls"); 1142 1143/* 1144 * Retrieve the full filesystem path that correspond to a vnode from the name 1145 * cache (if available) 1146 */ 1147int 1148vn_fullpath(struct thread *td, struct vnode *vn, char **retbuf, char **freebuf) 1149{ 1150 char *buf; 1151 struct filedesc *fdp; 1152 struct vnode *rdir; 1153 int error; 1154 1155 if (disablefullpath) 1156 return (ENODEV); 1157 if (vn == NULL) 1158 return (EINVAL); 1159 1160 buf = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 1161 fdp = td->td_proc->p_fd; 1162 FILEDESC_SLOCK(fdp); 1163 rdir = fdp->fd_rdir; 1164 VREF(rdir); 1165 FILEDESC_SUNLOCK(fdp); 1166 error = vn_fullpath1(td, vn, rdir, buf, retbuf, MAXPATHLEN); 1167 vrele(rdir); 1168 1169 if (!error) 1170 *freebuf = buf; 1171 else 1172 free(buf, M_TEMP); 1173 return (error); 1174} 1175 1176/* 1177 * This function is similar to vn_fullpath, but it attempts to lookup the 1178 * pathname relative to the global root mount point. This is required for the 1179 * auditing sub-system, as audited pathnames must be absolute, relative to the 1180 * global root mount point. 1181 */ 1182int 1183vn_fullpath_global(struct thread *td, struct vnode *vn, 1184 char **retbuf, char **freebuf) 1185{ 1186 char *buf; 1187 int error; 1188 1189 if (disablefullpath) 1190 return (ENODEV); 1191 if (vn == NULL) 1192 return (EINVAL); 1193 buf = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 1194 error = vn_fullpath1(td, vn, rootvnode, buf, retbuf, MAXPATHLEN); 1195 if (!error) 1196 *freebuf = buf; 1197 else 1198 free(buf, M_TEMP); 1199 return (error); 1200} 1201 1202int 1203vn_vptocnp(struct vnode **vp, struct ucred *cred, char *buf, u_int *buflen) 1204{ 1205 int error; 1206 1207 CACHE_RLOCK(); 1208 error = vn_vptocnp_locked(vp, cred, buf, buflen); 1209 if (error == 0) 1210 CACHE_RUNLOCK(); 1211 return (error); 1212} 1213 1214static int 1215vn_vptocnp_locked(struct vnode **vp, struct ucred *cred, char *buf, 1216 u_int *buflen) 1217{ 1218 struct vnode *dvp; 1219 struct namecache *ncp; 1220 int error; 1221 1222 TAILQ_FOREACH(ncp, &((*vp)->v_cache_dst), nc_dst) { 1223 if ((ncp->nc_flag & NCF_ISDOTDOT) == 0) 1224 break; 1225 } 1226 if (ncp != NULL) { 1227 if (*buflen < ncp->nc_nlen) { 1228 CACHE_RUNLOCK(); 1229 vrele(*vp); 1230 numfullpathfail4++; 1231 error = ENOMEM; 1232 SDT_PROBE3(vfs, namecache, fullpath, return, error, 1233 vp, NULL); 1234 return (error); 1235 } 1236 *buflen -= ncp->nc_nlen; 1237 memcpy(buf + *buflen, nc_get_name(ncp), ncp->nc_nlen); 1238 SDT_PROBE3(vfs, namecache, fullpath, hit, ncp->nc_dvp, 1239 nc_get_name(ncp), vp); 1240 dvp = *vp; 1241 *vp = ncp->nc_dvp; 1242 vref(*vp); 1243 CACHE_RUNLOCK(); 1244 vrele(dvp); 1245 CACHE_RLOCK(); 1246 return (0); 1247 } 1248 SDT_PROBE1(vfs, namecache, fullpath, miss, vp); 1249 1250 CACHE_RUNLOCK(); 1251 vn_lock(*vp, LK_SHARED | LK_RETRY); 1252 error = VOP_VPTOCNP(*vp, &dvp, cred, buf, buflen); 1253 vput(*vp); 1254 if (error) { 1255 numfullpathfail2++; 1256 SDT_PROBE3(vfs, namecache, fullpath, return, error, vp, NULL); 1257 return (error); 1258 } 1259 1260 *vp = dvp; 1261 CACHE_RLOCK(); 1262 if (dvp->v_iflag & VI_DOOMED) { 1263 /* forced unmount */ 1264 CACHE_RUNLOCK(); 1265 vrele(dvp); 1266 error = ENOENT; 1267 SDT_PROBE3(vfs, namecache, fullpath, return, error, vp, NULL); 1268 return (error); 1269 } 1270 /* 1271 * *vp has its use count incremented still. 1272 */ 1273 1274 return (0); 1275} 1276 1277/* 1278 * The magic behind kern___getcwd() and vn_fullpath(). 1279 */ 1280static int 1281vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir, 1282 char *buf, char **retbuf, u_int buflen) 1283{ 1284 int error, slash_prefixed; 1285#ifdef KDTRACE_HOOKS 1286 struct vnode *startvp = vp; 1287#endif 1288 struct vnode *vp1; 1289 1290 buflen--; 1291 buf[buflen] = '\0'; 1292 error = 0; 1293 slash_prefixed = 0; 1294 1295 SDT_PROBE1(vfs, namecache, fullpath, entry, vp); 1296 numfullpathcalls++; 1297 vref(vp); 1298 CACHE_RLOCK(); 1299 if (vp->v_type != VDIR) { 1300 error = vn_vptocnp_locked(&vp, td->td_ucred, buf, &buflen); 1301 if (error) 1302 return (error); 1303 if (buflen == 0) { 1304 CACHE_RUNLOCK(); 1305 vrele(vp); 1306 return (ENOMEM); 1307 } 1308 buf[--buflen] = '/'; 1309 slash_prefixed = 1; 1310 } 1311 while (vp != rdir && vp != rootvnode) { 1312 if (vp->v_vflag & VV_ROOT) { 1313 if (vp->v_iflag & VI_DOOMED) { /* forced unmount */ 1314 CACHE_RUNLOCK(); 1315 vrele(vp); 1316 error = ENOENT; 1317 SDT_PROBE3(vfs, namecache, fullpath, return, 1318 error, vp, NULL); 1319 break; 1320 } 1321 vp1 = vp->v_mount->mnt_vnodecovered; 1322 vref(vp1); 1323 CACHE_RUNLOCK(); 1324 vrele(vp); 1325 vp = vp1; 1326 CACHE_RLOCK(); 1327 continue; 1328 } 1329 if (vp->v_type != VDIR) { 1330 CACHE_RUNLOCK(); 1331 vrele(vp); 1332 numfullpathfail1++; 1333 error = ENOTDIR; 1334 SDT_PROBE3(vfs, namecache, fullpath, return, 1335 error, vp, NULL); 1336 break; 1337 } 1338 error = vn_vptocnp_locked(&vp, td->td_ucred, buf, &buflen); 1339 if (error) 1340 break; 1341 if (buflen == 0) { 1342 CACHE_RUNLOCK(); 1343 vrele(vp); 1344 error = ENOMEM; 1345 SDT_PROBE3(vfs, namecache, fullpath, return, error, 1346 startvp, NULL); 1347 break; 1348 } 1349 buf[--buflen] = '/'; 1350 slash_prefixed = 1; 1351 } 1352 if (error) 1353 return (error); 1354 if (!slash_prefixed) { 1355 if (buflen == 0) { 1356 CACHE_RUNLOCK(); 1357 vrele(vp); 1358 numfullpathfail4++; 1359 SDT_PROBE3(vfs, namecache, fullpath, return, ENOMEM, 1360 startvp, NULL); 1361 return (ENOMEM); 1362 } 1363 buf[--buflen] = '/'; 1364 } 1365 numfullpathfound++; 1366 CACHE_RUNLOCK(); 1367 vrele(vp); 1368 1369 SDT_PROBE3(vfs, namecache, fullpath, return, 0, startvp, buf + buflen); 1370 *retbuf = buf + buflen; 1371 return (0); 1372} 1373 1374struct vnode * 1375vn_dir_dd_ino(struct vnode *vp) 1376{ 1377 struct namecache *ncp; 1378 struct vnode *ddvp; 1379 1380 ASSERT_VOP_LOCKED(vp, "vn_dir_dd_ino"); 1381 CACHE_RLOCK(); 1382 TAILQ_FOREACH(ncp, &(vp->v_cache_dst), nc_dst) { 1383 if ((ncp->nc_flag & NCF_ISDOTDOT) != 0) 1384 continue; 1385 ddvp = ncp->nc_dvp; 1386 VI_LOCK(ddvp); 1387 CACHE_RUNLOCK(); 1388 if (vget(ddvp, LK_INTERLOCK | LK_SHARED | LK_NOWAIT, curthread)) 1389 return (NULL); 1390 return (ddvp); 1391 } 1392 CACHE_RUNLOCK(); 1393 return (NULL); 1394} 1395 1396int 1397vn_commname(struct vnode *vp, char *buf, u_int buflen) 1398{ 1399 struct namecache *ncp; 1400 int l; 1401 1402 CACHE_RLOCK(); 1403 TAILQ_FOREACH(ncp, &vp->v_cache_dst, nc_dst) 1404 if ((ncp->nc_flag & NCF_ISDOTDOT) == 0) 1405 break; 1406 if (ncp == NULL) { 1407 CACHE_RUNLOCK(); 1408 return (ENOENT); 1409 } 1410 l = min(ncp->nc_nlen, buflen - 1); 1411 memcpy(buf, nc_get_name(ncp), l); 1412 CACHE_RUNLOCK(); 1413 buf[l] = '\0'; 1414 return (0); 1415} 1416 1417/* ABI compat shims for old kernel modules. */ 1418#undef cache_enter 1419 1420void cache_enter(struct vnode *dvp, struct vnode *vp, 1421 struct componentname *cnp); 1422 1423void 1424cache_enter(struct vnode *dvp, struct vnode *vp, struct componentname *cnp) 1425{ 1426 1427 cache_enter_time(dvp, vp, cnp, NULL, NULL); 1428} 1429 1430/* 1431 * This function updates path string to vnode's full global path 1432 * and checks the size of the new path string against the pathlen argument. 1433 * 1434 * Requires a locked, referenced vnode and GIANT lock held. 1435 * Vnode is re-locked on success or ENODEV, otherwise unlocked. 1436 * 1437 * If sysctl debug.disablefullpath is set, ENODEV is returned, 1438 * vnode is left locked and path remain untouched. 1439 * 1440 * If vp is a directory, the call to vn_fullpath_global() always succeeds 1441 * because it falls back to the ".." lookup if the namecache lookup fails. 1442 */ 1443int 1444vn_path_to_global_path(struct thread *td, struct vnode *vp, char *path, 1445 u_int pathlen) 1446{ 1447 struct nameidata nd; 1448 struct vnode *vp1; 1449 char *rpath, *fbuf; 1450 int error; 1451 1452 ASSERT_VOP_ELOCKED(vp, __func__); 1453 1454 /* Return ENODEV if sysctl debug.disablefullpath==1 */ 1455 if (disablefullpath) 1456 return (ENODEV); 1457 1458 /* Construct global filesystem path from vp. */ 1459 VOP_UNLOCK(vp, 0); 1460 error = vn_fullpath_global(td, vp, &rpath, &fbuf); 1461 1462 if (error != 0) { 1463 vrele(vp); 1464 return (error); 1465 } 1466 1467 if (strlen(rpath) >= pathlen) { 1468 vrele(vp); 1469 error = ENAMETOOLONG; 1470 goto out; 1471 } 1472 1473 /* 1474 * Re-lookup the vnode by path to detect a possible rename. 1475 * As a side effect, the vnode is relocked. 1476 * If vnode was renamed, return ENOENT. 1477 */ 1478 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF | AUDITVNODE1, 1479 UIO_SYSSPACE, path, td); 1480 error = namei(&nd); 1481 if (error != 0) { 1482 vrele(vp); 1483 goto out; 1484 } 1485 NDFREE(&nd, NDF_ONLY_PNBUF); 1486 vp1 = nd.ni_vp; 1487 vrele(vp); 1488 if (vp1 == vp) 1489 strcpy(path, rpath); 1490 else { 1491 vput(vp1); 1492 error = ENOENT; 1493 } 1494 1495out: 1496 free(fbuf, M_TEMP); 1497 return (error); 1498} 1499