aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2009-04-06 21:11:08 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2009-04-06 21:11:08 +0000
commit34291180950a826179fbf2487969854351af4fee (patch)
tree5e08b13a6dd5b15ec4434f2c646d5ecce89ada39
parent6e57ff1890a629e39d2d24280626d6b6e362be76 (diff)
downloadsrc-34291180950a826179fbf2487969854351af4fee.tar.gz
src-34291180950a826179fbf2487969854351af4fee.zip
When a stale file handle is encountered, purge all cached information about
an NFS node including the access and attribute caches. Previously the NFS client only purged any name cache entries associated with the file. PR: kern/123755 Submitted by: Jaakko Heinonen jh of saunalahti fi Reported by: Timo Sirainen tss of iki fi Reviewed by: rwatson, rmacklem MFC after: 1 month
Notes
Notes: svn path=/head/; revision=190785
-rw-r--r--sys/nfs4client/nfs4_socket.c2
-rw-r--r--sys/nfsclient/nfs.h1
-rw-r--r--sys/nfsclient/nfs_krpc.c2
-rw-r--r--sys/nfsclient/nfs_socket.c2
-rw-r--r--sys/nfsclient/nfs_subs.c23
5 files changed, 27 insertions, 3 deletions
diff --git a/sys/nfs4client/nfs4_socket.c b/sys/nfs4client/nfs4_socket.c
index 754ba479176e..c1fe15412962 100644
--- a/sys/nfs4client/nfs4_socket.c
+++ b/sys/nfs4client/nfs4_socket.c
@@ -259,7 +259,7 @@ nfs4_request(struct vnode *vp, struct mbuf *mrest, int procnum,
** lookup cache, just in case.
**/
if (error == ESTALE)
- cache_purge(vp);
+ nfs_purgecache(vp);
return (error);
}
diff --git a/sys/nfsclient/nfs.h b/sys/nfsclient/nfs.h
index df939521607e..4dce2fe03464 100644
--- a/sys/nfsclient/nfs.h
+++ b/sys/nfsclient/nfs.h
@@ -322,6 +322,7 @@ void nfs_down(struct nfsreq *, struct nfsmount *, struct thread *,
#endif /* ! NFS4_USE_RPCCLNT */
#endif
+void nfs_purgecache(struct vnode *);
int nfs_vinvalbuf(struct vnode *, int, struct thread *, int);
int nfs_readrpc(struct vnode *, struct uio *, struct ucred *);
int nfs_writerpc(struct vnode *, struct uio *, struct ucred *, int *,
diff --git a/sys/nfsclient/nfs_krpc.c b/sys/nfsclient/nfs_krpc.c
index 8f3f12414828..767dc0f3c69f 100644
--- a/sys/nfsclient/nfs_krpc.c
+++ b/sys/nfsclient/nfs_krpc.c
@@ -557,7 +557,7 @@ tryagain:
* cache, just in case.
*/
if (error == ESTALE)
- cache_purge(vp);
+ nfs_purgecache(vp);
/*
* Skip wcc data on NFS errors for now. NetApp filers
* return corrupt postop attrs in the wcc data for NFS
diff --git a/sys/nfsclient/nfs_socket.c b/sys/nfsclient/nfs_socket.c
index a61962fc138c..8057604e364d 100644
--- a/sys/nfsclient/nfs_socket.c
+++ b/sys/nfsclient/nfs_socket.c
@@ -1364,7 +1364,7 @@ wait_for_pinned_req:
* lookup cache, just in case.
*/
if (error == ESTALE)
- cache_purge(vp);
+ nfs_purgecache(vp);
/*
* Skip wcc data on NFS errors for now. NetApp filers return corrupt
* postop attrs in the wcc data for NFS err EROFS. Not sure if they
diff --git a/sys/nfsclient/nfs_subs.c b/sys/nfsclient/nfs_subs.c
index e9b7f35b971c..1453dbf826cf 100644
--- a/sys/nfsclient/nfs_subs.c
+++ b/sys/nfsclient/nfs_subs.c
@@ -865,6 +865,29 @@ nfs_getattrcache(struct vnode *vp, struct vattr *vaper)
return (0);
}
+/*
+ * Purge all cached information about an NFS vnode including name
+ * cache entries, the attribute cache, and the access cache. This is
+ * called when an NFS request for a node fails with a stale
+ * filehandle.
+ */
+void
+nfs_purgecache(struct vnode *vp)
+{
+ struct nfsnode *np;
+ int i;
+
+ np = VTONFS(vp);
+ cache_purge(vp);
+ mtx_lock(&np->n_mtx);
+ np->n_attrstamp = 0;
+ KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(vp);
+ for (i = 0; i < NFS_ACCESSCACHESIZE; i++)
+ np->n_accesscache[i].stamp = 0;
+ KDTRACE_NFS_ACCESSCACHE_FLUSH_DONE(vp);
+ mtx_unlock(&np->n_mtx);
+}
+
static nfsuint64 nfs_nullcookie = { { 0, 0 } };
/*
* This function finds the directory cookie that corresponds to the