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 {