Module Name:    src
Committed By:   dholland
Date:           Sun Aug  2 18:18:46 UTC 2015

Modified Files:
        src/sys/ufs/lfs: lfs.h lfs_accessors.h lfs_balloc.c lfs_segment.c
            lfs_vfsops.c ulfs_bmap.c

Log Message:
Pass the fs object to LFS_MAX_DADDR so it can check lfs_is64.

Remove some hackish intentional 64->32 truncations next to the checks
using LFS_MAX_DADDR, and tackle the problem they handled in bmap
instead.

The problem: the magic block pointer value UNWRITTEN has magic value
-2, and if it's not handled specifically, uint32 -> uint64 promotion
turns it into 4294967294, which then causes consternation and
monkeyhouse downstream.

What's here is still kind of a hack, but it's a step forward.


To generate a diff of this commit:
cvs rdiff -u -r1.171 -r1.172 src/sys/ufs/lfs/lfs.h
cvs rdiff -u -r1.7 -r1.8 src/sys/ufs/lfs/lfs_accessors.h
cvs rdiff -u -r1.85 -r1.86 src/sys/ufs/lfs/lfs_balloc.c
cvs rdiff -u -r1.250 -r1.251 src/sys/ufs/lfs/lfs_segment.c
cvs rdiff -u -r1.333 -r1.334 src/sys/ufs/lfs/lfs_vfsops.c
cvs rdiff -u -r1.5 -r1.6 src/sys/ufs/lfs/ulfs_bmap.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/lfs/lfs.h
diff -u src/sys/ufs/lfs/lfs.h:1.171 src/sys/ufs/lfs/lfs.h:1.172
--- src/sys/ufs/lfs/lfs.h:1.171	Sun Aug  2 18:18:10 2015
+++ src/sys/ufs/lfs/lfs.h	Sun Aug  2 18:18:46 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: lfs.h,v 1.171 2015/08/02 18:18:10 dholland Exp $	*/
+/*	$NetBSD: lfs.h,v 1.172 2015/08/02 18:18:46 dholland Exp $	*/
 
 /*  from NetBSD: dinode.h,v 1.22 2013/01/22 09:39:18 dholland Exp  */
 /*  from NetBSD: dir.h,v 1.21 2009/07/22 04:49:19 dholland Exp  */
@@ -194,8 +194,6 @@
 #define	LFS_V1_SUMMARY_SIZE	512     /* V1 fixed summary size */
 #define	LFS_DFL_SUMMARY_SIZE	512	/* Default summary size */
 
-#define LFS_MAX_DADDR	0x7fffffff	/* Highest addressable fsb */
-
 #define LFS_MAXNAMLEN	255		/* maximum name length in a dir */
 
 #define ULFS_NXADDR	2

Index: src/sys/ufs/lfs/lfs_accessors.h
diff -u src/sys/ufs/lfs/lfs_accessors.h:1.7 src/sys/ufs/lfs/lfs_accessors.h:1.8
--- src/sys/ufs/lfs/lfs_accessors.h:1.7	Sun Aug  2 18:18:10 2015
+++ src/sys/ufs/lfs/lfs_accessors.h	Sun Aug  2 18:18:46 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: lfs_accessors.h,v 1.7 2015/08/02 18:18:10 dholland Exp $	*/
+/*	$NetBSD: lfs_accessors.h,v 1.8 2015/08/02 18:18:46 dholland Exp $	*/
 
 /*  from NetBSD: lfs.h,v 1.165 2015/07/24 06:59:32 dholland Exp  */
 /*  from NetBSD: dinode.h,v 1.22 2013/01/22 09:39:18 dholland Exp  */
@@ -563,6 +563,10 @@ lfs_sb_setfsmnt(STRUCT_LFS *fs, const ch
 	}
 }
 
+/* Highest addressable fsb */
+#define LFS_MAX_DADDR(fs) \
+	((fs)->lfs_is64 ? 0x7fffffffffffffff : 0x7fffffff)
+
 /* LFS_NINDIR is the number of indirects in a file system block. */
 #define	LFS_NINDIR(fs)	(lfs_sb_getnindir(fs))
 

