summaryrefslogtreecommitdiffstats
path: root/sys/nfsclient
diff options
context:
space:
mode:
authorrmacklem <rmacklem@FreeBSD.org>2012-03-03 01:06:54 +0000
committerrmacklem <rmacklem@FreeBSD.org>2012-03-03 01:06:54 +0000
commitf633984c25508041f91494b13f4fb2aa1830f4b8 (patch)
treedf54c95f923776fbae8821b12dbc69d75fa088f5 /sys/nfsclient
parentbf6ad4fe67f449a2ce5d1a3af561c1c1b658feac (diff)
downloadFreeBSD-src-f633984c25508041f91494b13f4fb2aa1830f4b8.zip
FreeBSD-src-f633984c25508041f91494b13f4fb2aa1830f4b8.tar.gz
Post r230394, the Lookup RPC counts for both NFS clients increased
significantly. Upon investigation this was caused by name cache misses for lookups of "..". For name cache entries for non-".." directories, the cache entry serves double duty. It maps both the named directory plus ".." for the parent of the directory. As such, two ctime values (one for each of the directory and its parent) need to be saved in the name cache entry. This patch adds an entry for ctime of the parent directory to the name cache. It also adds an additional uma zone for large entries with this time value, in order to minimize memory wastage. As well, it fixes a couple of cases where the mtime of the parent directory was being saved instead of ctime for positive name cache entries. With this patch, Lookup RPC counts return to values similar to pre-r230394 kernels. Reported by: bde Discussed with: kib Reviewed by: jhb MFC after: 2 weeks
Diffstat (limited to 'sys/nfsclient')
-rw-r--r--sys/nfsclient/nfs_vnops.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c
index 241af51..191ed40 100644
--- a/sys/nfsclient/nfs_vnops.c
+++ b/sys/nfsclient/nfs_vnops.c
@@ -912,7 +912,7 @@ nfs_lookup(struct vop_lookup_args *ap)
struct vnode *dvp = ap->a_dvp;
struct vnode **vpp = ap->a_vpp;
struct mount *mp = dvp->v_mount;
- struct vattr vattr;
+ struct vattr dvattr, vattr;
struct timespec nctime;
int flags = cnp->cn_flags;
struct vnode *newvp;
@@ -1129,7 +1129,7 @@ nfs_lookup(struct vop_lookup_args *ap)
}
if (v3) {
nfsm_postop_attr_va(newvp, attrflag, &vattr);
- nfsm_postop_attr(dvp, dattrflag);
+ nfsm_postop_attr_va(dvp, dattrflag, &dvattr);
} else {
nfsm_loadattr(newvp, &vattr);
attrflag = 1;
@@ -1137,9 +1137,10 @@ nfs_lookup(struct vop_lookup_args *ap)
if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
cnp->cn_flags |= SAVENAME;
if ((cnp->cn_flags & MAKEENTRY) &&
- (cnp->cn_nameiop != DELETE || !(flags & ISLASTCN)) && attrflag) {
- cache_enter_time(dvp, newvp, cnp, &vattr.va_ctime);
- }
+ (cnp->cn_nameiop != DELETE || !(flags & ISLASTCN)) &&
+ attrflag != 0 && (newvp->v_type != VDIR || dattrflag != 0))
+ cache_enter_time(dvp, newvp, cnp, &vattr.va_ctime,
+ newvp->v_type != VDIR ? NULL : &dvattr.va_ctime);
*vpp = newvp;
m_freem(mrep);
nfsmout:
@@ -1181,7 +1182,7 @@ nfsmout:
&vattr.va_mtime, ==)) {
mtx_unlock(&np->n_mtx);
cache_enter_time(dvp, NULL, cnp,
- &vattr.va_mtime);
+ &vattr.va_mtime, NULL);
} else
mtx_unlock(&np->n_mtx);
}
@@ -2463,11 +2464,11 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred)
nfsuint64 cookie;
struct nfsmount *nmp = VFSTONFS(vp->v_mount);
struct nfsnode *dnp = VTONFS(vp), *np;
- struct vattr vattr;
+ struct vattr vattr, dvattr;
nfsfh_t *fhp;
u_quad_t fileno;
int error = 0, tlen, more_dirs = 1, blksiz = 0, doit, bigenough = 1, i;
- int attrflag, fhsize;
+ int attrflag, dattrflag, fhsize;
#ifndef nolint
dp = NULL;
@@ -2513,7 +2514,7 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred)
*tl++ = txdr_unsigned(nmp->nm_readdirsize);
*tl = txdr_unsigned(nmp->nm_rsize);
nfsm_request(vp, NFSPROC_READDIRPLUS, uiop->uio_td, cred);
- nfsm_postop_attr(vp, attrflag);
+ nfsm_postop_attr_va(vp, dattrflag, &dvattr);
if (error) {
m_freem(mrep);
goto nfsmout;
@@ -2649,8 +2650,11 @@ nfs_readdirplusrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred)
md = mdsav2;
dp->d_type = IFTODT(VTTOIF(vattr.va_type));
ndp->ni_vp = newvp;
- cache_enter_time(ndp->ni_dvp, ndp->ni_vp, cnp,
- &vattr.va_ctime);
+ if (newvp->v_type != VDIR || dattrflag != 0)
+ cache_enter_time(ndp->ni_dvp, ndp->ni_vp,
+ cnp, &vattr.va_ctime,
+ newvp->v_type != VDIR ? NULL :
+ &dvattr.va_ctime);
}
} else {
/* Just skip over the file handle */
OpenPOWER on IntegriCloud