Subject: Re: NetBSD, apple fibre-channel card & 2.8TB Xserve-RAID
To: None <tech-kern@NetBSD.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: tech-kern
Date: 12/10/2004 15:49:38
> I'm going to take my own look at the code paths in question and see
> what I can see; for something like this, more eyes means a better
> chance of finding it....

I found something that looked suspicious.  I edited the relevant code,
and the directory that was acting weird is doing so no longer.

I'm now running a more thorough test - but with some 1.15TB of disk to
fill, it takes a while.  In the interim, here is the change I made, in
diff -u form.  (The kernel actually has two other patches as well, one
being the patch mycroft gave and the other being turning execute bits
on on the stack, to preserve 1.6.x binary compatability.  I'll give
those diffs below, more for completeness than anything else - I don't
think either one has anything to do with the problem.)

In this diff, the first cast, to u_int32_t, is to ensure the value is
unsigned.  If it's safe to depend on ufs_rw32 returning an unsigned
value, this cast can be removed.  The cast to daddr_t is necessary
because blkptrtodb is a macro and thus has no argument promotion
semantics.

All these diffs are relative to the 200410160000 snapshot's source/
directory.

--- /usr/src.clean/sys/ufs/ufs/ufs_bmap.c	2004-12-07 18:44:29.000000000 -0500
+++ /usr/src/sys/ufs/ufs/ufs_bmap.c	2004-12-09 18:39:11.000000000 -0500
@@ -158,7 +158,7 @@
 			*nump = 0;
 		if (ip->i_ump->um_fstype == UFS1)
 			*bnp = blkptrtodb(ump,
-			    (int32_t)ufs_rw32(ip->i_ffs1_db[bn],
+			    (daddr_t)(u_int32_t)ufs_rw32(ip->i_ffs1_db[bn],
 			    UFS_MPNEEDSWAP(vp->v_mount)));
 		else
 			*bnp = blkptrtodb(ump, ufs_rw64(ip->i_ffs2_db[bn],
@@ -169,9 +169,9 @@
 			if (ip->i_ump->um_fstype == UFS1) {
 				for (++bn; bn < NDADDR && *runp < maxrun &&
 				    is_sequential(ump,
-				        (int32_t)ufs_rw32(ip->i_ffs1_db[bn - 1],
+				        (daddr_t)(u_int32_t)ufs_rw32(ip->i_ffs1_db[bn - 1],
 				            UFS_MPNEEDSWAP(vp->v_mount)),
-				        (int32_t)ufs_rw32(ip->i_ffs1_db[bn],
+				        (daddr_t)(u_int32_t)ufs_rw32(ip->i_ffs1_db[bn],
 				            UFS_MPNEEDSWAP(vp->v_mount)));
 				    ++bn, ++*runp);
 			} else {
@@ -197,7 +197,7 @@
 
 	/* Get disk address out of indirect block array */
 	if (ip->i_ump->um_fstype == UFS1)
-		daddr = (int32_t)ufs_rw32(ip->i_ffs1_ib[xap->in_off],
+		daddr = (daddr_t)(u_int32_t)ufs_rw32(ip->i_ffs1_ib[xap->in_off],
 		    UFS_MPNEEDSWAP(vp->v_mount));
 	else
 		daddr = ufs_rw64(ip->i_ffs2_ib[xap->in_off],
@@ -252,7 +252,7 @@
 			}
 		}
 		if (ip->i_ump->um_fstype == UFS1) {
-			daddr = (int32_t)ufs_rw32(
+			daddr = (daddr_t)(u_int32_t)ufs_rw32(
 			    ((int32_t *)bp->b_data)[xap->in_off],
 			    UFS_MPNEEDSWAP(mp));
 			if (num == 1 && runp) {

And here are those other two patches:

--- /usr/src.clean/sys/kern/exec_subr.c	2004-12-07 18:44:23.000000000 -0500
+++ /usr/src/sys/kern/exec_subr.c	2004-12-09 17:41:52.000000000 -0500
@@ -344,7 +344,7 @@
 	}
 	KASSERT(access_size > 0);
 	NEW_VMCMD(&epp->ep_vmcmds, vmcmd_map_zero, access_size,
-	    access_linear_min, NULL, 0, VM_PROT_READ | VM_PROT_WRITE);
+	    access_linear_min, NULL, 0, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
 
 	return 0;
 }
--- /usr/src.clean/sys/ufs/ffs/ffs_balloc.c	2004-12-07 18:44:29.000000000 -0500
+++ /usr/src/sys/ufs/ffs/ffs_balloc.c	2004-12-09 18:09:12.000000000 -0500
@@ -103,13 +103,12 @@
 	int size;
 	struct ucred *cred;
 	int flags;
-	int32_t nb;
 	struct buf *bp, *nbp;
 	struct vnode *vp = ap->a_vp;
 	struct inode *ip = VTOI(vp);
 	struct fs *fs = ip->i_fs;
 	struct indir indirs[NIADDR + 2];
-	daddr_t newb, pref;
+	daddr_t newb, pref, nb;
 	int32_t *bap;	/* XXX ondisk32 */
 	int deallocated, osize, nsize, num, i, error;
 	int32_t *blkp, *allocblk, allociblk[NIADDR + 1];

/~\ The ASCII				der Mouse
\ / Ribbon Campaign
 X  Against HTML	       mouse@rodents.montreal.qc.ca
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B