Index: src/sys/ufs/lfs/lfs_balloc.c
diff -u src/sys/ufs/lfs/lfs_balloc.c:1.85 src/sys/ufs/lfs/lfs_balloc.c:1.86
--- src/sys/ufs/lfs/lfs_balloc.c:1.85	Sun Aug  2 18:08:13 2015
+++ src/sys/ufs/lfs/lfs_balloc.c	Sun Aug  2 18:18:46 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: lfs_balloc.c,v 1.85 2015/08/02 18:08:13 dholland Exp $	*/
+/*	$NetBSD: lfs_balloc.c,v 1.86 2015/08/02 18:18:46 dholland Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
@@ -60,7 +60,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: lfs_balloc.c,v 1.85 2015/08/02 18:08:13 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lfs_balloc.c,v 1.86 2015/08/02 18:18:46 dholland Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_quota.h"
@@ -219,8 +219,7 @@ lfs_balloc(struct vnode *vp, off_t start
 	if (error)
 		return (error);
 
-	daddr = (daddr_t)((int32_t)daddr); /* XXX ondisk32 */
-	KASSERT(daddr <= LFS_MAX_DADDR);
+	KASSERT(daddr <= LFS_MAX_DADDR(fs));
 
 	/*
 	 * Do byte accounting all at once, so we can gracefully fail *before*

Index: src/sys/ufs/lfs/lfs_segment.c
diff -u src/sys/ufs/lfs/lfs_segment.c:1.250 src/sys/ufs/lfs/lfs_segment.c:1.251
--- src/sys/ufs/lfs/lfs_segment.c:1.250	Sun Aug  2 18:18:10 2015
+++ src/sys/ufs/lfs/lfs_segment.c	Sun Aug  2 18:18:46 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: lfs_segment.c,v 1.250 2015/08/02 18:18:10 dholland Exp $	*/
+/*	$NetBSD: lfs_segment.c,v 1.251 2015/08/02 18:18:46 dholland Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
@@ -60,7 +60,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: lfs_segment.c,v 1.250 2015/08/02 18:18:10 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lfs_segment.c,v 1.251 2015/08/02 18:18:46 dholland Exp $");
 
 #define _VFS_VNODE_PRIVATE	/* XXX: check for VI_MARKER, this has to go */
 
@@ -1473,8 +1473,7 @@ lfs_update_single(struct lfs *fs, struct
 	if (error)
 		panic("lfs_updatemeta: ulfs_bmaparray returned %d", error);
 
-	daddr = (daddr_t)((int32_t)daddr); /* XXX ondisk32 */
-	KASSERT(daddr <= LFS_MAX_DADDR);
+	KASSERT(daddr <= LFS_MAX_DADDR(fs));
 	if (daddr > 0)
 		daddr = LFS_DBTOFSB(fs, daddr);
 

Index: src/sys/ufs/lfs/lfs_vfsops.c
diff -u src/sys/ufs/lfs/lfs_vfsops.c:1.333 src/sys/ufs/lfs/lfs_vfsops.c:1.334
--- src/sys/ufs/lfs/lfs_vfsops.c:1.333	Sun Aug  2 18:18:10 2015
+++ src/sys/ufs/lfs/lfs_vfsops.c	Sun Aug  2 18:18:46 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: lfs_vfsops.c,v 1.333 2015/08/02 18:18:10 dholland Exp $	*/
+/*	$NetBSD: lfs_vfsops.c,v 1.334 2015/08/02 18:18:46 dholland Exp $	*/
 
 /*-
  * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2007, 2007
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: lfs_vfsops.c,v 1.333 2015/08/02 18:18:10 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: lfs_vfsops.c,v 1.334 2015/08/02 18:18:46 dholland Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_lfs.h"
@@ -1826,9 +1826,9 @@ lfs_issequential_hole(const struct lfs *
 	daddr1 = (daddr_t)((int32_t)daddr1); /* XXX ondisk32 */
 
 	KASSERT(daddr0 == UNWRITTEN ||
-	    (0 <= daddr0 && daddr0 <= LFS_MAX_DADDR));
+	    (0 <= daddr0 && daddr0 <= LFS_MAX_DADDR(fs)));
 	KASSERT(daddr1 == UNWRITTEN ||
-	    (0 <= daddr1 && daddr1 <= LFS_MAX_DADDR));
+	    (0 <= daddr1 && daddr1 <= LFS_MAX_DADDR(fs)));
 
 	/* NOTE: all we want to know here is 'hole or not'. */
 	/* NOTE: UNASSIGNED is converted to 0 by ulfs_bmaparray. */

