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
This commit is contained in:
peadar 2004-04-14 23:23:55 +00:00
parent 185be4df7a
commit 5617193e91
3 changed files with 13 additions and 3 deletions

View File

@ -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 {

View File

@ -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 {

View File

@ -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