diff options
author | peadar <peadar@FreeBSD.org> | 2004-04-14 23:23:55 +0000 |
---|---|---|
committer | peadar <peadar@FreeBSD.org> | 2004-04-14 23:23:55 +0000 |
commit | 5617193e919f277fdd23876b7881da9cc75b6a5b (patch) | |
tree | 4f111d425a38413a4e757a89c1dc965f103c6244 | |
parent | 185be4df7ac473452a43a3b4c8d2ab01c7f626b4 (diff) | |
download | FreeBSD-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.c | 4 | ||||
-rw-r--r-- | sys/nfsclient/nfs_subs.c | 11 | ||||
-rw-r--r-- | sys/nfsclient/nfsnode.h | 1 |
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 |