Module Name:    src
Committed By:   dholland
Date:           Tue Jul 12 02:22:14 UTC 2011

Modified Files:
        src/sys/ufs/ext2fs: ext2fs_lookup.c
        src/sys/ufs/ufs: inode.h ufs_lookup.c ufs_vnops.c ufs_wapbl.c

Log Message:
Currently, ufs_lookup produces five auxiliary results that are left in
the vnode when lookup returns and fished out again later.

1. Create struct ufs_lookup_results to hold these.

2. Call the ufs_lookup_results instance in struct inode "i_crap" to be
clear about exactly what's going on, and to distinguish the lookup
results from respectable members of struct inode.

3. Update references to these members in the directory access
subroutines.

4. Include preliminary infrastructure for checking that the i_crap
being used is still valid when it's used. This doesn't actually do
anything yet.

5. Update the way ufs_wapbl_rename manipulates these elements to use
the new data structures. I have not changed the manipulation; it may
or may not be correct but I continue to suspect that it is not.

The word of the day is "stigmergy".


To generate a diff of this commit:
cvs rdiff -u -r1.64 -r1.65 src/sys/ufs/ext2fs/ext2fs_lookup.c
cvs rdiff -u -r1.57 -r1.58 src/sys/ufs/ufs/inode.h
cvs rdiff -u -r1.107 -r1.108 src/sys/ufs/ufs/ufs_lookup.c
cvs rdiff -u -r1.190 -r1.191 src/sys/ufs/ufs/ufs_vnops.c
cvs rdiff -u -r1.13 -r1.14 src/sys/ufs/ufs/ufs_wapbl.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/ufs/ext2fs/ext2fs_lookup.c
diff -u src/sys/ufs/ext2fs/ext2fs_lookup.c:1.64 src/sys/ufs/ext2fs/ext2fs_lookup.c:1.65
--- src/sys/ufs/ext2fs/ext2fs_lookup.c:1.64	Mon Jul 11 08:27:39 2011
+++ src/sys/ufs/ext2fs/ext2fs_lookup.c	Tue Jul 12 02:22:13 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ext2fs_lookup.c,v 1.64 2011/07/11 08:27:39 hannken Exp $	*/
+/*	$NetBSD: ext2fs_lookup.c,v 1.65 2011/07/12 02:22:13 dholland Exp $	*/
 
 /*
  * Modified for NetBSD 1.2E
@@ -48,7 +48,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_lookup.c,v 1.64 2011/07/11 08:27:39 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_lookup.c,v 1.65 2011/07/12 02:22:13 dholland Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -290,6 +290,7 @@
 	struct ufsmount *ump = dp->i_ump;
 	int dirblksiz = ump->um_dirblksiz;
 	ino_t foundino;
+	struct ufs_lookup_results *results;
 
 	flags = cnp->cn_flags;
 
@@ -298,6 +299,14 @@
 	*vpp = NULL;
 
 	/*
+	 * Produce the auxiliary lookup results into i_crap. Increment
+	 * its serial number so elsewhere we can tell if we're using
+	 * stale results. This should not be done this way. XXX.
+	 */
+	results = &dp->i_crap;
+	dp->i_crapcounter++;
+
+	/*
 	 * Check accessiblity of directory.
 	 */
 	if ((error = VOP_ACCESS(vdp, VEXEC, cred)) != 0)
@@ -343,34 +352,34 @@
 	 * of simplicity.
 	 */
 	bmask = vdp->v_mount->mnt_stat.f_iosize - 1;
