diff options
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/vfs_cache.c | 66 |
1 files changed, 58 insertions, 8 deletions
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c index e4de804..aa269de 100644 --- a/sys/kern/vfs_cache.c +++ b/sys/kern/vfs_cache.c @@ -97,6 +97,8 @@ struct namecache { TAILQ_ENTRY(namecache) nc_dst; /* destination vnode list */ struct vnode *nc_dvp; /* vnode of parent of name */ struct vnode *nc_vp; /* vnode the name refers to */ + struct timespec nc_time; /* timespec provided by fs */ + int nc_ticks; /* ticks value when entry was added */ u_char nc_flag; /* flag bits */ u_char nc_nlen; /* length of name */ char nc_name[0]; /* segment name + nul */ @@ -394,10 +396,12 @@ cache_zap(ncp) */ int -cache_lookup(dvp, vpp, cnp) +cache_lookup_times(dvp, vpp, cnp, tsp, ticksp) struct vnode *dvp; struct vnode **vpp; struct componentname *cnp; + struct timespec *tsp; + int *ticksp; { struct namecache *ncp; uint32_t hash; @@ -422,6 +426,10 @@ retry_wlocked: dothits++; SDT_PROBE(vfs, namecache, lookup, hit, dvp, ".", *vpp, 0, 0); + if (tsp != NULL) + timespecclear(tsp); + if (ticksp != NULL) + *ticksp = ticks; goto success; } if (cnp->cn_namelen == 2 && cnp->cn_nameptr[1] == '.') { @@ -440,19 +448,22 @@ retry_wlocked: CACHE_WUNLOCK(); return (0); } - if (dvp->v_cache_dd->nc_flag & NCF_ISDOTDOT) - *vpp = dvp->v_cache_dd->nc_vp; + ncp = dvp->v_cache_dd; + if (ncp->nc_flag & NCF_ISDOTDOT) + *vpp = ncp->nc_vp; else - *vpp = dvp->v_cache_dd->nc_dvp; + *vpp = ncp->nc_dvp; /* Return failure if negative entry was found. */ - if (*vpp == NULL) { - ncp = dvp->v_cache_dd; + if (*vpp == NULL) goto negative_success; - } CTR3(KTR_VFS, "cache_lookup(%p, %s) found %p via ..", dvp, cnp->cn_nameptr, *vpp); SDT_PROBE(vfs, namecache, lookup, hit, dvp, "..", *vpp, 0, 0); + if (tsp != NULL) + *tsp = ncp->nc_time; + if (ticksp != NULL) + *ticksp = ncp->nc_ticks; goto success; } } @@ -499,6 +510,10 @@ retry_wlocked: dvp, cnp->cn_nameptr, *vpp, ncp); SDT_PROBE(vfs, namecache, lookup, hit, dvp, ncp->nc_name, *vpp, 0, 0); + if (tsp != NULL) + *tsp = ncp->nc_time; + if (ticksp != NULL) + *ticksp = ncp->nc_ticks; goto success; } @@ -530,6 +545,10 @@ negative_success: cnp->cn_flags |= ISWHITEOUT; SDT_PROBE(vfs, namecache, lookup, hit_negative, dvp, ncp->nc_name, 0, 0, 0); + if (tsp != NULL) + *tsp = ncp->nc_time; + if (ticksp != NULL) + *ticksp = ncp->nc_ticks; CACHE_WUNLOCK(); return (ENOENT); @@ -616,10 +635,11 @@ unlock: * Add an entry to the cache. */ void -cache_enter(dvp, vp, cnp) +cache_enter_time(dvp, vp, cnp, tsp) struct vnode *dvp; struct vnode *vp; struct componentname *cnp; + struct timespec *tsp; { struct namecache *ncp, *n2; struct nchashhead *ncpp; @@ -692,6 +712,11 @@ cache_enter(dvp, vp, cnp) ncp->nc_vp = vp; ncp->nc_dvp = dvp; ncp->nc_flag = flag; + if (tsp != NULL) + ncp->nc_time = *tsp; + else + timespecclear(&ncp->nc_time); + ncp->nc_ticks = ticks; len = ncp->nc_nlen = cnp->cn_namelen; hash = fnv_32_buf(cnp->cn_nameptr, len, FNV1_32_INIT); strlcpy(ncp->nc_name, cnp->cn_nameptr, len + 1); @@ -708,6 +733,8 @@ cache_enter(dvp, vp, cnp) if (n2->nc_dvp == dvp && n2->nc_nlen == cnp->cn_namelen && !bcmp(n2->nc_name, cnp->cn_nameptr, n2->nc_nlen)) { + n2->nc_time = ncp->nc_time; + n2->nc_ticks = ncp->nc_ticks; CACHE_WUNLOCK(); cache_free(ncp); return; @@ -1280,6 +1307,29 @@ vn_commname(struct vnode *vp, char *buf, u_int buflen) return (0); } +/* ABI compat shims for old kernel modules. */ +#undef cache_enter +#undef cache_lookup + +void cache_enter(struct vnode *dvp, struct vnode *vp, + struct componentname *cnp); +int cache_lookup(struct vnode *dvp, struct vnode **vpp, + struct componentname *cnp); + +void +cache_enter(struct vnode *dvp, struct vnode *vp, struct componentname *cnp) +{ + + cache_enter_time(dvp, vp, cnp, NULL); +} + +int +cache_lookup(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp) +{ + + return (cache_lookup_times(dvp, vpp, cnp, NULL, NULL)); +} + /* * This function updates path string to vnode's full global path * and checks the size of the new path string against the pathlen argument. |