Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/ufs/lfs Pass the fs object to LFS_MAX_DADDR so it can ch...



details:   https://anonhg.NetBSD.org/src/rev/bc79e3477ca5
branches:  trunk
changeset: 339669:bc79e3477ca5
user:      dholland <dholland%NetBSD.org@localhost>
date:      Sun Aug 02 18:18:46 2015 +0000

description:
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:

 sys/ufs/lfs/lfs.h           |   4 +--
 sys/ufs/lfs/lfs_accessors.h |   6 ++++-
 sys/ufs/lfs/lfs_balloc.c    |   7 ++---
 sys/ufs/lfs/lfs_segment.c   |   7 ++---
 sys/ufs/lfs/lfs_vfsops.c    |   8 +++---
 sys/ufs/lfs/ulfs_bmap.c     |  50 ++++++++++++++++++++++++++++++--------------
 6 files changed, 50 insertions(+), 32 deletions(-)

diffs (227 lines):

diff -r d5921f29e57b -r bc79e3477ca5 sys/ufs/lfs/lfs.h
--- a/sys/ufs/lfs/lfs.h Sun Aug 02 18:18:09 2015 +0000
+++ b/sys/ufs/lfs/lfs.h Sun Aug 02 18:18:46 2015 +0000
@@ -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 -r d5921f29e57b -r bc79e3477ca5 sys/ufs/lfs/lfs_accessors.h
--- a/sys/ufs/lfs/lfs_accessors.h       Sun Aug 02 18:18:09 2015 +0000
+++ b/sys/ufs/lfs/lfs_accessors.h       Sun Aug 02 18:18:46 2015 +0000
@@ -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 @@
        }
 }
 
+/* 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 -r d5921f29e57b -r bc79e3477ca5 sys/ufs/lfs/lfs_balloc.c
--- a/sys/ufs/lfs/lfs_balloc.c  Sun Aug 02 18:18:09 2015 +0000
+++ b/sys/ufs/lfs/lfs_balloc.c  Sun Aug 02 18:18:46 2015 +0000
@@ -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 @@
        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 -r d5921f29e57b -r bc79e3477ca5 sys/ufs/lfs/lfs_segment.c
--- a/sys/ufs/lfs/lfs_segment.c Sun Aug 02 18:18:09 2015 +0000
+++ b/sys/ufs/lfs/lfs_segment.c Sun Aug 02 18:18:46 2015 +0000
@@ -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 @@
        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 -r d5921f29e57b -r bc79e3477ca5 sys/ufs/lfs/lfs_vfsops.c
--- a/sys/ufs/lfs/lfs_vfsops.c  Sun Aug 02 18:18:09 2015 +0000
+++ b/sys/ufs/lfs/lfs_vfsops.c  Sun Aug 02 18:18:46 2015 +0000
@@ -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 @@
        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 -r d5921f29e57b -r bc79e3477ca5 sys/ufs/lfs/ulfs_bmap.c
--- a/sys/ufs/lfs/ulfs_bmap.c   Sun Aug 02 18:18:09 2015 +0000
+++ b/sys/ufs/lfs/ulfs_bmap.c   Sun Aug 02 18:18:46 2015 +0000
@@ -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 @@
 }
 
 /*
+ * 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 @@
                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 @@
                        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 @@
 
        /* 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 @@
                        }
                }
                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 {



Home | Main Index | Thread Index | Old Index