-	if (nameiop != LOOKUP || dp->i_diroff == 0 ||
-	    dp->i_diroff >= ext2fs_size(dp)) {
+	if (nameiop != LOOKUP || results->ulr_diroff == 0 ||
+	    results->ulr_diroff >= ext2fs_size(dp)) {
 		entryoffsetinblock = 0;
-		dp->i_offset = 0;
+		results->ulr_offset = 0;
 		numdirpasses = 1;
 	} else {
-		dp->i_offset = dp->i_diroff;
-		if ((entryoffsetinblock = dp->i_offset & bmask) &&
-		    (error = ext2fs_blkatoff(vdp, (off_t)dp->i_offset, NULL, &bp)))
+		results->ulr_offset = results->ulr_diroff;
+		if ((entryoffsetinblock = results->ulr_offset & bmask) &&
+		    (error = ext2fs_blkatoff(vdp, (off_t)results->ulr_offset, NULL, &bp)))
 			return (error);
 		numdirpasses = 2;
 		nchstats.ncs_2passes++;
 	}
-	prevoff = dp->i_offset;
+	prevoff = results->ulr_offset;
 	endsearch = roundup(ext2fs_size(dp), dirblksiz);
 	enduseful = 0;
 
 searchloop:
-	while (dp->i_offset < endsearch) {
+	while (results->ulr_offset < endsearch) {
 		if (curcpu()->ci_schedstate.spc_flags & SPCF_SHOULDYIELD)
 			preempt();
 		/*
 		 * If necessary, get the next directory block.
 		 */
-		if ((dp->i_offset & bmask) == 0) {
+		if ((results->ulr_offset & bmask) == 0) {
 			if (bp != NULL)
 				brelse(bp, 0);
-			error = ext2fs_blkatoff(vdp, (off_t)dp->i_offset, NULL,
+			error = ext2fs_blkatoff(vdp, (off_t)results->ulr_offset, NULL,
 			    &bp);
 			if (error != 0)
 				return (error);
@@ -400,9 +409,9 @@
 		     ext2fs_dirbadentry(vdp, ep, entryoffsetinblock))) {
 			int i;
 
-			ufs_dirbad(dp, dp->i_offset, "mangled entry");
+			ufs_dirbad(dp, results->ulr_offset, "mangled entry");
 			i = dirblksiz - (entryoffsetinblock & (dirblksiz - 1));
-			dp->i_offset += i;
+			results->ulr_offset += i;
 			entryoffsetinblock += i;
 			continue;
 		}
@@ -421,15 +430,15 @@
 			if (size > 0) {
 				if (size >= slotneeded) {
 					slotstatus = FOUND;
-					slotoffset = dp->i_offset;
+					slotoffset = results->ulr_offset;
 					slotsize = fs2h16(ep->e2d_reclen);
 				} else if (slotstatus == NONE) {
 					slotfreespace += size;
 					if (slotoffset == -1)
-						slotoffset = dp->i_offset;
+						slotoffset = results->ulr_offset;
 					if (slotfreespace >= slotneeded) {
 						slotstatus = COMPACT;
-						slotsize = dp->i_offset +
+						slotsize = results->ulr_offset +
 						    fs2h16(ep->e2d_reclen) -
 						    slotoffset;
 					}
@@ -451,15 +460,15 @@
 				 * directory buffer.
 				 */
 				foundino = fs2h32(ep->e2d_ino);
-				dp->i_reclen = fs2h16(ep->e2d_reclen);
+				results->ulr_reclen = fs2h16(ep->e2d_reclen);
 				goto found;
 			}
 		}
-		prevoff = dp->i_offset;
-		dp->i_offset += fs2h16(ep->e2d_reclen);
+		prevoff = results->ulr_offset;
+		results->ulr_offset += fs2h16(ep->e2d_reclen);
 		entryoffsetinblock += fs2h16(ep->e2d_reclen);
 		if (ep->e2d_ino)
-			enduseful = dp->i_offset;
+			enduseful = results->ulr_offset;
 	}
 /* notfound: */
 	/*
@@ -468,8 +477,8 @@
 	 */
 	if (numdirpasses == 2) {
 		numdirpasses--;
-		dp->i_offset = 0;
-		endsearch = dp->i_diroff;
+		results->ulr_offset = 0;
+		endsearch = results->ulr_diroff;
 		goto searchloop;
 	}
 	if (bp != NULL)
@@ -491,23 +500,23 @@
 		/*
 		 * Return an indication of where the new directory
 		 * entry should be put.  If we didn't find a slot,
-		 * then set dp->i_count to 0 indicating
+		 * then set results->ulr_count to 0 indicating
 		 * that the new slot belongs at the end of the
 		 * directory. If we found a slot, then the new entry
-		 * can be put in the range from dp->i_offset to
-		 * dp->i_offset + dp->i_count.
+		 * can be put in the range from results->ulr_offset to
+		 * results->ulr_offset + results->ulr_count.
 		 */
 		if (slotstatus == NONE) {
-			dp->i_offset = roundup(ext2fs_size(dp), dirblksiz);
-			dp->i_count = 0;
-			enduseful = dp->i_offset;
+			results->ulr_offset = roundup(ext2fs_size(dp), dirblksiz);
+			results->ulr_count = 0;
+			enduseful = results->ulr_offset;
 		} else {
-			dp->i_offset = slotoffset;
-			dp->i_count = slotsize;
+			results->ulr_offset = slotoffset;
+			results->ulr_count = slotsize;
 			if (enduseful < slotoffset + slotsize)
 				enduseful = slotoffset + slotsize;
 		}
-		dp->i_endoff = roundup(enduseful, dirblksiz);
+		results->ulr_endoff = roundup(enduseful, dirblksiz);
 #if 0
 		dp->i_flag |= IN_CHANGE | IN_UPDATE;
 #endif
@@ -538,10 +547,10 @@
 	 * Check that directory length properly reflects presence
 	 * of this entry.
 	 */
-	if (dp->i_offset + EXT2FS_DIRSIZ(ep->e2d_namlen) > ext2fs_size(dp)) {
-		ufs_dirbad(dp, dp->i_offset, "i_size too small");
+	if (results->ulr_offset + EXT2FS_DIRSIZ(ep->e2d_namlen) > ext2fs_size(dp)) {
+		ufs_dirbad(dp, results->ulr_offset, "i_size too small");
 		error = ext2fs_setsize(dp,
-				dp->i_offset + EXT2FS_DIRSIZ(ep->e2d_namlen));
+				results->ulr_offset + EXT2FS_DIRSIZ(ep->e2d_namlen));
 		if (error) {
 			brelse(bp, 0);
 			return (error);
@@ -557,7 +566,7 @@
 	 * in the cache as to where the entry was found.
 	 */
 	if ((flags & ISLASTCN) && nameiop == LOOKUP)
-		dp->i_diroff = dp->i_offset &~ (dirblksiz - 1);
+		results->ulr_diroff = results->ulr_offset &~ (dirblksiz - 1);
 
 	/*
 	 * If deleting, and at end of pathname, return
@@ -571,15 +580,15 @@
 		if ((error = VOP_ACCESS(vdp, VWRITE, cred)) != 0)
 			return (error);
 		/*
-		 * Return pointer to current entry in dp->i_offset,
+		 * Return pointer to current entry in results->ulr_offset,
 		 * and distance past previous entry (if there
-		 * is a previous entry in this block) in dp->i_count.
+		 * is a previous entry in this block) in results->ulr_count.
 		 * Save directory inode pointer in ndp->ni_dvp for dirremove().
 		 */
-		if ((dp->i_offset & (dirblksiz - 1)) == 0)
-			dp->i_count = 0;
+		if ((results->ulr_offset & (dirblksiz - 1)) == 0)
+			results->ulr_count = 0;
 		else
-			dp->i_count = dp->i_offset - prevoff;
+			results->ulr_count = results->ulr_offset - prevoff;
 		if (dp->i_number == foundino) {
 			vref(vdp);
 			*vpp = vdp;
@@ -734,7 +743,7 @@
  * that it left in nameidata.  The argument ip is the inode which the new
  * directory entry will refer to.  Dvp is a pointer to the directory to
  * be written, which was left locked by namei. Remaining parameters
- * (dp->i_offset, dp->i_count) indicate how the space for the new
+ * (ulr_offset, ulr_count) indicate how the space for the new
  * entry is to be obtained.
  */
 int
@@ -751,8 +760,13 @@
 	char *dirbuf;
 	struct ufsmount *ump = VFSTOUFS(dvp->v_mount);
 	int dirblksiz = ump->um_dirblksiz;
+	struct ufs_lookup_results *ulr;
 
 	dp = VTOI(dvp);
+
+	ulr = &dp->i_crap;
+	UFS_CHECK_CRAPCOUNTER(dp);
+
 	newdir.e2d_ino = h2fs32(ip->i_number);
 	newdir.e2d_namlen = cnp->cn_namelen;
 	if (ip->i_e2fs->e2fs.e2fs_rev > E2FS_REV0 &&
@@ -763,16 +777,16 @@
 	}
 	memcpy(newdir.e2d_name, cnp->cn_nameptr, (unsigned)cnp->cn_namelen + 1);
 	newentrysize = EXT2FS_DIRSIZ(cnp->cn_namelen);
-	if (dp->i_count == 0) {
+	if (ulr->ulr_count == 0) {
 		/*
-		 * If dp->i_count is 0, then namei could find no
-		 * space in the directory. Here, dp->i_offset will
+		 * If ulr_count is 0, then namei could find no
+		 * space in the directory. Here, ulr_offset will
 		 * be on a directory block boundary and we will write the
 		 * new entry into a fresh block.
 		 */
-		if (dp->i_offset & (dirblksiz - 1))
+		if (ulr->ulr_offset & (dirblksiz - 1))
 			panic("ext2fs_direnter: newblk");
-		auio.uio_offset = dp->i_offset;
+		auio.uio_offset = ulr->ulr_offset;
 		newdir.e2d_reclen = h2fs16(dirblksiz);
 		auio.uio_resid = newentrysize;
 		aiov.iov_len = newentrysize;
@@ -797,9 +811,9 @@
 	}
 
 	/*
-	 * If dp->i_count is non-zero, then namei found space
-	 * for the new entry in the range dp->i_offset to
-	 * dp->i_offset + dp->i_count in the directory.
+	 * If ulr_count is non-zero, then namei found space
+	 * for the new entry in the range ulr_offset to
+	 * ulr_offset + ulr_count in the directory.
 	 * To use this space, we may have to compact the entries located
 	 * there, by copying them together towards the beginning of the
 	 * block, leaving the free space in one usable chunk at the end.
@@ -808,19 +822,19 @@
 	/*
 	 * Get the block containing the space for the new directory entry.
 	 */
-	if ((error = ext2fs_blkatoff(dvp, (off_t)dp->i_offset, &dirbuf, &bp)) != 0)
+	if ((error = ext2fs_blkatoff(dvp, (off_t)ulr->ulr_offset, &dirbuf, &bp)) != 0)
 		return (error);
 	/*
 	 * Find space for the new entry. In the simple case, the entry at
 	 * offset base will have the space. If it does not, then namei
-	 * arranged that compacting the region dp->i_offset to
-	 * dp->i_offset + dp->i_count would yield the
+	 * arranged that compacting the region ulr_offset to
+	 * ulr_offset + ulr_count would yield the
 	 * space.
 	 */
 	ep = (struct ext2fs_direct *)dirbuf;
 	dsize = EXT2FS_DIRSIZ(ep->e2d_namlen);
 	spacefree = fs2h16(ep->e2d_reclen) - dsize;
-	for (loc = fs2h16(ep->e2d_reclen); loc < dp->i_count; ) {
+	for (loc = fs2h16(ep->e2d_reclen); loc < ulr->ulr_count; ) {
 		nep = (struct ext2fs_direct *)(dirbuf + loc);
 		if (ep->e2d_ino) {
 			/* trim the existing slot */
@@ -860,17 +874,17 @@
 	memcpy((void *)ep, (void *)&newdir, (u_int)newentrysize);
 	error = VOP_BWRITE(bp->b_vp, bp);
 	dp->i_flag |= IN_CHANGE | IN_UPDATE;
-	if (!error && dp->i_endoff && dp->i_endoff < ext2fs_size(dp))
-		error = ext2fs_truncate(dvp, (off_t)dp->i_endoff, IO_SYNC,
+	if (!error && ulr->ulr_endoff && ulr->ulr_endoff < ext2fs_size(dp))
+		error = ext2fs_truncate(dvp, (off_t)ulr->ulr_endoff, IO_SYNC,
 		    cnp->cn_cred);
 	return (error);
 }
 
 /*
  * Remove a directory entry after a call to namei, using
- * the parameters which it left in nameidata. The entry
- * dp->i_offset contains the offset into the directory of the
- * entry to be eliminated.  The dp->i_count field contains the
+ * the auxiliary results it provided. The entry
+ * ulr_offset contains the offset into the directory of the
+ * entry to be eliminated.  The ulr_count field contains the
  * size of the previous record in the directory.  If this
  * is 0, the first entry is being deleted, so we need only
  * zero the inode number to mark the entry as free.  If the
@@ -885,13 +899,19 @@
 	struct ext2fs_direct *ep;
 	struct buf *bp;
 	int error;
+	struct ufs_lookup_results *ulr;
 
 	dp = VTOI(dvp);
-	if (dp->i_count == 0) {
+
+	/* XXX should handle this material another way */
+	ulr = &dp->i_crap;
+	UFS_CHECK_CRAPCOUNTER(dp);
+
+	if (ulr->ulr_count == 0) {
 		/*
 		 * First entry in block: set d_ino to zero.
 		 */
-		error = ext2fs_blkatoff(dvp, (off_t)dp->i_offset,
+		error = ext2fs_blkatoff(dvp, (off_t)ulr->ulr_offset,
 		    (void *)&ep, &bp);
 		if (error != 0)
 			return (error);
@@ -903,11 +923,11 @@
 	/*
 	 * Collapse new free space into previous entry.
 	 */
-	error = ext2fs_blkatoff(dvp, (off_t)(dp->i_offset - dp->i_count),
+	error = ext2fs_blkatoff(dvp, (off_t)(ulr->ulr_offset - ulr->ulr_count),
 	    (void *)&ep, &bp);
 	if (error != 0)
 		return (error);
-	ep->e2d_reclen = h2fs16(fs2h16(ep->e2d_reclen) + dp->i_reclen);
+	ep->e2d_reclen = h2fs16(fs2h16(ep->e2d_reclen) + ulr->ulr_reclen);
 	error = VOP_BWRITE(bp->b_vp, bp);
 	dp->i_flag |= IN_CHANGE | IN_UPDATE;
 	return (error);
@@ -926,8 +946,13 @@
 	struct ext2fs_direct *ep;
 	struct vnode *vdp = ITOV(dp);
 	int error;
+	struct ufs_lookup_results *ulr;
+
+	/* XXX should handle this material another way */
+	ulr = &dp->i_crap;
+	UFS_CHECK_CRAPCOUNTER(dp);
 
-	error = ext2fs_blkatoff(vdp, (off_t)dp->i_offset, (void *)&ep, &bp);
+	error = ext2fs_blkatoff(vdp, (off_t)ulr->ulr_offset, (void *)&ep, &bp);
 	if (error != 0)
 		return (error);
 	ep->e2d_ino = h2fs32(ip->i_number);

Index: src/sys/ufs/ufs/inode.h
diff -u src/sys/ufs/ufs/inode.h:1.57 src/sys/ufs/ufs/inode.h:1.58
--- src/sys/ufs/ufs/inode.h:1.57	Wed Jul 28 11:03:48 2010
+++ src/sys/ufs/ufs/inode.h	Tue Jul 12 02:22:13 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: inode.h,v 1.57 2010/07/28 11:03:48 hannken Exp $	*/
+/*	$NetBSD: inode.h,v 1.58 2011/07/12 02:22:13 dholland Exp $	*/
 
 /*
  * Copyright (c) 1982, 1989, 1993
@@ -47,6 +47,22 @@
 #include <miscfs/genfs/genfs_node.h>
 
 /*
+ * Lookup result state (other than the result inode). This is
+ * currently stashed in the vnode between VOP_LOOKUP and directory
+ * operation VOPs, which is gross.
+ */
+struct ufs_lookup_results {
+	int32_t	  ulr_count;	/* Size of free slot in directory. */
+	doff_t	  ulr_endoff;	/* End of useful stuff in directory. */
+	doff_t	  ulr_diroff;	/* Offset in dir, where we found last entry. */
+	doff_t	  ulr_offset;	/* Offset of free space in directory. */
+	u_int32_t ulr_reclen;	/* Size of found directory entry. */
+};
+
+/* notyet XXX */
+#define UFS_CHECK_CRAPCOUNTER(dp) ((void)(dp)->i_crapcounter)
+
+/*
  * Per-filesystem inode extensions.
  */
 struct ffs_inode_ext {
@@ -98,14 +114,12 @@
 	struct	 lockf *i_lockf;/* Head of byte-level lock list. */
 
 	/*
-	 * Side effects; used during directory lookup.
+	 * Side effects; used during (and after) directory lookup.
+	 * XXX should not be here.
 	 */
-	int32_t	  i_count;	/* Size of free slot in directory. */
-	doff_t	  i_endoff;	/* End of useful stuff in directory. */
-	doff_t	  i_diroff;	/* Offset in dir, where we found last entry. */
-	doff_t	  i_offset;	/* Offset of free space in directory. */
-	u_int32_t i_reclen;	/* Size of found directory entry. */
-	int       i_unused;	/* was for softdep, now unused */
+	struct ufs_lookup_results i_crap;
+	unsigned i_crapcounter;	/* serial number for i_crap */
+
 	/*
 	 * Inode extensions
 	 */

Index: src/sys/ufs/ufs/ufs_lookup.c
diff -u src/sys/ufs/ufs/ufs_lookup.c:1.107 src/sys/ufs/ufs/ufs_lookup.c:1.108
--- src/sys/ufs/ufs/ufs_lookup.c:1.107	Mon Jul 11 08:27:41 2011
+++ src/sys/ufs/ufs/ufs_lookup.c	Tue Jul 12 02:22:13 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ufs_lookup.c,v 1.107 2011/07/11 08:27:41 hannken Exp $	*/
+/*	$NetBSD: ufs_lookup.c,v 1.108 2011/07/12 02:22:13 dholland Exp $	*/
 
 /*
  * Copyright (c) 1989, 1993
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_lookup.c,v 1.107 2011/07/11 08:27:41 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_lookup.c,v 1.108 2011/07/12 02:22:13 dholland Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ffs.h"
@@ -144,6 +144,7 @@
 	const int needswap = UFS_MPNEEDSWAP(ump);
 	int dirblksiz = ump->um_dirblksiz;
 	ino_t foundino;
+	struct ufs_lookup_results *results;
 
 	flags = cnp->cn_flags;
 
@@ -151,6 +152,15 @@
 	slotoffset = -1;
 	*vpp = NULL;
 	endsearch = 0; /* silence compiler warning */
+
+	/*
+	 * Produce the auxiliary lookup results into i_crap. Increment
+	 * its serial number so elsewhere we can tell if we're using
+	 * stale results. This should not be done this way. XXX.
+	 */
+	results = &dp->i_crap;
+	dp->i_crapcounter++;
+
 	/*
 	 * Check accessiblity of directory.
 	 */
@@ -225,13 +235,13 @@
 		numdirpasses = 1;
 		entryoffsetinblock = 0; /* silence compiler warning */
 		switch (ufsdirhash_lookup(dp, cnp->cn_nameptr, cnp->cn_namelen,
-		    &dp->i_offset, &bp, nameiop == DELETE ? &prevoff : NULL)) {
+		    &results->ulr_offset, &bp, nameiop == DELETE ? &prevoff : NULL)) {
 		case 0:
 			ep = (struct direct *)((char *)bp->b_data +
-			    (dp->i_offset & bmask));
+			    (results->ulr_offset & bmask));
 			goto foundentry;
 		case ENOENT:
-			dp->i_offset = roundup(dp->i_size, dirblksiz);
+			results->ulr_offset = roundup(dp->i_size, dirblksiz);
 			goto notfound;
 		default:
 			/* Something failed; just do a linear search. */
@@ -240,35 +250,35 @@
 	}
 #endif /* UFS_DIRHASH */
 
-	if (nameiop != LOOKUP || dp->i_diroff == 0 ||
-	    dp->i_diroff >= dp->i_size) {
+	if (nameiop != LOOKUP || results->ulr_diroff == 0 ||
+	    results->ulr_diroff >= dp->i_size) {
 		entryoffsetinblock = 0;
-		dp->i_offset = 0;
+		results->ulr_offset = 0;
 		numdirpasses = 1;
 	} else {
-		dp->i_offset = dp->i_diroff;
-		if ((entryoffsetinblock = dp->i_offset & bmask) &&
-		    (error = ufs_blkatoff(vdp, (off_t)dp->i_offset,
+		results->ulr_offset = results->ulr_diroff;
+		if ((entryoffsetinblock = results->ulr_offset & bmask) &&
+		    (error = ufs_blkatoff(vdp, (off_t)results->ulr_offset,
 		    NULL, &bp, false)))
 			goto out;
 		numdirpasses = 2;
 		nchstats.ncs_2passes++;
 	}
-	prevoff = dp->i_offset;
+	prevoff = results->ulr_offset;
 	endsearch = roundup(dp->i_size, dirblksiz);
 	enduseful = 0;
 
 searchloop:
-	while (dp->i_offset < endsearch) {
+	while (results->ulr_offset < endsearch) {
 		if (curcpu()->ci_schedstate.spc_flags & SPCF_SHOULDYIELD)
 			preempt();
 		/*
 		 * If necessary, get the next directory block.
 		 */
-		if ((dp->i_offset & bmask) == 0) {
+		if ((results->ulr_offset & bmask) == 0) {
 			if (bp != NULL)
 				brelse(bp, 0);
-			error = ufs_blkatoff(vdp, (off_t)dp->i_offset, NULL,
+			error = ufs_blkatoff(vdp, (off_t)results->ulr_offset, NULL,
 			    &bp, false);
 			if (error)
 				goto out;
@@ -296,9 +306,9 @@
 		    (dirchk && ufs_dirbadentry(vdp, ep, entryoffsetinblock))) {
 			int i;
 
-			ufs_dirbad(dp, dp->i_offset, "mangled entry");
+			ufs_dirbad(dp, results->ulr_offset, "mangled entry");
 			i = dirblksiz - (entryoffsetinblock & (dirblksiz - 1));
-			dp->i_offset += i;
+			results->ulr_offset += i;
 			entryoffsetinblock += i;
 			continue;
 		}
@@ -317,16 +327,16 @@
 			if (size > 0) {
 				if (size >= slotneeded) {
 					slotstatus = FOUND;
-					slotoffset = dp->i_offset;
+					slotoffset = results->ulr_offset;
 					slotsize = ufs_rw16(ep->d_reclen,
 					    needswap);
 				} else if (slotstatus == NONE) {
 					slotfreespace += size;
 					if (slotoffset == -1)
-						slotoffset = dp->i_offset;
+						slotoffset = results->ulr_offset;
 					if (slotfreespace >= slotneeded) {
 						slotstatus = COMPACT;
-						slotsize = dp->i_offset +
+						slotsize = results->ulr_offset +
 						    ufs_rw16(ep->d_reclen,
 							     needswap) -
 						    slotoffset;
@@ -363,12 +373,12 @@
 				 */
 				if (!FSFMT(vdp) && ep->d_type == DT_WHT) {
 					slotstatus = FOUND;
-					slotoffset = dp->i_offset;
+					slotoffset = results->ulr_offset;
 					slotsize = ufs_rw16(ep->d_reclen,
 					    needswap);
-					dp->i_reclen = slotsize;
+					results->ulr_reclen = slotsize;
 					/*
-					 * This is used to set dp->i_endoff,
+					 * This is used to set results->ulr_endoff,
 					 * which may be used by ufs_direnter2()
 					 * as a length to truncate the
 					 * directory to.  Therefore, it must
@@ -389,15 +399,15 @@
 					goto notfound;
 				}
 				foundino = ufs_rw32(ep->d_ino, needswap);
-				dp->i_reclen = ufs_rw16(ep->d_reclen, needswap);
+				results->ulr_reclen = ufs_rw16(ep->d_reclen, needswap);
 				goto found;
 			}
 		}
-		prevoff = dp->i_offset;
-		dp->i_offset += ufs_rw16(ep->d_reclen, needswap);
+		prevoff = results->ulr_offset;
+		results->ulr_offset += ufs_rw16(ep->d_reclen, needswap);
 		entryoffsetinblock += ufs_rw16(ep->d_reclen, needswap);
 		if (ep->d_ino)
-			enduseful = dp->i_offset;
+			enduseful = results->ulr_offset;
 	}
 notfound:
 	/*
@@ -406,8 +416,8 @@
 	 */
 	if (numdirpasses == 2) {
 		numdirpasses--;
-		dp->i_offset = 0;
-		endsearch = dp->i_diroff;
+		results->ulr_offset = 0;
+		endsearch = results->ulr_diroff;
 		goto searchloop;
 	}
 	if (bp != NULL)
@@ -432,29 +442,29 @@
 		/*
 		 * Return an indication of where the new directory
 		 * entry should be put.  If we didn't find a slot,
-		 * then set dp->i_count to 0 indicating
+		 * then set results->ulr_count to 0 indicating
 		 * that the new slot belongs at the end of the
 		 * directory. If we found a slot, then the new entry
-		 * can be put in the range from dp->i_offset to
-		 * dp->i_offset + dp->i_count.
+		 * can be put in the range from results->ulr_offset to
+		 * results->ulr_offset + results->ulr_count.
 		 */
 		if (slotstatus == NONE) {
-			dp->i_offset = roundup(dp->i_size, dirblksiz);
-			dp->i_count = 0;
-			enduseful = dp->i_offset;
+			results->ulr_offset = roundup(dp->i_size, dirblksiz);
+			results->ulr_count = 0;
+			enduseful = results->ulr_offset;
 		} else if (nameiop == DELETE) {
-			dp->i_offset = slotoffset;
-			if ((dp->i_offset & (dirblksiz - 1)) == 0)
-				dp->i_count = 0;
+			results->ulr_offset = slotoffset;
+			if ((results->ulr_offset & (dirblksiz - 1)) == 0)
+				results->ulr_count = 0;
 			else
-				dp->i_count = dp->i_offset - prevoff;
+				results->ulr_count = results->ulr_offset - prevoff;
 		} else {
-			dp->i_offset = slotoffset;
-			dp->i_count = slotsize;
+			results->ulr_offset = slotoffset;
+			results->ulr_count = slotsize;
 			if (enduseful < slotoffset + slotsize)
 				enduseful = slotoffset + slotsize;
 		}
-		dp->i_endoff = roundup(enduseful, dirblksiz);
+		results->ulr_endoff = roundup(enduseful, dirblksiz);
 #if 0 /* commented out by dbj. none of the on disk fields changed */
 		dp->i_flag |= IN_CHANGE | IN_UPDATE;
 #endif
@@ -487,9 +497,9 @@
 	 * Check that directory length properly reflects presence
 	 * of this entry.
 	 */
-	if (dp->i_offset + DIRSIZ(FSFMT(vdp), ep, needswap) > dp->i_size) {
-		ufs_dirbad(dp, dp->i_offset, "i_size too small");
-		dp->i_size = dp->i_offset + DIRSIZ(FSFMT(vdp), ep, needswap);
+	if (results->ulr_offset + DIRSIZ(FSFMT(vdp), ep, needswap) > dp->i_size) {
+		ufs_dirbad(dp, results->ulr_offset, "i_size too small");
+		dp->i_size = results->ulr_offset + DIRSIZ(FSFMT(vdp), ep, needswap);
 		DIP_ASSIGN(dp, size, dp->i_size);
 		dp->i_flag |= IN_CHANGE | IN_UPDATE;
 		UFS_WAPBL_UPDATE(vdp, NULL, NULL, UPDATE_DIROP);
@@ -502,7 +512,7 @@
 	 * in the cache as to where the entry was found.
 	 */
 	if ((flags & ISLASTCN) && nameiop == LOOKUP)
-		dp->i_diroff = dp->i_offset &~ (dirblksiz - 1);
+		results->ulr_diroff = results->ulr_offset &~ (dirblksiz - 1);
 
 	/*
 	 * If deleting, and at end of pathname, return
@@ -517,15 +527,15 @@
 		if (error)
 			goto out;
 		/*
-		 * Return pointer to current entry in dp->i_offset,
+		 * Return pointer to current entry in results->ulr_offset,
 		 * and distance past previous entry (if there
-		 * is a previous entry in this block) in dp->i_count.
+		 * is a previous entry in this block) in results->ulr_count.
 		 * Save directory inode pointer in ndp->ni_dvp for dirremove().
 		 */
-		if ((dp->i_offset & (dirblksiz - 1)) == 0)
-			dp->i_count = 0;
+		if ((results->ulr_offset & (dirblksiz - 1)) == 0)
+			results->ulr_count = 0;
 		else
-			dp->i_count = dp->i_offset - prevoff;
+			results->ulr_count = results->ulr_offset - prevoff;
 		if (dp->i_number == foundino) {
 			vref(vdp);
 			*vpp = vdp;
@@ -755,6 +765,7 @@
 	struct ufsmount *ump = VFSTOUFS(dvp->v_mount);
 	const int needswap = UFS_MPNEEDSWAP(ump);
 	int dirblksiz = ump->um_dirblksiz;
+	struct ufs_lookup_results *ulr;
 
 	UFS_WAPBL_JLOCK_ASSERT(dvp->v_mount);
 
@@ -765,20 +776,24 @@
 	dp = VTOI(dvp);
 	newentrysize = DIRSIZ(0, dirp, 0);
 
-	if (dp->i_count == 0) {
+	/* XXX should handle this material another way */
+	ulr = &dp->i_crap;
+	UFS_CHECK_CRAPCOUNTER(dp);
+
+	if (ulr->ulr_count == 0) {
 		/*
-		 * If dp->i_count is 0, then namei could find no
-		 * space in the directory. Here, dp->i_offset will
+		 * If ulr_count is 0, then namei could find no
+		 * space in the directory. Here, ulr_offset will
 		 * be on a directory block boundary and we will write the
 		 * new entry into a fresh block.
 		 */
-		if (dp->i_offset & (dirblksiz - 1))
+		if (ulr->ulr_offset & (dirblksiz - 1))
 			panic("ufs_direnter: newblk");
-		if ((error = UFS_BALLOC(dvp, (off_t)dp->i_offset, dirblksiz,
+		if ((error = UFS_BALLOC(dvp, (off_t)ulr->ulr_offset, dirblksiz,
 		    cr, B_CLRBUF | B_SYNC, &bp)) != 0) {
 			return (error);
 		}
-		dp->i_size = dp->i_offset + dirblksiz;
+		dp->i_size = ulr->ulr_offset + dirblksiz;
 		DIP_ASSIGN(dp, size, dp->i_size);
 		dp->i_flag |= IN_CHANGE | IN_UPDATE;
 		uvm_vnp_setsize(dvp, dp->i_size);
@@ -795,14 +810,14 @@
 				dirp->d_type = tmp;
 			}
 		}
-		blkoff = dp->i_offset & (ump->um_mountp->mnt_stat.f_iosize - 1);
+		blkoff = ulr->ulr_offset & (ump->um_mountp->mnt_stat.f_iosize - 1);
 		memcpy((char *)bp->b_data + blkoff, dirp, newentrysize);
 #ifdef UFS_DIRHASH
 		if (dp->i_dirhash != NULL) {
-			ufsdirhash_newblk(dp, dp->i_offset);
-			ufsdirhash_add(dp, dirp, dp->i_offset);
+			ufsdirhash_newblk(dp, ulr->ulr_offset);
+			ufsdirhash_add(dp, dirp, ulr->ulr_offset);
 			ufsdirhash_checkblock(dp, (char *)bp->b_data + blkoff,
-			    dp->i_offset);
+			    ulr->ulr_offset);
 		}
 #endif
 		error = VOP_BWRITE(bp->b_vp, bp);
@@ -829,8 +844,12 @@
 	 *
 	 * N.B. - THIS IS AN ARTIFACT OF 4.2 AND SHOULD NEVER HAPPEN.
 	 */
-	if (dp->i_offset + dp->i_count > dp->i_size) {
-		dp->i_size = dp->i_offset + dp->i_count;
+	if (ulr->ulr_offset + ulr->ulr_count > dp->i_size) {
+#ifdef DIAGNOSTIC
+		printf("ufs_direnter: reached 4.2-only block, "
+		       "not supposed to happen\n");
+#endif
+		dp->i_size = ulr->ulr_offset + ulr->ulr_count;
 		DIP_ASSIGN(dp, size, dp->i_size);
 		dp->i_flag |= IN_CHANGE | IN_UPDATE;
 		UFS_WAPBL_UPDATE(dvp, NULL, NULL, UPDATE_DIROP);
@@ -838,7 +857,7 @@
 	/*
 	 * Get the block containing the space for the new directory entry.
 	 */
-	error = ufs_blkatoff(dvp, (off_t)dp->i_offset, &dirbuf, &bp, true);
+	error = ufs_blkatoff(dvp, (off_t)ulr->ulr_offset, &dirbuf, &bp, true);
 	if (error) {
 		return (error);
 	}
@@ -851,7 +870,7 @@
 	ep = (struct direct *)dirbuf;
 	dsize = (ep->d_ino != 0) ?  DIRSIZ(FSFMT(dvp), ep, needswap) : 0;
 	spacefree = ufs_rw16(ep->d_reclen, needswap) - dsize;
-	for (loc = ufs_rw16(ep->d_reclen, needswap); loc < dp->i_count; ) {
+	for (loc = ufs_rw16(ep->d_reclen, needswap); loc < ulr->ulr_count; ) {
 		uint16_t reclen;
 
 		nep = (struct direct *)(dirbuf + loc);
@@ -881,8 +900,8 @@
 #ifdef UFS_DIRHASH
 		if (dp->i_dirhash != NULL)
 			ufsdirhash_move(dp, nep,
-			    dp->i_offset + ((char *)nep - dirbuf),
-			    dp->i_offset + ((char *)ep - dirbuf));
+			    ulr->ulr_offset + ((char *)nep - dirbuf),
+			    ulr->ulr_offset + ((char *)ep - dirbuf));
 #endif
 		memcpy((void *)ep, (void *)nep, dsize);
 	}
@@ -924,14 +943,14 @@
 #ifdef UFS_DIRHASH
 	if (dp->i_dirhash != NULL && (ep->d_ino == 0 ||
 	    dirp->d_reclen == spacefree))
-		ufsdirhash_add(dp, dirp, dp->i_offset + ((char *)ep - dirbuf));
+		ufsdirhash_add(dp, dirp, ulr->ulr_offset + ((char *)ep - dirbuf));
 #endif
 	memcpy((void *)ep, (void *)dirp, (u_int)newentrysize);
 #ifdef UFS_DIRHASH
 	if (dp->i_dirhash != NULL)
 		ufsdirhash_checkblock(dp, dirbuf -
-		    (dp->i_offset & (dirblksiz - 1)),
-		    dp->i_offset & ~(dirblksiz - 1));
+		    (ulr->ulr_offset & (dirblksiz - 1)),
+		    ulr->ulr_offset & ~(dirblksiz - 1));
 #endif
 	error = VOP_BWRITE(bp->b_vp, bp);
 	dp->i_flag |= IN_CHANGE | IN_UPDATE;
@@ -942,12 +961,12 @@
 	 * lock other inodes which can lead to deadlock if we also hold a
 	 * lock on the newly entered node.
 	 */
-	if (error == 0 && dp->i_endoff && dp->i_endoff < dp->i_size) {
+	if (error == 0 && ulr->ulr_endoff && ulr->ulr_endoff < dp->i_size) {
 #ifdef UFS_DIRHASH
 		if (dp->i_dirhash != NULL)
-			ufsdirhash_dirtrunc(dp, dp->i_endoff);
+			ufsdirhash_dirtrunc(dp, ulr->ulr_endoff);
 #endif
-		(void) UFS_TRUNCATE(dvp, (off_t)dp->i_endoff, IO_SYNC, cr);
+		(void) UFS_TRUNCATE(dvp, (off_t)ulr->ulr_endoff, IO_SYNC, cr);
 	}
 	UFS_WAPBL_UPDATE(dvp, NULL, NULL, UPDATE_DIROP);
 	return (error);
@@ -975,6 +994,11 @@
 #ifdef FFS_EI
 	const int needswap = UFS_MPNEEDSWAP(dp->i_ump);
 #endif
+	struct ufs_lookup_results *ulr;
+
+	/* XXX should handle this material another way */
+	ulr = &dp->i_crap;
+	UFS_CHECK_CRAPCOUNTER(dp);
 
 	UFS_WAPBL_JLOCK_ASSERT(dvp->v_mount);
 
@@ -982,7 +1006,7 @@
 		/*
 		 * Whiteout entry: set d_ino to WINO.
 		 */
-		error = ufs_blkatoff(dvp, (off_t)dp->i_offset, (void *)&ep,
+		error = ufs_blkatoff(dvp, (off_t)ulr->ulr_offset, (void *)&ep,
 				     &bp, true);
 		if (error)
 			return (error);
@@ -992,7 +1016,7 @@
 	}
 
 	if ((error = ufs_blkatoff(dvp,
-	    (off_t)(dp->i_offset - dp->i_count), (void *)&ep, &bp, true)) != 0)
+	    (off_t)(ulr->ulr_offset - ulr->ulr_count), (void *)&ep, &bp, true)) != 0)
 		return (error);
 
 #ifdef UFS_DIRHASH
@@ -1001,12 +1025,12 @@
 	 * that `ep' is the previous entry when dp->i_count != 0.
 	 */
 	if (dp->i_dirhash != NULL)
-		ufsdirhash_remove(dp, (dp->i_count == 0) ? ep :
+		ufsdirhash_remove(dp, (ulr->ulr_count == 0) ? ep :
 		   (struct direct *)((char *)ep +
-		   ufs_rw16(ep->d_reclen, needswap)), dp->i_offset);
+		   ufs_rw16(ep->d_reclen, needswap)), ulr->ulr_offset);
 #endif
 
-	if (dp->i_count == 0) {
+	if (ulr->ulr_count == 0) {
 		/*
 		 * First entry in block: set d_ino to zero.
 		 */
@@ -1016,7 +1040,7 @@
 		 * Collapse new free space into previous entry.
 		 */
 		ep->d_reclen =
-		    ufs_rw16(ufs_rw16(ep->d_reclen, needswap) + dp->i_reclen,
+		    ufs_rw16(ufs_rw16(ep->d_reclen, needswap) + ulr->ulr_reclen,
 			needswap);
 	}
 
@@ -1024,8 +1048,8 @@
 	if (dp->i_dirhash != NULL) {
 		int dirblksiz = ip->i_ump->um_dirblksiz;
 		ufsdirhash_checkblock(dp, (char *)ep -
-		    ((dp->i_offset - dp->i_count) & (dirblksiz - 1)),
-		    dp->i_offset & ~(dirblksiz - 1));
+		    ((ulr->ulr_offset - ulr->ulr_count) & (dirblksiz - 1)),
+		    ulr->ulr_offset & ~(dirblksiz - 1));
 	}
 #endif
 
@@ -1063,8 +1087,13 @@
 	struct direct *ep;
 	struct vnode *vdp = ITOV(dp);
 	int error;
+	struct ufs_lookup_results *ulr;
+
+	/* XXX should handle this material another way */
+	ulr = &dp->i_crap;
+	UFS_CHECK_CRAPCOUNTER(dp);
 
-	error = ufs_blkatoff(vdp, (off_t)dp->i_offset, (void *)&ep, &bp, true);
+	error = ufs_blkatoff(vdp, (off_t)ulr->ulr_offset, (void *)&ep, &bp, true);
 	if (error)
 		return (error);
 	ep->d_ino = ufs_rw32(newinum, UFS_MPNEEDSWAP(dp->i_ump));

Index: src/sys/ufs/ufs/ufs_vnops.c
diff -u src/sys/ufs/ufs/ufs_vnops.c:1.190 src/sys/ufs/ufs/ufs_vnops.c:1.191
--- src/sys/ufs/ufs/ufs_vnops.c:1.190	Mon Jul 11 08:27:41 2011
+++ src/sys/ufs/ufs/ufs_vnops.c	Tue Jul 12 02:22:13 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: ufs_vnops.c,v 1.190 2011/07/11 08:27:41 hannken Exp $	*/
+/*	$NetBSD: ufs_vnops.c,v 1.191 2011/07/12 02:22:13 dholland Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.190 2011/07/11 08:27:41 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.191 2011/07/12 02:22:13 dholland Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_ffs.h"
@@ -1286,7 +1286,8 @@
 		 */
 		if (doingdirectory && newparent) {
 			KASSERT(dp != NULL);
-			xp->i_offset = mastertemplate.dot_reclen;
+			/* XXX gross; should be an argument */
+			xp->i_crap.ulr_offset = mastertemplate.dot_reclen;
 			ufs_dirrewrite(xp, dp, newparent, DT_DIR, 0, IN_CHANGE);
 			cache_purge(fdvp);
 		}

Index: src/sys/ufs/ufs/ufs_wapbl.c
diff -u src/sys/ufs/ufs/ufs_wapbl.c:1.13 src/sys/ufs/ufs/ufs_wapbl.c:1.14
--- src/sys/ufs/ufs/ufs_wapbl.c:1.13	Mon May 23 22:02:26 2011
+++ src/sys/ufs/ufs/ufs_wapbl.c	Tue Jul 12 02:22:14 2011
@@ -1,4 +1,4 @@
-/*  $NetBSD: ufs_wapbl.c,v 1.13 2011/05/23 22:02:26 rmind Exp $ */
+/*  $NetBSD: ufs_wapbl.c,v 1.14 2011/07/12 02:22:14 dholland Exp $ */
 
 /*-
  * Copyright (c) 2003,2006,2008 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_wapbl.c,v 1.13 2011/05/23 22:02:26 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_wapbl.c,v 1.14 2011/07/12 02:22:14 dholland Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -160,15 +160,10 @@
 	struct direct		*newdir;
 	int			doingdirectory, oldparent, newparent, error;
 
-	int32_t	  saved_f_count;
-	doff_t	  saved_f_diroff;
-	doff_t	  saved_f_offset;
-	u_int32_t saved_f_reclen;
-	int32_t	  saved_t_count;
-	doff_t	  saved_t_endoff;
-	doff_t	  saved_t_diroff;
-	doff_t	  saved_t_offset;
-	u_int32_t saved_t_reclen;
+	struct ufs_lookup_results saved_f_crap;
+	struct ufs_lookup_results saved_t_crap;
+	unsigned saved_f_crapcounter;
+	unsigned saved_t_crapcounter;
 
 	tvp = ap->a_tvp;
 	tdvp = ap->a_tdvp;
@@ -319,11 +314,8 @@
 	 */
 
 	/* save directory lookup information in case tdvp == fdvp */
-	saved_t_count  = tdp->i_count;
-	saved_t_endoff = tdp->i_endoff;
-	saved_t_diroff = tdp->i_diroff;
-	saved_t_offset = tdp->i_offset;
-	saved_t_reclen = tdp->i_reclen;
+	saved_t_crap = tdp->i_crap;
+	saved_t_crapcounter = tdp->i_crapcounter;
 
 	/*
 	 * This was moved up to before the journal lock to
@@ -372,17 +364,15 @@
 	vrele(ap->a_fvp);
 
 	/* save directory lookup information in case tdvp == fdvp */
-	saved_f_count  = fdp->i_count;
-	saved_f_diroff = fdp->i_diroff;
-	saved_f_offset = fdp->i_offset;
-	saved_f_reclen = fdp->i_reclen;
+	saved_f_crap = fdp->i_crap;
+	saved_f_crapcounter = fdp->i_crapcounter;
+
+	/* before the introduction of _crap this didn't save endoff (XXX?) */
+	saved_f_crap.ulr_endoff = 0;
 
 	/* restore directory lookup information in case tdvp == fdvp */
-	tdp->i_offset = saved_t_offset;
-	tdp->i_reclen = saved_t_reclen;
-	tdp->i_count  = saved_t_count;
-	tdp->i_endoff = saved_t_endoff;
-	tdp->i_diroff = saved_t_diroff;
+	tdp->i_crap = saved_t_crap;
+	tdp->i_crapcounter = saved_t_crapcounter;
 
 	error = UFS_WAPBL_BEGIN(fdvp->v_mount);
 	if (error)
@@ -519,10 +509,10 @@
 	}
 
 	/* restore directory lookup information in case tdvp == fdvp */
-	fdp->i_offset = saved_f_offset;
-	fdp->i_reclen = saved_f_reclen;
-	fdp->i_count  = saved_f_count;
-	fdp->i_diroff = saved_f_diroff;
+	/* before the introduction of _crap this didn't restore endoff (XXX?)*/
+	saved_f_crap.ulr_endoff = fdp->i_crap.ulr_endoff;
+	fdp->i_crap = saved_f_crap;
+	fdp->i_crapcounter = saved_f_crapcounter;
 
 	/*
 	 * Handle case where the directory we need to remove may have
@@ -530,11 +520,11 @@
 	 * or when i_count may be wrong due to insertion before this entry.
 	 */
 	if ((tdp->i_number == fdp->i_number) &&
-		(((saved_f_offset >= saved_t_offset) &&
-			(saved_f_offset < saved_t_offset + saved_t_count)) ||
-		((saved_f_offset - saved_f_count >= saved_t_offset) &&
-			(saved_f_offset - saved_f_count <
-			 saved_t_offset + saved_t_count)))) {
+		(((saved_f_crap.ulr_offset >= saved_t_crap.ulr_offset) &&
+			(saved_f_crap.ulr_offset < saved_t_crap.ulr_offset + saved_t_crap.ulr_count)) ||
+		((saved_f_crap.ulr_offset - saved_f_crap.ulr_count >= saved_t_crap.ulr_offset) &&
+			(saved_f_crap.ulr_offset - saved_f_crap.ulr_count <
+			 saved_t_crap.ulr_offset + saved_t_crap.ulr_count)))) {
 		struct buf *bp;
 		struct direct *ep;
 		struct ufsmount *ump = fdp->i_ump;
@@ -551,28 +541,30 @@
 		 * the fcnp entry will be somewhere between the start of
 		 * compaction and the original location.
 		 */
-		fdp->i_offset = saved_t_offset;
-		error = ufs_blkatoff(fdvp, (off_t)fdp->i_offset, &dirbuf, &bp,
+		/* XXX crap */
+		fdp->i_crap.ulr_offset = saved_t_crap.ulr_offset;
+		error = ufs_blkatoff(fdvp, (off_t)fdp->i_crap.ulr_offset, &dirbuf, &bp,
 		    false);
 		if (error)
 			goto bad;
 
 		/*
-		 * keep existing fdp->i_count in case
+		 * keep existing ulr_count in case
 		 * compaction started at the same location as the fcnp entry.
 		 */
-		endsearch = saved_f_offset + saved_f_reclen;
+		endsearch = saved_f_crap.ulr_offset + saved_f_crap.ulr_reclen;
 		entryoffsetinblock = 0;
-		while (fdp->i_offset < endsearch) {
+		/* XXX crap */
+		while (fdp->i_crap.ulr_offset < endsearch) {
 			int reclen;
 
 			/*
 			 * If necessary, get the next directory block.
 			 */
-			if ((fdp->i_offset & bmask) == 0) {
+			if ((fdp->i_crap.ulr_offset & bmask) == 0) {
 				if (bp != NULL)
 					brelse(bp, 0);
-				error = ufs_blkatoff(fdvp, (off_t)fdp->i_offset,
+				error = ufs_blkatoff(fdvp, (off_t)fdp->i_crap.ulr_offset,
 				    &dirbuf, &bp, false);
 				if (error)
 					goto bad;
@@ -598,23 +590,23 @@
 			    (ufs_rw32(ep->d_ino, needswap) != WINO) &&
 			    (namlen == fcnp->cn_namelen) &&
 			    memcmp(ep->d_name, fcnp->cn_nameptr, namlen) == 0) {
-				fdp->i_reclen = reclen;
+				fdp->i_crap.ulr_reclen = reclen;
 				break;
 			}
-			fdp->i_offset += reclen;
-			fdp->i_count = reclen;
+			fdp->i_crap.ulr_offset += reclen;
+			fdp->i_crap.ulr_count = reclen;
 			entryoffsetinblock += reclen;
 		}
 
-		KASSERT(fdp->i_offset <= endsearch);
+		KASSERT(fdp->i_crap.ulr_offset <= endsearch);
 
 		/*
-		 * If fdp->i_offset points to start of a directory block,
-		 * set fdp->i_count so ufs_dirremove() doesn't compact over
+		 * If ulr_offset points to start of a directory block,
+		 * set ulr_count so ufs_dirremove() doesn't compact over
 		 * a directory block boundary.
 		 */
-		if ((fdp->i_offset & (dirblksiz - 1)) == 0)
-			fdp->i_count = 0;
+		if ((fdp->i_crap.ulr_offset & (dirblksiz - 1)) == 0)
+			fdp->i_crap.ulr_count = 0;
 
 		brelse(bp, 0);
 	}
@@ -643,7 +635,8 @@
 		 */
 		if (doingdirectory && newparent) {
 			KASSERT(fdp != NULL);
-			fxp->i_offset = mastertemplate.dot_reclen;
+			/* XXX crap, should be argument */
+			fxp->i_crap.ulr_offset = mastertemplate.dot_reclen;
 			ufs_dirrewrite(fxp, fdp, newparent, DT_DIR, 0, IN_CHANGE);
 			cache_purge(fdvp);
 		}

Reply via email to