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 {