summaryrefslogtreecommitdiff
path: root/sys/ufs
diff options
context:
space:
mode:
authordholland <dholland@NetBSD.org>2015-08-02 18:18:46 +0000
committerdholland <dholland@NetBSD.org>2015-08-02 18:18:46 +0000
commit0452e472993c7542fb1b8ef2bbeede4e9ded07b2 (patch)
treed205bf092e5157f6cbee18f0c5945e1561f38f2b /sys/ufs
parentce7ab97df2d93f089223154db810050d22f81163 (diff)
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.
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/lfs/lfs.h4
-rw-r--r--sys/ufs/lfs/lfs_accessors.h6
-rw-r--r--sys/ufs/lfs/lfs_balloc.c7
-rw-r--r--sys/ufs/lfs/lfs_segment.c7
-rw-r--r--sys/ufs/lfs/lfs_vfsops.c8
-rw-r--r--sys/ufs/lfs/ulfs_bmap.c50
6 files changed, 50 insertions, 32 deletions
diff --git a/sys/ufs/lfs/lfs.h b/sys/ufs/lfs/lfs.h
index 56ccc41f15d..7c13b929d22 100644
--- a/sys/ufs/lfs/lfs.h
+++ b/sys/ufs/lfs/lfs.h
@@ -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
diff --git a/sys/ufs/lfs/lfs_accessors.h b/sys/ufs/lfs/lfs_accessors.h
index 3dea004d102..8fb930cdc29 100644
--- a/sys/ufs/lfs/lfs_accessors.h
+++ b/sys/ufs/lfs/lfs_accessors.h
@@ -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 char *str)
}
}
+/* 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))
diff --git a/sys/ufs/lfs/lfs_balloc.c b/sys/ufs/lfs/lfs_balloc.c
index ebff6f60755..3aaaf64d885 100644
--- a/sys/ufs/lfs/lfs_balloc.c
+++ b/sys/ufs/lfs/lfs_balloc.c
@@ -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 startoffset, int iosize, kauth_cred_t cred,
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*
diff --git a/sys/ufs/lfs/lfs_segment.c b/sys/ufs/lfs/lfs_segment.c
index b1cabdf9299..9c9dcf11abf 100644
--- a/sys/ufs/lfs/lfs_segment.c
+++ b/sys/ufs/lfs/lfs_segment.c
@@ -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 segment *sp,
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);
diff --git a/sys/ufs/lfs/lfs_vfsops.c b/sys/ufs/lfs/lfs_vfsops.c
index 8ea909512e3..47211bb919f 100644
--- a/sys/ufs/lfs/lfs_vfsops.c
+++ b/sys/ufs/lfs/lfs_vfsops.c
@@ -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 *fs,
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. */
diff --git a/sys/ufs/lfs/ulfs_bmap.c b/sys/ufs/lfs/ulfs_bmap.c
index 6d299410e6c..50ee343a36f 100644
--- a/sys/ufs/lfs/ulfs_bmap.c
+++ b/sys/ufs/lfs/ulfs_bmap.c
@@ -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, daddr_t daddr0, daddr_t daddr1)
}
/*
+ * 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 bn, daddr_t *bnp, struct indir *ap,
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 bn, daddr_t *bnp, struct indir *ap,
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 bn, daddr_t *bnp, struct indir *ap,
/* 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 bn, daddr_t *bnp, struct indir *ap,
}
}
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 {