]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - fs/xfs/xfs_bmap.c
[XFS] Allow xfs_bmbt_split() to fallback to the lowspace allocator
[mv-sheeva.git] / fs / xfs / xfs_bmap.c
index 65b8fa83e078da2ce7386b911eb62b39b3b0d3db..cf4dee01983aa71594041415c6742d7ff30d2e9d 100644 (file)
@@ -428,7 +428,8 @@ xfs_bmap_add_attrfork_btree(
                cur->bc_private.b.firstblock = *firstblock;
                if ((error = xfs_bmbt_lookup_ge(cur, 0, 0, 0, &stat)))
                        goto error0;
-               ASSERT(stat == 1);      /* must be at least one entry */
+               /* must be at least one entry */
+               XFS_WANT_CORRUPTED_GOTO(stat == 1, error0);
                if ((error = xfs_bmbt_newroot(cur, flags, &stat)))
                        goto error0;
                if (stat == 0) {
@@ -816,13 +817,13 @@ xfs_bmap_add_extent_delay_real(
                                        RIGHT.br_startblock,
                                        RIGHT.br_blockcount, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_delete(cur, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_decrement(cur, 0, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_update(cur, LEFT.br_startoff,
                                        LEFT.br_startblock,
                                        LEFT.br_blockcount +
@@ -860,7 +861,7 @@ xfs_bmap_add_extent_delay_real(
                                        LEFT.br_startblock, LEFT.br_blockcount,
                                        &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_update(cur, LEFT.br_startoff,
                                        LEFT.br_startblock,
                                        LEFT.br_blockcount +
@@ -895,7 +896,7 @@ xfs_bmap_add_extent_delay_real(
                                        RIGHT.br_startblock,
                                        RIGHT.br_blockcount, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_update(cur, PREV.br_startoff,
                                        new->br_startblock,
                                        PREV.br_blockcount +
@@ -928,11 +929,11 @@ xfs_bmap_add_extent_delay_real(
                                        new->br_startblock, new->br_blockcount,
                                        &i)))
                                goto done;
-                       ASSERT(i == 0);
+                       XFS_WANT_CORRUPTED_GOTO(i == 0, done);
                        cur->bc_rec.b.br_state = XFS_EXT_NORM;
                        if ((error = xfs_bmbt_insert(cur, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                }
                *dnew = 0;
                /* DELTA: The in-core extent described by new changed type. */
@@ -963,7 +964,7 @@ xfs_bmap_add_extent_delay_real(
                                        LEFT.br_startblock, LEFT.br_blockcount,
                                        &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_update(cur, LEFT.br_startoff,
                                        LEFT.br_startblock,
                                        LEFT.br_blockcount +
@@ -1004,11 +1005,11 @@ xfs_bmap_add_extent_delay_real(
                                        new->br_startblock, new->br_blockcount,
                                        &i)))
                                goto done;
-                       ASSERT(i == 0);
+                       XFS_WANT_CORRUPTED_GOTO(i == 0, done);
                        cur->bc_rec.b.br_state = XFS_EXT_NORM;
                        if ((error = xfs_bmbt_insert(cur, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                }
                if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS &&
                    ip->i_d.di_nextents > ip->i_df.if_ext_max) {
@@ -1054,7 +1055,7 @@ xfs_bmap_add_extent_delay_real(
                                        RIGHT.br_startblock,
                                        RIGHT.br_blockcount, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_update(cur, new->br_startoff,
                                        new->br_startblock,
                                        new->br_blockcount +
@@ -1094,11 +1095,11 @@ xfs_bmap_add_extent_delay_real(
                                        new->br_startblock, new->br_blockcount,
                                        &i)))
                                goto done;
-                       ASSERT(i == 0);
+                       XFS_WANT_CORRUPTED_GOTO(i == 0, done);
                        cur->bc_rec.b.br_state = XFS_EXT_NORM;
                        if ((error = xfs_bmbt_insert(cur, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                }
                if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS &&
                    ip->i_d.di_nextents > ip->i_df.if_ext_max) {
@@ -1149,11 +1150,11 @@ xfs_bmap_add_extent_delay_real(
                                        new->br_startblock, new->br_blockcount,
                                        &i)))
                                goto done;
-                       ASSERT(i == 0);
+                       XFS_WANT_CORRUPTED_GOTO(i == 0, done);
                        cur->bc_rec.b.br_state = XFS_EXT_NORM;
                        if ((error = xfs_bmbt_insert(cur, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                }
                if (ip->i_d.di_format == XFS_DINODE_FMT_EXTENTS &&
                    ip->i_d.di_nextents > ip->i_df.if_ext_max) {
@@ -1377,19 +1378,19 @@ xfs_bmap_add_extent_unwritten_real(
                                        RIGHT.br_startblock,
                                        RIGHT.br_blockcount, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_delete(cur, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_decrement(cur, 0, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_delete(cur, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_decrement(cur, 0, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_update(cur, LEFT.br_startoff,
                                LEFT.br_startblock,
                                LEFT.br_blockcount + PREV.br_blockcount +
@@ -1426,13 +1427,13 @@ xfs_bmap_add_extent_unwritten_real(
                                        PREV.br_startblock, PREV.br_blockcount,
                                        &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_delete(cur, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_decrement(cur, 0, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_update(cur, LEFT.br_startoff,
                                LEFT.br_startblock,
                                LEFT.br_blockcount + PREV.br_blockcount,
@@ -1469,13 +1470,13 @@ xfs_bmap_add_extent_unwritten_real(
                                        RIGHT.br_startblock,
                                        RIGHT.br_blockcount, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_delete(cur, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_decrement(cur, 0, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_update(cur, new->br_startoff,
                                new->br_startblock,
                                new->br_blockcount + RIGHT.br_blockcount,
@@ -1508,7 +1509,7 @@ xfs_bmap_add_extent_unwritten_real(
                                        new->br_startblock, new->br_blockcount,
                                        &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_update(cur, new->br_startoff,
                                new->br_startblock, new->br_blockcount,
                                newext)))
@@ -1549,7 +1550,7 @@ xfs_bmap_add_extent_unwritten_real(
                                        PREV.br_startblock, PREV.br_blockcount,
                                        &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_update(cur,
                                PREV.br_startoff + new->br_blockcount,
                                PREV.br_startblock + new->br_blockcount,
@@ -1596,7 +1597,7 @@ xfs_bmap_add_extent_unwritten_real(
                                        PREV.br_startblock, PREV.br_blockcount,
                                        &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_update(cur,
                                PREV.br_startoff + new->br_blockcount,
                                PREV.br_startblock + new->br_blockcount,
@@ -1606,7 +1607,7 @@ xfs_bmap_add_extent_unwritten_real(
                        cur->bc_rec.b = *new;
                        if ((error = xfs_bmbt_insert(cur, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                }
                /* DELTA: One in-core extent is split in two. */
                temp = PREV.br_startoff;
@@ -1640,7 +1641,7 @@ xfs_bmap_add_extent_unwritten_real(
                                        PREV.br_startblock,
                                        PREV.br_blockcount, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_update(cur, PREV.br_startoff,
                                PREV.br_startblock,
                                PREV.br_blockcount - new->br_blockcount,
@@ -1682,7 +1683,7 @@ xfs_bmap_add_extent_unwritten_real(
                                        PREV.br_startblock, PREV.br_blockcount,
                                        &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_update(cur, PREV.br_startoff,
                                PREV.br_startblock,
                                PREV.br_blockcount - new->br_blockcount,
@@ -1692,11 +1693,11 @@ xfs_bmap_add_extent_unwritten_real(
                                        new->br_startblock, new->br_blockcount,
                                        &i)))
                                goto done;
-                       ASSERT(i == 0);
+                       XFS_WANT_CORRUPTED_GOTO(i == 0, done);
                        cur->bc_rec.b.br_state = XFS_EXT_NORM;
                        if ((error = xfs_bmbt_insert(cur, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                }
                /* DELTA: One in-core extent is split in two. */
                temp = PREV.br_startoff;
@@ -1732,7 +1733,7 @@ xfs_bmap_add_extent_unwritten_real(
                                        PREV.br_startblock, PREV.br_blockcount,
                                        &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        /* new right extent - oldext */
                        if ((error = xfs_bmbt_update(cur, r[1].br_startoff,
                                r[1].br_startblock, r[1].br_blockcount,
@@ -1744,15 +1745,22 @@ xfs_bmap_add_extent_unwritten_real(
                        cur->bc_rec.b = PREV;
                        if ((error = xfs_bmbt_insert(cur, &i)))
                                goto done;
-                       ASSERT(i == 1);
-                       if ((error = xfs_bmbt_increment(cur, 0, &i)))
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
+                       /*
+                        * Reset the cursor to the position of the new extent
+                        * we are about to insert as we can't trust it after
+                        * the previous insert.
+                        */
+                       if ((error = xfs_bmbt_lookup_eq(cur, new->br_startoff,
+                                       new->br_startblock, new->br_blockcount,
+                                       &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 0, done);
                        /* new middle extent - newext */
-                       cur->bc_rec.b = *new;
+                       cur->bc_rec.b.br_state = new->br_state;
                        if ((error = xfs_bmbt_insert(cur, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                }
                /* DELTA: One in-core extent is split in three. */
                temp = PREV.br_startoff;
@@ -2097,13 +2105,13 @@ xfs_bmap_add_extent_hole_real(
                                        right.br_startblock,
                                        right.br_blockcount, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_delete(cur, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_decrement(cur, 0, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_update(cur, left.br_startoff,
                                        left.br_startblock,
                                        left.br_blockcount +
@@ -2139,7 +2147,7 @@ xfs_bmap_add_extent_hole_real(
                                        left.br_startblock,
                                        left.br_blockcount, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_update(cur, left.br_startoff,
                                        left.br_startblock,
                                        left.br_blockcount +
@@ -2174,7 +2182,7 @@ xfs_bmap_add_extent_hole_real(
                                        right.br_startblock,
                                        right.br_blockcount, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        if ((error = xfs_bmbt_update(cur, new->br_startoff,
                                        new->br_startblock,
                                        new->br_blockcount +
@@ -2208,11 +2216,11 @@ xfs_bmap_add_extent_hole_real(
                                        new->br_startblock,
                                        new->br_blockcount, &i)))
                                goto done;
-                       ASSERT(i == 0);
+                       XFS_WANT_CORRUPTED_GOTO(i == 0, done);
                        cur->bc_rec.b.br_state = new->br_state;
                        if ((error = xfs_bmbt_insert(cur, &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                }
                /* DELTA: A new extent was added in a hole. */
                temp = new->br_startoff;
@@ -2402,7 +2410,7 @@ xfs_bmap_extsize_align(
 
 #define XFS_ALLOC_GAP_UNITS    4
 
-STATIC int
+STATIC void
 xfs_bmap_adjacent(
        xfs_bmalloca_t  *ap)            /* bmap alloc argument struct */
 {
@@ -2548,7 +2556,6 @@ xfs_bmap_adjacent(
                        ap->rval = gotbno;
        }
 #undef ISVALID
-       return 0;
 }
 
 STATIC int
@@ -3132,7 +3139,7 @@ xfs_bmap_del_extent(
                                        got.br_startblock, got.br_blockcount,
                                        &i)))
                                goto done;
-                       ASSERT(i == 1);
+                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                }
                da_old = da_new = 0;
        } else {
@@ -3165,7 +3172,7 @@ xfs_bmap_del_extent(
                }
                if ((error = xfs_bmbt_delete(cur, &i)))
                        goto done;
-               ASSERT(i == 1);
+               XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                break;
 
        case 2:
@@ -3269,7 +3276,7 @@ xfs_bmap_del_extent(
                                                        got.br_startblock,
                                                        temp, &i)))
                                                goto done;
-                                       ASSERT(i == 1);
+                                       XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                                        /*
                                         * Update the btree record back
                                         * to the original value.
@@ -3290,7 +3297,7 @@ xfs_bmap_del_extent(
                                        error = XFS_ERROR(ENOSPC);
                                        goto done;
                                }
-                               ASSERT(i == 1);
+                               XFS_WANT_CORRUPTED_GOTO(i == 1, done);
                        } else
                                flags |= XFS_ILOG_FEXT(whichfork);
                        XFS_IFORK_NEXT_SET(ip, whichfork,
@@ -4075,7 +4082,6 @@ xfs_bmap_add_attrfork(
 error2:
        xfs_bmap_cancel(&flist);
 error1:
-       ASSERT(ismrlocked(&ip->i_lock,MR_UPDATE));
        xfs_iunlock(ip, XFS_ILOCK_EXCL);
 error0:
        xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT);
@@ -4154,16 +4160,21 @@ xfs_bmap_compute_maxlevels(
         * number of leaf entries, is controlled by the type of di_nextents
         * (a signed 32-bit number, xfs_extnum_t), or by di_anextents
         * (a signed 16-bit number, xfs_aextnum_t).
+        *
+        * Note that we can no longer assume that if we are in ATTR1 that
+        * the fork offset of all the inodes will be (m_attroffset >> 3)
+        * because we could have mounted with ATTR2 and then mounted back
+        * with ATTR1, keeping the di_forkoff's fixed but probably at
+        * various positions. Therefore, for both ATTR1 and ATTR2
+        * we have to assume the worst case scenario of a minimum size
+        * available.
         */
        if (whichfork == XFS_DATA_FORK) {
                maxleafents = MAXEXTNUM;
-               sz = (mp->m_flags & XFS_MOUNT_ATTR2) ?
-                       XFS_BMDR_SPACE_CALC(MINDBTPTRS) : mp->m_attroffset;
+               sz = XFS_BMDR_SPACE_CALC(MINDBTPTRS);
        } else {
                maxleafents = MAXAEXTNUM;
-               sz = (mp->m_flags & XFS_MOUNT_ATTR2) ?
-                       XFS_BMDR_SPACE_CALC(MINABTPTRS) :
-                       mp->m_sb.sb_inodesize - mp->m_attroffset;
+               sz = XFS_BMDR_SPACE_CALC(MINABTPTRS);
        }
        maxrootrecs = (int)XFS_BTREE_BLOCK_MAXRECS(sz, xfs_bmdr, 0);
        minleafrecs = mp->m_bmap_dmnr[0];
@@ -5967,7 +5978,7 @@ unlock_and_return:
        xfs_iunlock_map_shared(ip, lock);
        xfs_iunlock(ip, XFS_IOLOCK_SHARED);
 
-       kmem_free(map, subnex * sizeof(*map));
+       kmem_free(map);
 
        return error;
 }