summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpeadar <peadar@FreeBSD.org>2004-04-14 23:23:55 +0000
committerpeadar <peadar@FreeBSD.org>2004-04-14 23:23:55 +0000
commit5617193e919f277fdd23876b7881da9cc75b6a5b (patch)
tree4f111d425a38413a4e757a89c1dc965f103c6244
parent185be4df7ac473452a43a3b4c8d2ab01c7f626b4 (diff)
downloadFreeBSD-src-5617193e919f277fdd23876b7881da9cc75b6a5b.zip
FreeBSD-src-5617193e919f277fdd23876b7881da9cc75b6a5b.tar.gz
Let the NFS client notice a file's size changing as a modification.
This avoids presenting invalid data to the client's applications when the file is modified, and then extended within the window of the resolution of the modifcation timestamp. Reviewed By: iedowse PR: kern/64091
-rw-r--r--sys/nfsclient/nfs_bio.c4
-rw-r--r--sys/nfsclient/nfs_subs.c11
-rw-r--r--sys/nfsclient/nfsnode.h1
3 files changed, 13 insertions, 3 deletions
diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c
index 6866103..7df0531 100644
--- a/sys/nfsclient/nfs_bio.c
+++ b/sys/nfsclient/nfs_bio.c
@@ -432,13 +432,15 @@ nfs_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
error = VOP_GETATTR(vp, &vattr, cred, td);
if (error)
return (error);
- if (np->n_mtime != vattr.va_mtime.tv_sec) {
+ if ((np->n_flag & NSIZECHANGED)
+ || (np->n_mtime != vattr.va_mtime.tv_sec)) {
if (vp->v_type == VDIR)
(nmp->nm_rpcops->nr_invaldir)(vp);
error = nfs_vinvalbuf(vp, V_SAVE, cred, td, 1);
if (error)
return (error);
np->n_mtime = vattr.va_mtime.tv_sec;
+ np->n_flag &= ~NSIZECHANGED;
}
}
do {
diff --git a/sys/nfsclient/nfs_subs.c b/sys/nfsclient/nfs_subs.c
index ebdb6e8..6a3fea3 100644
--- a/sys/nfsclient/nfs_subs.c
+++ b/sys/nfsclient/nfs_subs.c
@@ -601,12 +601,19 @@ nfs_loadattrcache(struct vnode **vpp, struct mbuf **mdp, caddr_t *dposp,
vap->va_size = np->n_size;
np->n_attrstamp = 0;
} else if (np->n_flag & NMODIFIED) {
- if (vap->va_size < np->n_size)
+ /*
+ * We've modified the file: Use the larger
+ * of our size, and the server's size.
+ */
+ if (vap->va_size < np->n_size) {
vap->va_size = np->n_size;
- else
+ } else {
np->n_size = vap->va_size;
+ np->n_flag |= NSIZECHANGED;
+ }
} else {
np->n_size = vap->va_size;
+ np->n_flag |= NSIZECHANGED;
}
vnode_pager_setsize(vp, np->n_size);
} else {
diff --git a/sys/nfsclient/nfsnode.h b/sys/nfsclient/nfsnode.h
index 0877c82..893927f 100644
--- a/sys/nfsclient/nfsnode.h
+++ b/sys/nfsclient/nfsnode.h
@@ -149,6 +149,7 @@ struct nfsnode {
#define NCHG 0x0400 /* Special file times changed */
#define NCREATED 0x0800 /* Opened by nfs_create() */
#define NTRUNCATE 0x1000 /* Opened by nfs_setattr() */
+#define NSIZECHANGED 0x2000 /* File size has changed: need cache inval */
/*
* Convert between nfsnode pointers and vnode pointers
OpenPOWER on IntegriCloud