From 79e5012ee8e7f9b807b05508d366e196ee6d62b6 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Fri, 23 Apr 2004 18:01:07 +0000 Subject: [PATCH] Fix a client tail -f vs server-appended file data corruption case by invalidating client-side cached data on detection of a server based file size change. Taken-from: FreeBSD-5 Patch-Prepared-by: Chris Pressey --- sys/vfs/nfs/nfs_bio.c | 8 +++++--- sys/vfs/nfs/nfs_subs.c | 15 +++++++++++---- sys/vfs/nfs/nfsnode.h | 5 +++-- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/sys/vfs/nfs/nfs_bio.c b/sys/vfs/nfs/nfs_bio.c index 8b86902052..15a801826f 100644 --- a/sys/vfs/nfs/nfs_bio.c +++ b/sys/vfs/nfs/nfs_bio.c @@ -34,8 +34,8 @@ * SUCH DAMAGE. * * @(#)nfs_bio.c 8.9 (Berkeley) 3/30/95 - * $FreeBSD: src/sys/nfs/nfs_bio.c,v 1.83.2.4 2002/12/29 18:19:53 dillon Exp $ - * $DragonFly: src/sys/vfs/nfs/nfs_bio.c,v 1.13 2004/04/19 16:33:49 cpressey Exp $ + * $FreeBSD: /repoman/r/ncvs/src/sys/nfsclient/nfs_bio.c,v 1.130 2004/04/14 23:23:55 peadar Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs_bio.c,v 1.14 2004/04/23 18:01:07 dillon Exp $ */ @@ -385,13 +385,15 @@ nfs_bioread(struct vnode *vp, struct uio *uio, int ioflag) error = VOP_GETATTR(vp, &vattr, 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) nfs_invaldir(vp); error = nfs_vinvalbuf(vp, V_SAVE, td, 1); if (error) return (error); np->n_mtime = vattr.va_mtime.tv_sec; + np->n_flag &= ~NSIZECHANGED; } } } diff --git a/sys/vfs/nfs/nfs_subs.c b/sys/vfs/nfs/nfs_subs.c index c547913984..b542be1479 100644 --- a/sys/vfs/nfs/nfs_subs.c +++ b/sys/vfs/nfs/nfs_subs.c @@ -34,8 +34,8 @@ * SUCH DAMAGE. * * @(#)nfs_subs.c 8.8 (Berkeley) 5/22/95 - * $FreeBSD: src/sys/nfs/nfs_subs.c,v 1.90.2.2 2001/10/25 19:18:53 dillon Exp $ - * $DragonFly: src/sys/vfs/nfs/nfs_subs.c,v 1.14 2004/04/19 16:33:49 cpressey Exp $ + * $FreeBSD: /repoman/r/ncvs/src/sys/nfsclient/nfs_subs.c,v 1.128 2004/04/14 23:23:55 peadar Exp $ + * $DragonFly: src/sys/vfs/nfs/nfs_subs.c,v 1.15 2004/04/23 18:01:07 dillon Exp $ */ /* @@ -1297,12 +1297,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/vfs/nfs/nfsnode.h b/sys/vfs/nfs/nfsnode.h index be78c77d4f..5bad8a7163 100644 --- a/sys/vfs/nfs/nfsnode.h +++ b/sys/vfs/nfs/nfsnode.h @@ -34,8 +34,8 @@ * SUCH DAMAGE. * * @(#)nfsnode.h 8.9 (Berkeley) 5/14/95 - * $FreeBSD: src/sys/nfs/nfsnode.h,v 1.32.2.1 2001/06/26 04:20:11 bp Exp $ - * $DragonFly: src/sys/vfs/nfs/nfsnode.h,v 1.6 2003/10/10 22:01:13 dillon Exp $ + * $FreeBSD: /repoman/r/ncvs/src/sys/nfsclient/nfsnode.h,v 1.43 2004/04/14 23:23:55 peadar Exp $ + * $DragonFly: src/sys/vfs/nfs/nfsnode.h,v 1.7 2004/04/23 18:01:07 dillon Exp $ */ @@ -150,6 +150,7 @@ struct nfsnode { #define NCHG 0x0400 /* Special file times changed */ #define NLOCKED 0x0800 /* node is locked */ #define NWANTED 0x0100 /* someone wants to lock */ +#define NSIZECHANGED 0x2000 /* File size has changed: need cache inval */ /* * Convert between nfsnode pointers and vnode pointers -- 2.41.0