[patch] invalidate NFS attribute cache if setattr fails with
ESTALE
John Baldwin
jhb at freebsd.org
Thu Mar 12 06:58:39 PDT 2009
On Monday 09 March 2009 12:34:33 pm Rick Macklem wrote:
>
> On Mon, 9 Mar 2009, Jaakko Heinonen wrote:
>
> >
> > Hi,
> >
> > Here is a patch which changes nfs_setattrrpc() to invalidate the NFS
> > attribute cache in case the RPC failed with ESTALE.
> >
> > The issue was originally reported by Timo Sirainen in PR kern/123755:
> >
> >> NFS client: open() a file
> >> NFS server: unlink() the file
> >> NFS client: fchown() the file -> ESTALE (as expected)
> >> NFS client: fstat() the file -> success (not expected)
> >
> > %%%
> > Index: sys/nfsclient/nfs_vnops.c
> > ===================================================================
> > --- sys/nfsclient/nfs_vnops.c (revision 188842)
> > +++ sys/nfsclient/nfs_vnops.c (working copy)
> > @@ -838,6 +838,10 @@ nfs_setattrrpc(struct vnode *vp, struct
> > nfsm_loadattr(vp, NULL);
> > m_freem(mrep);
> > nfsmout:
> > + /* Invalidate the attribute cache if the NFS file handle is stale. */
> > + if (error == ESTALE)
> > + np->n_attrstamp = 0;
> > +
> > return (error);
> > }
> >
> > %%%
> >
> > Could someone take a look if this could be committed?
> >
> I'm not a committer, but I think that it might be appropriate to
> invalidate the attribute cache for any ESTALE reply from a server.
> (Since ESTALE implies that the file no linger exists on the server,
> I can't think why the attribute cache should remain valid for anything.)
>
> There is already code in nfs_request() that purges the name cache for
> ESTALE and I think that invalidating the cache there too, might make
> sense?
I think we should purge the access cache too? I just put this in my p4 branch
yesterday (it also has a merge of your changes to expand the per-node access
cache, so the access cache clearing is a bit larger than it would be
otherwise):
--- //depot/projects/smpng/sys/nfs4client/nfs4_socket.c 2008/11/03 21:11:59
+++ //depot/user/jhb/lock/nfs4client/nfs4_socket.c 2009/03/11 22:15:03
@@ -259,7 +259,7 @@
** lookup cache, just in case.
**/
if (error == ESTALE)
- cache_purge(vp);
+ nfs_purgecache(vp);
return (error);
}
--- //depot/projects/smpng/sys/nfsclient/nfs.h 2008/11/18 23:25:45
+++ //depot/user/jhb/lock/nfsclient/nfs.h 2009/03/11 22:15:03
@@ -319,6 +322,7 @@
#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 *,
--- //depot/projects/smpng/sys/nfsclient/nfs_krpc.c 2008/11/03 21:11:59
+++ //depot/user/jhb/lock/nfsclient/nfs_krpc.c 2009/03/11 22:15:03
@@ -521,7 +521,7 @@
* 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
--- //depot/projects/smpng/sys/nfsclient/nfs_socket.c 2008/11/03 21:11:59
+++ //depot/user/jhb/lock/nfsclient/nfs_socket.c 2009/03/11 22:15:03
@@ -1364,7 +1364,7 @@
* 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
--- //depot/projects/smpng/sys/nfsclient/nfs_subs.c 2008/11/03 21:11:59
+++ //depot/user/jhb/lock/nfsclient/nfs_subs.c 2009/03/11 22:15:03
@@ -826,6 +826,27 @@
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;
+ for (i = 0; i < NFS_ACCESSCACHESIZE; i++)
+ np->n_accesscache[i].stamp = 0;
+ mtx_unlock(&np->n_mtx);
+}
+
static nfsuint64 nfs_nullcookie = { { 0, 0 } };
/*
* This function finds the directory cookie that corresponds to the
--
John Baldwin
More information about the freebsd-fs
mailing list