Index: src/sys/ufs/lfs/ulfs_bmap.c
diff -u src/sys/ufs/lfs/ulfs_bmap.c:1.5 src/sys/ufs/lfs/ulfs_bmap.c:1.6
--- src/sys/ufs/lfs/ulfs_bmap.c:1.5	Sun Jul 28 01:10:49 2013
+++ src/sys/ufs/lfs/ulfs_bmap.c	Sun Aug  2 18:18:46 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: ulfs_bmap.c,v 1.5 2013/07/28 01:10:49 dholland Exp $	*/
+/*	$NetBSD: ulfs_bmap.c,v 1.6 2015/08/02 18:18:46 dholland Exp $	*/
 /*  from NetBSD: ufs_bmap.c,v 1.50 2013/01/22 09:39:18 dholland Exp  */
 
 /*
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ulfs_bmap.c,v 1.5 2013/07/28 01:10:49 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ulfs_bmap.c,v 1.6 2015/08/02 18:18:46 dholland Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -70,6 +70,24 @@ ulfs_issequential(const struct lfs *fs, 
 }
 
 /*
+ * This is used for block pointers in inodes and elsewhere, which can
+ * contain the magic value UNWRITTEN, which is -2. This is mishandled
+ * by u32 -> u64 promotion unless special-cased.
+ *
+ * XXX this should be rolled into better inode accessors and go away.
+ */
+static inline uint64_t
+ulfs_fix_unwritten(uint32_t val)
+{
+	if (val == (uint32_t)UNWRITTEN) {
+		return (uint64_t)(int64_t)UNWRITTEN;
+	} else {
+		return val;
+	}
+}
+
+
+/*
  * Bmap converts the logical block number of a file to its physical block
  * number on the disk. The conversion is done by using the logical block
  * number to index into the array of block pointers described by the dinode.
@@ -154,8 +172,8 @@ ulfs_bmaparray(struct vnode *vp, daddr_t
 		if (nump != NULL)
 			*nump = 0;
 		if (ump->um_fstype == ULFS1)
-			daddr = ulfs_rw32(ip->i_ffs1_db[bn],
-			    ULFS_MPNEEDSWAP(fs));
+			daddr = ulfs_fix_unwritten(ulfs_rw32(ip->i_ffs1_db[bn],
+			    ULFS_MPNEEDSWAP(fs)));
 		else
 			daddr = ulfs_rw64(ip->i_ffs2_db[bn],
 			    ULFS_MPNEEDSWAP(fs));
@@ -183,10 +201,10 @@ ulfs_bmaparray(struct vnode *vp, daddr_t
 			if (ump->um_fstype == ULFS1) {
 				for (++bn; bn < ULFS_NDADDR && *runp < maxrun &&
 				    is_sequential(fs,
-				        ulfs_rw32(ip->i_ffs1_db[bn - 1],
-				            ULFS_MPNEEDSWAP(fs)),
-				        ulfs_rw32(ip->i_ffs1_db[bn],
-				            ULFS_MPNEEDSWAP(fs)));
+				        ulfs_fix_unwritten(ulfs_rw32(ip->i_ffs1_db[bn - 1],
+				            ULFS_MPNEEDSWAP(fs))),
+				        ulfs_fix_unwritten(ulfs_rw32(ip->i_ffs1_db[bn],
+				            ULFS_MPNEEDSWAP(fs))));
 				    ++bn, ++*runp);
 			} else {
 				for (++bn; bn < ULFS_NDADDR && *runp < maxrun &&
@@ -211,8 +229,8 @@ ulfs_bmaparray(struct vnode *vp, daddr_t
 
 	/* Get disk address out of indirect block array */
 	if (ump->um_fstype == ULFS1)
-		daddr = ulfs_rw32(ip->i_ffs1_ib[xap->in_off],
-		    ULFS_MPNEEDSWAP(fs));
+		daddr = ulfs_fix_unwritten(ulfs_rw32(ip->i_ffs1_ib[xap->in_off],
+		    ULFS_MPNEEDSWAP(fs)));
 	else
 		daddr = ulfs_rw64(ip->i_ffs2_ib[xap->in_off],
 		    ULFS_MPNEEDSWAP(fs));
@@ -274,16 +292,16 @@ ulfs_bmaparray(struct vnode *vp, daddr_t
 			}
 		}
 		if (ump->um_fstype == ULFS1) {
-			daddr = ulfs_rw32(((u_int32_t *)bp->b_data)[xap->in_off],
-			    ULFS_MPNEEDSWAP(fs));
+			daddr = ulfs_fix_unwritten(ulfs_rw32(((u_int32_t *)bp->b_data)[xap->in_off],
+			    ULFS_MPNEEDSWAP(fs)));
 			if (num == 1 && daddr && runp) {
 				for (bn = xap->in_off + 1;
 				    bn < MNINDIR(fs) && *runp < maxrun &&
 				    is_sequential(fs,
-				        ulfs_rw32(((int32_t *)bp->b_data)[bn-1],
-				            ULFS_MPNEEDSWAP(fs)),
-				        ulfs_rw32(((int32_t *)bp->b_data)[bn],
-				            ULFS_MPNEEDSWAP(fs)));
+				        ulfs_fix_unwritten(ulfs_rw32(((int32_t *)bp->b_data)[bn-1],
+				            ULFS_MPNEEDSWAP(fs))),
+				        ulfs_fix_unwritten(ulfs_rw32(((int32_t *)bp->b_data)[bn],
+				            ULFS_MPNEEDSWAP(fs))));
 				    ++bn, ++*runp);
 			}
 		} else {

Reply via email to