diff options
| author | dholland <dholland@NetBSD.org> | 2015-08-02 18:18:46 +0000 |
|---|---|---|
| committer | dholland <dholland@NetBSD.org> | 2015-08-02 18:18:46 +0000 |
| commit | 0452e472993c7542fb1b8ef2bbeede4e9ded07b2 (patch) | |
| tree | d205bf092e5157f6cbee18f0c5945e1561f38f2b /sys/ufs | |
| parent | ce7ab97df2d93f089223154db810050d22f81163 (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.h | 4 | ||||
| -rw-r--r-- | sys/ufs/lfs/lfs_accessors.h | 6 | ||||
| -rw-r--r-- | sys/ufs/lfs/lfs_balloc.c | 7 | ||||
| -rw-r--r-- | sys/ufs/lfs/lfs_segment.c | 7 | ||||
| -rw-r--r-- | sys/ufs/lfs/lfs_vfsops.c | 8 | ||||
| -rw-r--r-- | sys/ufs/lfs/ulfs_bmap.c | 50 |
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 { |
