]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
Make sure xfs_repair detects invalid btree roots in inodes
authorBarry Naujok <bnaujok@sgi.com>
Fri, 16 Mar 2007 03:00:32 +0000 (03:00 +0000)
committerBarry Naujok <bnaujok@sgi.com>
Fri, 16 Mar 2007 03:00:32 +0000 (03:00 +0000)
Merge of master-melb:xfs-cmds:28254a by kenmcd.

  Bump version to 2.8.20

VERSION
debian/changelog
doc/CHANGES
io/pwrite.c
repair/dinode.c
repair/dir2.c

diff --git a/VERSION b/VERSION
index 5acea625932518d40af077a81b1ae541bd92f435..f70b7c9c83ee56229138336021fc08d0ed0582b1 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -3,5 +3,5 @@
 #
 PKG_MAJOR=2
 PKG_MINOR=8
-PKG_REVISION=19
+PKG_REVISION=20
 PKG_BUILD=1
index 39c799e5af9e83b3f1846b4cb7f8c3472e583290..62684858784527cf03ea31c4bb638cb9daac968a 100644 (file)
@@ -1,3 +1,10 @@
+xfsprogs (2.8.20-1) unstable; urgency=low
+
+  * New upstream release (closes: #414079)
+  * Fixed up autoconf version dependency (closes: #414073)
+
+ -- Nathan Scott <nathans@debian.org>  Fri, 16 Mar 2007 08:24:33 +1100
+
 xfsprogs (2.8.19-1) unstable; urgency=low
 
   * New upstream release (closes: #409063)
index 4473ed2a356ae03652a98041ac94cd419bd036b7..3d7e8c8b813119327b6ffb1e5dd8e7172c65e5e0 100644 (file)
@@ -1,6 +1,10 @@
-xfsprogs-2.8.XX
+xfsprogs-2.8.20 (23 February 2007)
+       - Fix xfs_repair not detecting invalid btree root in inodes.
+       - Fix xfs_repair restoring corrupted superblock after repairing it.
+       - Fix xfs_repair crashing on invalid quota inode values.
        - Fix xfs_quota gracetime reporting.
          Thanks to Utako Kusaka <utako@tnes.nec.co.jp> for this.
+       - Fix libxfs IO_DEBUG output.
        - Instead of using AC_CHECK_TYPES which isn't supported for
          older versions of autoconf, add our own type check in the
          m4/package_types.m4 file for __u32.
@@ -27,7 +31,7 @@ xfsprogs-2.8.18 (8 December 2006)
          Thanks to Utako Kusaka <utako@tnes.nec.co.jp> for the above three
          fixes.
 
-xfsprogs-2.8.17 (?)
+xfsprogs-2.8.17 (5 December 2006)
        - Fix up libxfs SEGV when attempting to mount a non-XFS filesystem.
          Thanks to Utako Kusaka <utako@tnes.nec.co.jp> for this.
        - Fix up xfs_repair aborting if it finds an inode with an invalid
index ca12a5b8270f55ac69cbca669509e0879781bd3e..54c3f782022165848d4ff1024a7711f93dbeb6dc 100644 (file)
@@ -310,6 +310,7 @@ pwrite_f(
                c = write_backward(offset, &count, &total);
                break;
        default:
+               total = 0;
                ASSERT(0);
        }
        if (c < 0)
index b237319782d88baaf0bc5daf3975cda9a3a9ae62..eba620cea9024be98eb553c770e6ddbcaf226cd6 100644 (file)
@@ -307,8 +307,8 @@ clear_dinode(xfs_mount_t *mp, xfs_dinode_t *dino, xfs_ino_t ino_num)
  * misc. inode-related utility routines
  */
 
-/* 
- * verify_ag_bno is heavily used. In the common case, it 
+/*
+ * verify_ag_bno is heavily used. In the common case, it
  * performs just two number of compares
  */
 static __inline int
@@ -802,7 +802,7 @@ process_bmbt_reclist_int(
                                PROCESS_BMBT_UNLOCK_RETURN(1);
                        }
 
-                       /* Process in chunks of 16 (XR_BB_UNIT/XR_BB) 
+                       /* Process in chunks of 16 (XR_BB_UNIT/XR_BB)
                         * for common XR_E_UNKNOWN to XR_E_INUSE transition
                         */
                        if (((agbno & XR_BB_MASK) == 0) && ((s + c - b) >= (XR_BB_UNIT/XR_BB))) {
@@ -1223,6 +1223,8 @@ process_btinode(
        xfs_bmbt_key_t          *pkey;
        char                    *forkname;
        int                     i;
+       int                     level;
+       int                     numrecs;
        bmap_cursor_t           cursor;
 
        dib = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork);
@@ -1235,13 +1237,11 @@ process_btinode(
        else
                forkname = _("attr");
 
-       if (INT_GET(dib->bb_level, ARCH_CONVERT) == 0) {
+       level = INT_GET(dib->bb_level, ARCH_CONVERT);
+       numrecs = INT_GET(dib->bb_numrecs, ARCH_CONVERT);
+
+       if ((level == 0) || (level > XFS_BM_MAXLEVELS(mp, whichfork))) {
                /*
-                * This should never happen since a btree inode
-                * has to have at least one other block in the
-                * bmap in addition to the root block in the
-                * inode's data fork.
-                *
                 * XXX - if we were going to fix up the inode,
                 * we'd try to treat the fork as an interior
                 * node and see if we could get an accurate
@@ -1249,28 +1249,30 @@ process_btinode(
                 * to by the pointers in the fork.  For now
                 * though, we just bail (and blow out the inode).
                 */
-               do_warn(_("bad level 0 in inode %llu bmap btree root block\n"),
+               do_warn(_("bad level %d in inode %llu bmap btree root block\n"),
+                       level, XFS_AGINO_TO_INO(mp, agno, ino));
+               return(1);
+       }
+       if (numrecs == 0) {
+               do_warn(_("bad numrecs 0 in inode %llu bmap btree root block\n"),
                        XFS_AGINO_TO_INO(mp, agno, ino));
                return(1);
        }
        /*
         * use bmdr/dfork_dsize since the root block is in the data fork
         */
-       init_bm_cursor(&cursor, INT_GET(dib->bb_level, ARCH_CONVERT) + 1);
-
-       if (XFS_BMDR_SPACE_CALC(INT_GET(dib->bb_numrecs, ARCH_CONVERT)) >
-                       ((whichfork == XFS_DATA_FORK) ?
+       if (XFS_BMDR_SPACE_CALC(numrecs) > ((whichfork == XFS_DATA_FORK) ?
                        XFS_DFORK_DSIZE(dip, mp) :
                        XFS_DFORK_ASIZE(dip, mp)))  {
                do_warn(
        _("indicated size of %s btree root (%d bytes) greater than space in "
          "inode %llu %s fork\n"),
-                       forkname, XFS_BMDR_SPACE_CALC(INT_GET(dib->bb_numrecs,
-                               ARCH_CONVERT)),
-                       lino, forkname);
+                       forkname, XFS_BMDR_SPACE_CALC(numrecs), lino, forkname);
                return(1);
        }
 
+       init_bm_cursor(&cursor, level + 1);
+
        pp = XFS_BTREE_PTR_ADDR(
                        XFS_DFORK_SIZE(dip, mp, whichfork),
                xfs_bmdr, dib, 1,
@@ -1286,7 +1288,7 @@ process_btinode(
 
        last_key = NULLDFILOFF;
 
-       for (i = 0; i < INT_GET(dib->bb_numrecs, ARCH_CONVERT); i++)  {
+       for (i = 0; i < numrecs; i++)  {
                /*
                 * XXX - if we were going to do more to fix up the inode
                 * btree, we'd do it right here.  For now, if there's a
@@ -1298,8 +1300,8 @@ process_btinode(
                        return(1);
                }
 
-               if (scan_lbtree((xfs_dfsbno_t)INT_GET(pp[i], ARCH_CONVERT), INT_GET(dib->bb_level, ARCH_CONVERT),
-                                   scanfunc_bmap, type, whichfork,
+               if (scan_lbtree((xfs_dfsbno_t)INT_GET(pp[i], ARCH_CONVERT),
+                                   level, scanfunc_bmap, type, whichfork,
                                    lino, tot, nex, blkmapp, &cursor,
                                    1, check_dups))
                        return(1);
@@ -1310,8 +1312,7 @@ process_btinode(
                 * blocks but the parent hasn't been updated
                 */
                if (check_dups == 0 &&
-                   cursor.level[INT_GET(dib->bb_level,
-                               ARCH_CONVERT)-1].first_key !=
+                   cursor.level[level-1].first_key !=
                    INT_GET(pkey[i].br_startoff, ARCH_CONVERT))  {
                        if (!no_modify)  {
                                do_warn(
@@ -1319,22 +1320,19 @@ process_btinode(
          "%llu %s fork\n"),
                                        INT_GET(pkey[i].br_startoff,
                                                ARCH_CONVERT),
-                                       cursor.level[INT_GET(dib->bb_level,
-                                               ARCH_CONVERT)-1].first_key,
+                                       cursor.level[level-1].first_key,
                                        XFS_AGINO_TO_INO(mp, agno, ino),
                                        forkname);
                                *dirty = 1;
                                INT_SET(pkey[i].br_startoff, ARCH_CONVERT,
-                                       cursor.level[INT_GET(dib->bb_level,
-                                               ARCH_CONVERT)-1].first_key);
+                                       cursor.level[level-1].first_key);
                        } else  {
                                do_warn(
        _("bad key in bmbt root (is %llu, would reset to %llu) in inode "
          "%llu %s fork\n"),
                                        INT_GET(pkey[i].br_startoff,
                                                ARCH_CONVERT),
-                                       cursor.level[INT_GET(dib->bb_level,
-                                               ARCH_CONVERT)-1].first_key,
+                                       cursor.level[level-1].first_key,
                                        XFS_AGINO_TO_INO(mp, agno, ino),
                                        forkname);
                        }
@@ -1345,8 +1343,7 @@ process_btinode(
                 */
                if (check_dups == 0)  {
                        if (last_key != NULLDFILOFF && last_key >=
-                           cursor.level[INT_GET(dib->bb_level,
-                                       ARCH_CONVERT)-1].first_key)  {
+                           cursor.level[level-1].first_key)  {
                                do_warn(
                _("out of order bmbt root key %llu in inode %llu %s fork\n"),
                                        first_key,
@@ -1354,8 +1351,7 @@ process_btinode(
                                        forkname);
                                return(1);
                        }
-                       last_key = cursor.level[INT_GET(dib->bb_level,
-                                               ARCH_CONVERT)-1].first_key;
+                       last_key = cursor.level[level-1].first_key;
                }
        }
        /*
@@ -2064,9 +2060,9 @@ process_dinode_int(xfs_mount_t *mp,
                if (!verify_mode)  {
                        do_warn(_("bad inode type %#o inode %llu\n"),
                                (int) (INT_GET(dinoc->di_mode, ARCH_CONVERT) & S_IFMT), lino);
-                       if (!no_modify)  
+                       if (!no_modify)
                                *dirty += clear_dinode(mp, dino, lino);
-                       else 
+                       else
                                *dirty = 1;
                        *cleared = 1;
                        *used = is_free;
index 4687c7b9dc808d2bb28704521936fed7beeced1d..46240769ff0b0337982c1d389350237154a74805 100644 (file)
@@ -1805,6 +1805,7 @@ process_leaf_level_dir2(
        prev_bno = 0;
        bmp = NULL;
        current_hashval = 0;
+       greatest_hashval = 0;
        buf_dirty = 0;
 
        do {