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>
index | next in thread | previous in thread | raw e-mail
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
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200112130151.fBD1pVG27177>
