svn commit: r233326 - in stable/9: sbin/mount_nfs sys/fs/nfsclient
sys/i386/conf sys/nfsclient
John Baldwin
jhb at FreeBSD.org
Thu Mar 22 21:07:55 UTC 2012
Author: jhb
Date: Thu Mar 22 21:07:54 2012
New Revision: 233326
URL: http://svn.freebsd.org/changeset/base/233326
Log:
MFC 230547:
Add a timeout on positive name cache entries in the NFS client. That is,
we will only trust a positive name cache entry for a specified amount of
time before falling back to a LOOKUP RPC, even if the ctime for the file
handle matches the cached copy in the name cache entry. The timeout is
configured via a new 'nametimeo' mount option and defaults to 60 seconds.
It may be set to zero to disable positive name caching entirely.
Modified:
stable/9/sbin/mount_nfs/mount_nfs.8
stable/9/sys/fs/nfsclient/nfs_clvfsops.c
stable/9/sys/fs/nfsclient/nfs_clvnops.c
stable/9/sys/fs/nfsclient/nfsmount.h
stable/9/sys/nfsclient/nfs_vfsops.c
stable/9/sys/nfsclient/nfs_vnops.c
stable/9/sys/nfsclient/nfsmount.h
Directory Properties:
stable/9/sbin/mount_nfs/ (props changed)
stable/9/sys/ (props changed)
stable/9/sys/amd64/include/xen/ (props changed)
stable/9/sys/boot/ (props changed)
stable/9/sys/boot/i386/efi/ (props changed)
stable/9/sys/boot/ia64/efi/ (props changed)
stable/9/sys/boot/ia64/ski/ (props changed)
stable/9/sys/boot/powerpc/boot1.chrp/ (props changed)
stable/9/sys/boot/powerpc/ofw/ (props changed)
stable/9/sys/cddl/contrib/opensolaris/ (props changed)
stable/9/sys/conf/ (props changed)
stable/9/sys/contrib/dev/acpica/ (props changed)
stable/9/sys/contrib/octeon-sdk/ (props changed)
stable/9/sys/contrib/pf/ (props changed)
stable/9/sys/contrib/x86emu/ (props changed)
stable/9/sys/fs/ (props changed)
stable/9/sys/fs/ntfs/ (props changed)
stable/9/sys/i386/conf/XENHVM (props changed)
Modified: stable/9/sbin/mount_nfs/mount_nfs.8
==============================================================================
--- stable/9/sbin/mount_nfs/mount_nfs.8 Thu Mar 22 20:52:00 2012 (r233325)
+++ stable/9/sbin/mount_nfs/mount_nfs.8 Thu Mar 22 21:07:54 2012 (r233326)
@@ -157,6 +157,10 @@ Force the mount protocol to use UDP tran
(Necessary for some old
.Bx
servers.)
+.It Cm nametimeo Ns = Ns Aq Ar value
+Override the default of NFS_DEFAULT_NAMETIMEO for the timeout (in seconds)
+for positive name cache entries.
+If this is set to 0 it disables positive name caching for the mount point.
.It Cm negnametimeo Ns = Ns Aq Ar value
Override the default of NFS_DEFAULT_NEGNAMETIMEO for the timeout (in seconds)
for negative name cache entries. If this is set to 0 it disables negative
Modified: stable/9/sys/fs/nfsclient/nfs_clvfsops.c
==============================================================================
--- stable/9/sys/fs/nfsclient/nfs_clvfsops.c Thu Mar 22 20:52:00 2012 (r233325)
+++ stable/9/sys/fs/nfsclient/nfs_clvfsops.c Thu Mar 22 21:07:54 2012 (r233326)
@@ -104,7 +104,7 @@ static void nfs_decode_args(struct mount
static int mountnfs(struct nfs_args *, struct mount *,
struct sockaddr *, char *, u_char *, int, u_char *, int,
u_char *, int, struct vnode **, struct ucred *,
- struct thread *, int);
+ struct thread *, int, int);
static void nfs_getnlminfo(struct vnode *, uint8_t *, size_t *,
struct sockaddr_storage *, int *, off_t *,
struct timeval *);
@@ -520,7 +520,8 @@ nfs_mountdiskless(char *path,
dirlen = 0;
nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
if ((error = mountnfs(args, mp, nam, path, NULL, 0, dirpath, dirlen,
- NULL, 0, vpp, td->td_ucred, td, NFS_DEFAULT_NEGNAMETIMEO)) != 0) {
+ NULL, 0, vpp, td->td_ucred, td, NFS_DEFAULT_NAMETIMEO,
+ NFS_DEFAULT_NEGNAMETIMEO)) != 0) {
printf("nfs_mountroot: mount %s on /: %d\n", path, error);
return (error);
}
@@ -715,7 +716,7 @@ static const char *nfs_opts[] = { "from"
"retrans", "acregmin", "acregmax", "acdirmin", "acdirmax", "resvport",
"readahead", "hostname", "timeout", "addr", "fh", "nfsv3", "sec",
"principal", "nfsv4", "gssname", "allgssname", "dirpath",
- "negnametimeo", "nocto", "wcommitsize",
+ "nametimeo", "negnametimeo", "nocto", "wcommitsize",
NULL };
/*
@@ -760,6 +761,7 @@ nfs_mount(struct mount *mp)
char hst[MNAMELEN];
u_char nfh[NFSX_FHMAX], krbname[100], dirpath[100], srvkrbname[100];
char *opt, *name, *secname;
+ int nametimeo = NFS_DEFAULT_NAMETIMEO;
int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO;
int dirlen, has_nfs_args_opt, krbnamelen, srvkrbnamelen;
size_t hstlen;
@@ -968,6 +970,14 @@ nfs_mount(struct mount *mp)
}
args.flags |= NFSMNT_TIMEO;
}
+ if (vfs_getopt(mp->mnt_optnew, "nametimeo", (void **)&opt, NULL) == 0) {
+ ret = sscanf(opt, "%d", &nametimeo);
+ if (ret != 1 || nametimeo < 0) {
+ vfs_mount_error(mp, "illegal nametimeo: %s", opt);
+ error = EINVAL;
+ goto out;
+ }
+ }
if (vfs_getopt(mp->mnt_optnew, "negnametimeo", (void **)&opt, NULL)
== 0) {
ret = sscanf(opt, "%d", &negnametimeo);
@@ -1122,7 +1132,7 @@ nfs_mount(struct mount *mp)
args.fh = nfh;
error = mountnfs(&args, mp, nam, hst, krbname, krbnamelen, dirpath,
dirlen, srvkrbname, srvkrbnamelen, &vp, td->td_ucred, td,
- negnametimeo);
+ nametimeo, negnametimeo);
out:
if (!error) {
MNT_ILOCK(mp);
@@ -1166,7 +1176,7 @@ static int
mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
char *hst, u_char *krbname, int krbnamelen, u_char *dirpath, int dirlen,
u_char *srvkrbname, int srvkrbnamelen, struct vnode **vpp,
- struct ucred *cred, struct thread *td, int negnametimeo)
+ struct ucred *cred, struct thread *td, int nametimeo, int negnametimeo)
{
struct nfsmount *nmp;
struct nfsnode *np;
@@ -1233,13 +1243,14 @@ mountnfs(struct nfs_args *argp, struct m
}
vfs_getnewfsid(mp);
nmp->nm_mountp = mp;
- mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF | MTX_DUPOK);
+ mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF | MTX_DUPOK);
/*
- * Since nfs_decode_args() might optionally set them, these need to
- * set to defaults before the call, so that the optional settings
- * aren't overwritten.
+ * Since nfs_decode_args() might optionally set them, these
+ * need to be set to defaults before the call, so that the
+ * optional settings aren't overwritten.
*/
+ nmp->nm_nametimeo = nametimeo;
nmp->nm_negnametimeo = negnametimeo;
nmp->nm_timeo = NFS_TIMEO;
nmp->nm_retry = NFS_RETRANS;
Modified: stable/9/sys/fs/nfsclient/nfs_clvnops.c
==============================================================================
--- stable/9/sys/fs/nfsclient/nfs_clvnops.c Thu Mar 22 20:52:00 2012 (r233325)
+++ stable/9/sys/fs/nfsclient/nfs_clvnops.c Thu Mar 22 21:07:54 2012 (r233326)
@@ -1063,7 +1063,8 @@ nfs_lookup(struct vop_lookup_args *ap)
* We only accept a positive hit in the cache if the
* change time of the file matches our cached copy.
* Otherwise, we discard the cache entry and fallback
- * to doing a lookup RPC.
+ * to doing a lookup RPC. We also only trust cache
+ * entries for less than nm_nametimeo seconds.
*
* To better handle stale file handles and attributes,
* clear the attribute cache of this node if it is a
@@ -1085,7 +1086,8 @@ nfs_lookup(struct vop_lookup_args *ap)
mtx_unlock(&newnp->n_mtx);
}
if (nfscl_nodeleg(newvp, 0) == 0 ||
- (VOP_GETATTR(newvp, &vattr, cnp->cn_cred) == 0 &&
+ ((u_int)(ticks - ncticks) < (nmp->nm_nametimeo * hz) &&
+ VOP_GETATTR(newvp, &vattr, cnp->cn_cred) == 0 &&
timespeccmp(&vattr.va_ctime, &nctime, ==))) {
NFSINCRGLOBAL(newnfsstats.lookupcache_hits);
if (cnp->cn_nameiop != LOOKUP &&
Modified: stable/9/sys/fs/nfsclient/nfsmount.h
==============================================================================
--- stable/9/sys/fs/nfsclient/nfsmount.h Thu Mar 22 20:52:00 2012 (r233325)
+++ stable/9/sys/fs/nfsclient/nfsmount.h Thu Mar 22 21:07:54 2012 (r233326)
@@ -66,6 +66,7 @@ struct nfsmount {
u_int64_t nm_maxfilesize; /* maximum file size */
int nm_tprintf_initial_delay; /* initial delay */
int nm_tprintf_delay; /* interval for messages */
+ int nm_nametimeo; /* timeout for +ve entries (sec) */
int nm_negnametimeo; /* timeout for -ve entries (sec) */
/* Newnfs additions */
@@ -106,6 +107,10 @@ struct nfsmount {
*/
#define VFSTONFS(mp) ((struct nfsmount *)((mp)->mnt_data))
+#ifndef NFS_DEFAULT_NAMETIMEO
+#define NFS_DEFAULT_NAMETIMEO 60
+#endif
+
#ifndef NFS_DEFAULT_NEGNAMETIMEO
#define NFS_DEFAULT_NEGNAMETIMEO 60
#endif
Modified: stable/9/sys/nfsclient/nfs_vfsops.c
==============================================================================
--- stable/9/sys/nfsclient/nfs_vfsops.c Thu Mar 22 20:52:00 2012 (r233325)
+++ stable/9/sys/nfsclient/nfs_vfsops.c Thu Mar 22 21:07:54 2012 (r233326)
@@ -118,7 +118,7 @@ static void nfs_decode_args(struct mount
struct nfs_args *argp, const char *hostname);
static int mountnfs(struct nfs_args *, struct mount *,
struct sockaddr *, char *, struct vnode **,
- struct ucred *cred, int);
+ struct ucred *cred, int, int);
static void nfs_getnlminfo(struct vnode *, uint8_t *, size_t *,
struct sockaddr_storage *, int *, off_t *,
struct timeval *);
@@ -560,8 +560,8 @@ nfs_mountdiskless(char *path,
int error;
nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK);
- if ((error = mountnfs(args, mp, nam, path, vpp,
- td->td_ucred, NFS_DEFAULT_NEGNAMETIMEO)) != 0) {
+ if ((error = mountnfs(args, mp, nam, path, vpp, td->td_ucred,
+ NFS_DEFAULT_NAMETIMEO, NFS_DEFAULT_NEGNAMETIMEO)) != 0) {
printf("nfs_mountroot: mount %s on /: %d\n", path, error);
return (error);
}
@@ -789,6 +789,7 @@ static const char *nfs_opts[] = { "from"
"wsize", "rsize", "retrans", "acregmin", "acregmax", "acdirmin",
"acdirmax", "deadthresh", "hostname", "timeout", "addr", "fh", "nfsv3",
"sec", "maxgroups", "principal", "negnametimeo", "nocto", "wcommitsize",
+ "nametimeo",
NULL };
/*
@@ -837,6 +838,7 @@ nfs_mount(struct mount *mp)
size_t len;
u_char nfh[NFSX_V3FHMAX];
char *opt;
+ int nametimeo = NFS_DEFAULT_NAMETIMEO;
int negnametimeo = NFS_DEFAULT_NEGNAMETIMEO;
has_nfs_args_opt = 0;
@@ -1059,6 +1061,14 @@ nfs_mount(struct mount *mp)
}
args.flags |= NFSMNT_MAXGRPS;
}
+ if (vfs_getopt(mp->mnt_optnew, "nametimeo", (void **)&opt, NULL) == 0) {
+ ret = sscanf(opt, "%d", &nametimeo);
+ if (ret != 1 || nametimeo < 0) {
+ vfs_mount_error(mp, "illegal nametimeo: %s", opt);
+ error = EINVAL;
+ goto out;
+ }
+ }
if (vfs_getopt(mp->mnt_optnew, "negnametimeo", (void **)&opt, NULL)
== 0) {
ret = sscanf(opt, "%d", &negnametimeo);
@@ -1179,7 +1189,7 @@ nfs_mount(struct mount *mp)
goto out;
}
error = mountnfs(&args, mp, nam, args.hostname, &vp,
- curthread->td_ucred, negnametimeo);
+ curthread->td_ucred, nametimeo, negnametimeo);
out:
if (!error) {
MNT_ILOCK(mp);
@@ -1221,7 +1231,8 @@ nfs_cmount(struct mntarg *ma, void *data
*/
static int
mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
- char *hst, struct vnode **vpp, struct ucred *cred, int negnametimeo)
+ char *hst, struct vnode **vpp, struct ucred *cred, int nametimeo,
+ int negnametimeo)
{
struct nfsmount *nmp;
struct nfsnode *np;
@@ -1271,6 +1282,7 @@ mountnfs(struct nfs_args *argp, struct m
nmp->nm_numgrps = NFS_MAXGRPS;
nmp->nm_readahead = NFS_DEFRAHEAD;
nmp->nm_deadthresh = NFS_MAXDEADTHRESH;
+ nmp->nm_nametimeo = nametimeo;
nmp->nm_negnametimeo = negnametimeo;
nmp->nm_tprintf_delay = nfs_tprintf_delay;
if (nmp->nm_tprintf_delay < 0)
Modified: stable/9/sys/nfsclient/nfs_vnops.c
==============================================================================
--- stable/9/sys/nfsclient/nfs_vnops.c Thu Mar 22 20:52:00 2012 (r233325)
+++ stable/9/sys/nfsclient/nfs_vnops.c Thu Mar 22 21:07:54 2012 (r233326)
@@ -959,7 +959,8 @@ nfs_lookup(struct vop_lookup_args *ap)
* We only accept a positive hit in the cache if the
* change time of the file matches our cached copy.
* Otherwise, we discard the cache entry and fallback
- * to doing a lookup RPC.
+ * to doing a lookup RPC. We also only trust cache
+ * entries for less than nm_nametimeo seconds.
*
* To better handle stale file handles and attributes,
* clear the attribute cache of this node if it is a
@@ -980,7 +981,8 @@ nfs_lookup(struct vop_lookup_args *ap)
KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(newvp);
mtx_unlock(&newnp->n_mtx);
}
- if (VOP_GETATTR(newvp, &vattr, cnp->cn_cred) == 0 &&
+ if ((u_int)(ticks - ncticks) < (nmp->nm_nametimeo * hz) &&
+ VOP_GETATTR(newvp, &vattr, cnp->cn_cred) == 0 &&
timespeccmp(&vattr.va_ctime, &nctime, ==)) {
nfsstats.lookupcache_hits++;
if (cnp->cn_nameiop != LOOKUP &&
Modified: stable/9/sys/nfsclient/nfsmount.h
==============================================================================
--- stable/9/sys/nfsclient/nfsmount.h Thu Mar 22 20:52:00 2012 (r233325)
+++ stable/9/sys/nfsclient/nfsmount.h Thu Mar 22 21:07:54 2012 (r233326)
@@ -83,6 +83,7 @@ struct nfsmount {
struct rpc_timers nm_timers[NFS_MAX_TIMER]; /* RTT Timers for rpcs */
char nm_principal[MNAMELEN]; /* GSS-API principal of server */
gss_OID nm_mech_oid; /* OID of selected GSS-API mechanism */
+ int nm_nametimeo; /* timeout for +ve entries (sec) */
int nm_negnametimeo; /* timeout for -ve entries (sec) */
/* NFSv4 */
@@ -116,6 +117,10 @@ struct nfsmount {
#define NFS_TPRINTF_DELAY 30
#endif
+#ifndef NFS_DEFAULT_NAMETIMEO
+#define NFS_DEFAULT_NAMETIMEO 60
+#endif
+
#ifndef NFS_DEFAULT_NEGNAMETIMEO
#define NFS_DEFAULT_NEGNAMETIMEO 60
#endif
More information about the svn-src-stable-9
mailing list