Page MenuHomeFreeBSD

D32635.id97382.diff
No OneTemporary

D32635.id97382.diff

diff --git a/sys/fs/nfsclient/nfs_clvnops.c.stat b/sys/fs/nfsclient/nfs_clvnops.c
--- a/sys/fs/nfsclient/nfs_clvnops.c.stat
+++ b/sys/fs/nfsclient/nfs_clvnops.c
@@ -1014,6 +1014,7 @@
struct vattr *vap = ap->a_vap;
int error = 0;
u_quad_t tsize;
+ struct timespec ts;
#ifndef nolint
tsize = (u_quad_t)0;
@@ -1108,11 +1109,18 @@
NFSUNLOCKNODE(np);
}
error = nfs_setattrrpc(vp, vap, ap->a_cred, td);
- if (error && vap->va_size != VNOVAL) {
- NFSLOCKNODE(np);
- np->n_size = np->n_vattr.na_size = tsize;
- vnode_pager_setsize(vp, tsize);
- NFSUNLOCKNODE(np);
+ if (vap->va_size != VNOVAL) {
+ if (error == 0) {
+ nanouptime(&ts);
+ NFSLOCKNODE(np);
+ np->n_localmodtime = ts;
+ NFSUNLOCKNODE(np);
+ } else {
+ NFSLOCKNODE(np);
+ np->n_size = np->n_vattr.na_size = tsize;
+ vnode_pager_setsize(vp, tsize);
+ NFSUNLOCKNODE(np);
+ }
}
return (error);
}
@@ -1169,7 +1177,7 @@
struct nfsfh *nfhp;
struct nfsvattr dnfsva, nfsva;
struct vattr vattr;
- struct timespec nctime;
+ struct timespec nctime, ts;
uint32_t openmode;
*vpp = NULLVP;
@@ -1293,6 +1301,7 @@
newvp = NULLVP;
NFSINCRGLOBAL(nfsstatsv1.lookupcache_misses);
+ nanouptime(&ts);
error = nfsrpc_lookup(dvp, cnp->cn_nameptr, cnp->cn_namelen,
cnp->cn_cred, td, &dnfsva, &nfsva, &nfhp, &attrflag, &dattrflag,
NULL, openmode);
@@ -1359,6 +1368,22 @@
if (error)
return (error);
newvp = NFSTOV(np);
+ /*
+ * If n_localmodtime >= time before RPC, then
+ * a file modification operation, such as
+ * VOP_SETATTR() of size, has occurred while
+ * the Lookup RPC and acquisition of the vnode
+ * happened. As such, the attributes might
+ * be stale, with possibly an incorrect size.
+ */
+ NFSLOCKNODE(np);
+ if (timespecisset(&np->n_localmodtime) &&
+ timespeccmp(&np->n_localmodtime, &ts, >=)) {
+ NFSCL_DEBUG(4, "nfs_lookup: rename localmod "
+ "stale attributes\n");
+ attrflag = 0;
+ }
+ NFSUNLOCKNODE(np);
if (attrflag)
(void) nfscl_loadattrcache(&newvp, &nfsva, NULL, NULL,
0, 1);
@@ -1418,6 +1443,22 @@
if (error)
return (error);
newvp = NFSTOV(np);
+ /*
+ * If n_localmodtime >= time before RPC, then
+ * a file modification operation, such as
+ * VOP_SETATTR() of size, has occurred while
+ * the Lookup RPC and acquisition of the vnode
+ * happened. As such, the attributes might
+ * be stale, with possibly an incorrect size.
+ */
+ NFSLOCKNODE(np);
+ if (timespecisset(&np->n_localmodtime) &&
+ timespeccmp(&np->n_localmodtime, &ts, >=)) {
+ NFSCL_DEBUG(4, "nfs_lookup: localmod "
+ "stale attributes\n");
+ attrflag = 0;
+ }
+ NFSUNLOCKNODE(np);
if (attrflag)
(void) nfscl_loadattrcache(&newvp, &nfsva, NULL, NULL,
0, 1);
@@ -3643,11 +3684,14 @@
struct thread *td = curthread;
struct nfsvattr nfsva;
struct nfsmount *nmp;
+ struct nfsnode *np;
off_t alen;
int attrflag, error, ret;
+ struct timespec ts;
attrflag = 0;
nmp = VFSTONFS(vp->v_mount);
+ np = VTONFS(vp);
mtx_lock(&nmp->nm_mtx);
if (NFSHASNFSV4(nmp) && nmp->nm_minorvers >= NFSV42_MINORVERSION &&
(nmp->nm_privflag & NFSMNTP_NOALLOCATE) == 0) {
@@ -3667,6 +3711,10 @@
if (error == 0) {
*ap->a_offset += alen;
*ap->a_len -= alen;
+ nanouptime(&ts);
+ NFSLOCKNODE(np);
+ np->n_localmodtime = ts;
+ NFSUNLOCKNODE(np);
} else if (error == NFSERR_NOTSUPP) {
mtx_lock(&nmp->nm_mtx);
nmp->nm_privflag |= NFSMNTP_NOALLOCATE;
@@ -3701,6 +3749,7 @@
off_t tlen, mlen;
int attrflag, error, ret;
bool clipped;
+ struct timespec ts;
error = 0;
attrflag = 0;
@@ -3743,6 +3792,10 @@
if (error == 0) {
NFSCL_DEBUG(4, "dealloc: attrflag=%d na_size=%ju\n",
attrflag, (uintmax_t)nfsva.na_size);
+ nanouptime(&ts);
+ NFSLOCKNODE(np);
+ np->n_localmodtime = ts;
+ NFSUNLOCKNODE(np);
if (attrflag != 0) {
if ((uint64_t)*ap->a_offset < nfsva.na_size)
*ap->a_offset += omin((off_t)
diff --git a/sys/fs/nfsclient/nfsnode.h.stat b/sys/fs/nfsclient/nfsnode.h
--- a/sys/fs/nfsclient/nfsnode.h.stat
+++ b/sys/fs/nfsclient/nfsnode.h
@@ -129,6 +129,7 @@
struct nfsv4node *n_v4; /* extra V4 stuff */
struct ucred *n_writecred; /* Cred. for putpages */
struct nfsclopen *n_openstateid; /* Cached open stateid */
+ struct timespec n_localmodtime; /* Last local modify */
};
#define n_atim n_un1.nf_atim

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 21, 1:07 AM (16 h, 19 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31876546
Default Alt Text
D32635.id97382.diff (4 KB)

Event Timeline