Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 12 Dec 2001 17:51:31 -0800 (PST)
From:      Matthew Dillon <dillon@apollo.backplane.com>
To:        Peter Wemm <peter@wemm.org>
Cc:        Jordan Hubbard <jkh@winston.freebsd.org>, Mike Smith <msmith@FreeBSD.ORG>, hackers@FreeBSD.ORG, msmith@mass.dis.org
Subject:   Re: NFS: How to make FreeBSD fall on its face in one easy step 
Message-ID:  <200112130151.fBD1pVG27177@apollo.backplane.com>
References:   <20011213011344.CBDD03810@overcee.netplex.com.au>

next in thread | previous in thread | raw e-mail | index | archive | help
    I found a second bug... nfs truncation code race.

    I've enclosed both patches below.  NFS truncation race first, softupdates
    bug second.   The patches are against -stable.

    There are still more bugs... the nfstest code is seeing data corruption
    on read.  It looks like another truncation bug.  I'm tracking it down.

						-Matt

Index: nfs/nfs_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/nfs/Attic/nfs_vnops.c,v
retrieving revision 1.150.2.4
diff -u -r1.150.2.4 nfs_vnops.c
--- nfs/nfs_vnops.c	2001/08/05 00:23:58	1.150.2.4
+++ nfs/nfs_vnops.c	2001/12/13 01:42:15
@@ -710,6 +710,15 @@
 			 */
 			if (vp->v_mount->mnt_flag & MNT_RDONLY)
 				return (EROFS);
+
+			/*
+			 * We run vnode_pager_setsize() early (why?),
+			 * we must set np->n_size now to avoid vinvalbuf
+			 * V_SAVE races that might setsize a lower
+			 * value.
+			 */
+ 			tsize = np->n_size;
+ 			np->n_size = vap->va_size;
 			vnode_pager_setsize(vp, vap->va_size);
  			if (np->n_flag & NMODIFIED) {
  			    if (vap->va_size == 0)
@@ -719,12 +728,12 @@
  				error = nfs_vinvalbuf(vp, V_SAVE,
  					ap->a_cred, ap->a_p, 1);
  			    if (error) {
+				np->n_size = tsize;
 				vnode_pager_setsize(vp, np->n_size);
  				return (error);
 			    }
  			}
- 			tsize = np->n_size;
- 			np->n_size = np->n_vattr.va_size = vap->va_size;
+			np->n_vattr.va_size = vap->va_size;
   		};
   	} else if ((vap->va_mtime.tv_sec != VNOVAL ||
 		vap->va_atime.tv_sec != VNOVAL) && (np->n_flag & NMODIFIED) &&
Index: ufs/ffs/ffs_inode.c
===================================================================
RCS file: /home/ncvs/src/sys/ufs/ffs/ffs_inode.c,v
retrieving revision 1.56.2.3
diff -u -r1.56.2.3 ffs_inode.c
--- ufs/ffs/ffs_inode.c	2001/11/20 20:27:27	1.56.2.3
+++ ufs/ffs/ffs_inode.c	2001/12/12 23:43:36
@@ -244,6 +244,10 @@
 		if (error) {
 			return (error);
 		}
+		if (length > 0 && DOINGSOFTDEP(ovp)) {
+			if ((error = VOP_FSYNC(ovp, cred, MNT_WAIT, p)) != 0)
+				return (error);
+		}
 		oip->i_size = length;
 		size = blksize(fs, oip, lbn);
 		if (ovp->v_type != VDIR)
@@ -359,6 +363,10 @@
 		if (newspace == 0)
 			panic("ffs_truncate: newspace");
 		if (oldspace - newspace > 0) {
+			/*
+			 * XXX Softupdates, adjust queued directblock
+			 *     in place rather then the second FSYNC above?
+			 */
 			/*
 			 * Block number of space to be free'd is
 			 * the old block # plus the number of frags

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200112130151.fBD1pVG27177>