[XFS] kill xfs_dinode_core_t
[safe/jmp/linux-2.6] / fs / xfs / xfs_btree.c
index 28cc768..7ed5926 100644 (file)
@@ -52,127 +52,11 @@ const __uint32_t xfs_magics[XFS_BTNUM_MAX] = {
        XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, XFS_BMAP_MAGIC, XFS_IBT_MAGIC
 };
 
-/*
- * External routines.
- */
-
-#ifdef DEBUG
-/*
- * Debug routine: check that keys are in the right order.
- */
-void
-xfs_btree_check_key(
-       xfs_btnum_t     btnum,          /* btree identifier */
-       void            *ak1,           /* pointer to left (lower) key */
-       void            *ak2)           /* pointer to right (higher) key */
-{
-       switch (btnum) {
-       case XFS_BTNUM_BNO: {
-               xfs_alloc_key_t *k1;
-               xfs_alloc_key_t *k2;
-
-               k1 = ak1;
-               k2 = ak2;
-               ASSERT(be32_to_cpu(k1->ar_startblock) < be32_to_cpu(k2->ar_startblock));
-               break;
-           }
-       case XFS_BTNUM_CNT: {
-               xfs_alloc_key_t *k1;
-               xfs_alloc_key_t *k2;
-
-               k1 = ak1;
-               k2 = ak2;
-               ASSERT(be32_to_cpu(k1->ar_blockcount) < be32_to_cpu(k2->ar_blockcount) ||
-                      (k1->ar_blockcount == k2->ar_blockcount &&
-                       be32_to_cpu(k1->ar_startblock) < be32_to_cpu(k2->ar_startblock)));
-               break;
-           }
-       case XFS_BTNUM_BMAP: {
-               xfs_bmbt_key_t  *k1;
-               xfs_bmbt_key_t  *k2;
-
-               k1 = ak1;
-               k2 = ak2;
-               ASSERT(be64_to_cpu(k1->br_startoff) < be64_to_cpu(k2->br_startoff));
-               break;
-           }
-       case XFS_BTNUM_INO: {
-               xfs_inobt_key_t *k1;
-               xfs_inobt_key_t *k2;
-
-               k1 = ak1;
-               k2 = ak2;
-               ASSERT(be32_to_cpu(k1->ir_startino) < be32_to_cpu(k2->ir_startino));
-               break;
-           }
-       default:
-               ASSERT(0);
-       }
-}
-
-/*
- * Debug routine: check that records are in the right order.
- */
-void
-xfs_btree_check_rec(
-       xfs_btnum_t     btnum,          /* btree identifier */
-       void            *ar1,           /* pointer to left (lower) record */
-       void            *ar2)           /* pointer to right (higher) record */
-{
-       switch (btnum) {
-       case XFS_BTNUM_BNO: {
-               xfs_alloc_rec_t *r1;
-               xfs_alloc_rec_t *r2;
-
-               r1 = ar1;
-               r2 = ar2;
-               ASSERT(be32_to_cpu(r1->ar_startblock) +
-                      be32_to_cpu(r1->ar_blockcount) <=
-                      be32_to_cpu(r2->ar_startblock));
-               break;
-           }
-       case XFS_BTNUM_CNT: {
-               xfs_alloc_rec_t *r1;
-               xfs_alloc_rec_t *r2;
-
-               r1 = ar1;
-               r2 = ar2;
-               ASSERT(be32_to_cpu(r1->ar_blockcount) < be32_to_cpu(r2->ar_blockcount) ||
-                      (r1->ar_blockcount == r2->ar_blockcount &&
-                       be32_to_cpu(r1->ar_startblock) < be32_to_cpu(r2->ar_startblock)));
-               break;
-           }
-       case XFS_BTNUM_BMAP: {
-               xfs_bmbt_rec_t  *r1;
-               xfs_bmbt_rec_t  *r2;
-
-               r1 = ar1;
-               r2 = ar2;
-               ASSERT(xfs_bmbt_disk_get_startoff(r1) +
-                      xfs_bmbt_disk_get_blockcount(r1) <=
-                      xfs_bmbt_disk_get_startoff(r2));
-               break;
-           }
-       case XFS_BTNUM_INO: {
-               xfs_inobt_rec_t *r1;
-               xfs_inobt_rec_t *r2;
-
-               r1 = ar1;
-               r2 = ar2;
-               ASSERT(be32_to_cpu(r1->ir_startino) + XFS_INODES_PER_CHUNK <=
-                      be32_to_cpu(r2->ir_startino));
-               break;
-           }
-       default:
-               ASSERT(0);
-       }
-}
-#endif /* DEBUG */
 
-int                                    /* error (0 or EFSCORRUPTED) */
+STATIC int                             /* error (0 or EFSCORRUPTED) */
 xfs_btree_check_lblock(
        struct xfs_btree_cur    *cur,   /* btree cursor */
-       struct xfs_btree_lblock *block, /* btree long form block pointer */
+       struct xfs_btree_block  *block, /* btree long form block pointer */
        int                     level,  /* level of the btree block */
        struct xfs_buf          *bp)    /* buffer for block, if any */
 {
@@ -185,12 +69,14 @@ xfs_btree_check_lblock(
                be16_to_cpu(block->bb_level) == level &&
                be16_to_cpu(block->bb_numrecs) <=
                        cur->bc_ops->get_maxrecs(cur, level) &&
-               block->bb_leftsib &&
-               (be64_to_cpu(block->bb_leftsib) == NULLDFSBNO ||
-                XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_leftsib))) &&
-               block->bb_rightsib &&
-               (be64_to_cpu(block->bb_rightsib) == NULLDFSBNO ||
-                XFS_FSB_SANITY_CHECK(mp, be64_to_cpu(block->bb_rightsib)));
+               block->bb_u.l.bb_leftsib &&
+               (be64_to_cpu(block->bb_u.l.bb_leftsib) == NULLDFSBNO ||
+                XFS_FSB_SANITY_CHECK(mp,
+                       be64_to_cpu(block->bb_u.l.bb_leftsib))) &&
+               block->bb_u.l.bb_rightsib &&
+               (be64_to_cpu(block->bb_u.l.bb_rightsib) == NULLDFSBNO ||
+                XFS_FSB_SANITY_CHECK(mp,
+                       be64_to_cpu(block->bb_u.l.bb_rightsib)));
        if (unlikely(XFS_TEST_ERROR(!lblock_ok, mp,
                        XFS_ERRTAG_BTREE_CHECK_LBLOCK,
                        XFS_RANDOM_BTREE_CHECK_LBLOCK))) {
@@ -203,10 +89,10 @@ xfs_btree_check_lblock(
        return 0;
 }
 
-int                                    /* error (0 or EFSCORRUPTED) */
+STATIC int                             /* error (0 or EFSCORRUPTED) */
 xfs_btree_check_sblock(
        struct xfs_btree_cur    *cur,   /* btree cursor */
-       struct xfs_btree_sblock *block, /* btree short form block pointer */
+       struct xfs_btree_block  *block, /* btree short form block pointer */
        int                     level,  /* level of the btree block */
        struct xfs_buf          *bp)    /* buffer containing block */
 {
@@ -223,12 +109,12 @@ xfs_btree_check_sblock(
                be16_to_cpu(block->bb_level) == level &&
                be16_to_cpu(block->bb_numrecs) <=
                        cur->bc_ops->get_maxrecs(cur, level) &&
-               (be32_to_cpu(block->bb_leftsib) == NULLAGBLOCK ||
-                be32_to_cpu(block->bb_leftsib) < agflen) &&
-               block->bb_leftsib &&
-               (be32_to_cpu(block->bb_rightsib) == NULLAGBLOCK ||
-                be32_to_cpu(block->bb_rightsib) < agflen) &&
-               block->bb_rightsib;
+               (be32_to_cpu(block->bb_u.s.bb_leftsib) == NULLAGBLOCK ||
+                be32_to_cpu(block->bb_u.s.bb_leftsib) < agflen) &&
+               block->bb_u.s.bb_leftsib &&
+               (be32_to_cpu(block->bb_u.s.bb_rightsib) == NULLAGBLOCK ||
+                be32_to_cpu(block->bb_u.s.bb_rightsib) < agflen) &&
+               block->bb_u.s.bb_rightsib;
        if (unlikely(XFS_TEST_ERROR(!sblock_ok, cur->bc_mp,
                        XFS_ERRTAG_BTREE_CHECK_SBLOCK,
                        XFS_RANDOM_BTREE_CHECK_SBLOCK))) {
@@ -251,13 +137,10 @@ xfs_btree_check_block(
        int                     level,  /* level of the btree block */
        struct xfs_buf          *bp)    /* buffer containing block, if any */
 {
-       if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
-               return xfs_btree_check_lblock(cur,
-                               (struct xfs_btree_lblock *)block, level, bp);
-       } else {
-               return xfs_btree_check_sblock(cur,
-                               (struct xfs_btree_sblock *)block, level, bp);
-       }
+       if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
+               return xfs_btree_check_lblock(cur, block, level, bp);
+       else
+               return xfs_btree_check_sblock(cur, block, level, bp);
 }
 
 /*
@@ -276,10 +159,11 @@ xfs_btree_check_lptr(
        return 0;
 }
 
+#ifdef DEBUG
 /*
  * Check that (short) pointer is ok.
  */
-int                                    /* error (0 or EFSCORRUPTED) */
+STATIC int                             /* error (0 or EFSCORRUPTED) */
 xfs_btree_check_sptr(
        struct xfs_btree_cur    *cur,   /* btree cursor */
        xfs_agblock_t           bno,    /* btree block disk address */
@@ -298,7 +182,7 @@ xfs_btree_check_sptr(
 /*
  * Check that block ptr is ok.
  */
-int                                    /* error (0 or EFSCORRUPTED) */
+STATIC int                             /* error (0 or EFSCORRUPTED) */
 xfs_btree_check_ptr(
        struct xfs_btree_cur    *cur,   /* btree cursor */
        union xfs_btree_ptr     *ptr,   /* btree block disk address */
@@ -313,6 +197,7 @@ xfs_btree_check_ptr(
                                be32_to_cpu((&ptr->s)[index]), level);
        }
 }
+#endif
 
 /*
  * Delete the btree cursor.
@@ -440,8 +325,8 @@ xfs_btree_dup_cursor(
 static inline size_t xfs_btree_block_len(struct xfs_btree_cur *cur)
 {
        return (cur->bc_flags & XFS_BTREE_LONG_PTRS) ?
-               sizeof(struct xfs_btree_lblock) :
-               sizeof(struct xfs_btree_sblock);
+               XFS_BTREE_LBLOCK_LEN :
+               XFS_BTREE_SBLOCK_LEN;
 }
 
 /*
@@ -624,7 +509,7 @@ xfs_btree_islastblock(
        xfs_btree_cur_t         *cur,   /* btree cursor */
        int                     level)  /* level to check */
 {
-       xfs_btree_block_t       *block; /* generic btree block pointer */
+       struct xfs_btree_block  *block; /* generic btree block pointer */
        xfs_buf_t               *bp;    /* buffer containing block */
 
        block = xfs_btree_get_block(cur, level, &bp);
@@ -639,12 +524,12 @@ xfs_btree_islastblock(
  * Change the cursor to point to the first record at the given level.
  * Other levels are unaffected.
  */
-int                                    /* success=1, failure=0 */
+STATIC int                             /* success=1, failure=0 */
 xfs_btree_firstrec(
        xfs_btree_cur_t         *cur,   /* btree cursor */
        int                     level)  /* level to change */
 {
-       xfs_btree_block_t       *block; /* generic btree block pointer */
+       struct xfs_btree_block  *block; /* generic btree block pointer */
        xfs_buf_t               *bp;    /* buffer containing block */
 
        /*
@@ -668,12 +553,12 @@ xfs_btree_firstrec(
  * Change the cursor to point to the last record in the current block
  * at the given level.  Other levels are unaffected.
  */
-int                                    /* success=1, failure=0 */
+STATIC int                             /* success=1, failure=0 */
 xfs_btree_lastrec(
        xfs_btree_cur_t         *cur,   /* btree cursor */
        int                     level)  /* level to change */
 {
-       xfs_btree_block_t       *block; /* generic btree block pointer */
+       struct xfs_btree_block  *block; /* generic btree block pointer */
        xfs_buf_t               *bp;    /* buffer containing block */
 
        /*
@@ -891,7 +776,7 @@ xfs_btree_readahead_sblock(
  * Read-ahead btree blocks, at the given level.
  * Bits in lr are set from XFS_BTCUR_{LEFT,RIGHT}RA.
  */
-int
+STATIC int
 xfs_btree_readahead(
        struct xfs_btree_cur    *cur,           /* btree cursor */
        int                     lev,            /* level in btree */
@@ -928,7 +813,7 @@ xfs_btree_setbuf(
        int                     lev,    /* level in btree */
        xfs_buf_t               *bp)    /* new buffer to set */
 {
-       xfs_btree_block_t       *b;     /* btree block */
+       struct xfs_btree_block  *b;     /* btree block */
        xfs_buf_t               *obp;   /* old buffer pointer */
 
        obp = cur->bc_bufs[lev];
@@ -1309,7 +1194,7 @@ xfs_btree_log_keys(
 /*
  * Log record values from the btree block.
  */
-STATIC void
+void
 xfs_btree_log_recs(
        struct xfs_btree_cur    *cur,
        struct xfs_buf          *bp,
@@ -1357,7 +1242,7 @@ xfs_btree_log_ptrs(
 /*
  * Log fields from a btree block header.
  */
-STATIC void
+void
 xfs_btree_log_block(
        struct xfs_btree_cur    *cur,   /* btree cursor */
        struct xfs_buf          *bp,    /* buffer containing btree block */
@@ -1366,20 +1251,20 @@ xfs_btree_log_block(
        int                     first;  /* first byte offset logged */
        int                     last;   /* last byte offset logged */
        static const short      soffsets[] = {  /* table of offsets (short) */
-               offsetof(struct xfs_btree_sblock, bb_magic),
-               offsetof(struct xfs_btree_sblock, bb_level),
-               offsetof(struct xfs_btree_sblock, bb_numrecs),
-               offsetof(struct xfs_btree_sblock, bb_leftsib),
-               offsetof(struct xfs_btree_sblock, bb_rightsib),
-               sizeof(struct xfs_btree_sblock)
+               offsetof(struct xfs_btree_block, bb_magic),
+               offsetof(struct xfs_btree_block, bb_level),
+               offsetof(struct xfs_btree_block, bb_numrecs),
+               offsetof(struct xfs_btree_block, bb_u.s.bb_leftsib),
+               offsetof(struct xfs_btree_block, bb_u.s.bb_rightsib),
+               XFS_BTREE_SBLOCK_LEN
        };
        static const short      loffsets[] = {  /* table of offsets (long) */
-               offsetof(struct xfs_btree_lblock, bb_magic),
-               offsetof(struct xfs_btree_lblock, bb_level),
-               offsetof(struct xfs_btree_lblock, bb_numrecs),
-               offsetof(struct xfs_btree_lblock, bb_leftsib),
-               offsetof(struct xfs_btree_lblock, bb_rightsib),
-               sizeof(struct xfs_btree_lblock)
+               offsetof(struct xfs_btree_block, bb_magic),
+               offsetof(struct xfs_btree_block, bb_level),
+               offsetof(struct xfs_btree_block, bb_numrecs),
+               offsetof(struct xfs_btree_block, bb_u.l.bb_leftsib),
+               offsetof(struct xfs_btree_block, bb_u.l.bb_rightsib),
+               XFS_BTREE_LBLOCK_LEN
        };
 
        XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY);
@@ -1827,7 +1712,7 @@ error0:
 /*
  * Update keys at all levels from here to the root along the cursor's path.
  */
-int
+STATIC int
 xfs_btree_updkey(
        struct xfs_btree_cur    *cur,
        union xfs_btree_key     *keyp,
@@ -1937,7 +1822,7 @@ error0:
  * Move 1 record left from cur/level if possible.
  * Update cur to reflect the new path.
  */
-int                                    /* error */
+STATIC int                                     /* error */
 xfs_btree_lshift(
        struct xfs_btree_cur    *cur,
        int                     level,
@@ -2032,9 +1917,8 @@ xfs_btree_lshift(
                xfs_btree_log_keys(cur, lbp, lrecs, lrecs);
                xfs_btree_log_ptrs(cur, lbp, lrecs, lrecs);
 
-               xfs_btree_check_key(cur->bc_btnum,
-                                   xfs_btree_key_addr(cur, lrecs - 1, left),
-                                   lkp);
+               ASSERT(cur->bc_ops->keys_inorder(cur,
+                       xfs_btree_key_addr(cur, lrecs - 1, left), lkp));
        } else {
                /* It's a leaf.  Move records.  */
                union xfs_btree_rec     *lrp;   /* left record pointer */
@@ -2045,9 +1929,8 @@ xfs_btree_lshift(
                xfs_btree_copy_recs(cur, lrp, rrp, 1);
                xfs_btree_log_recs(cur, lbp, lrecs, lrecs);
 
-               xfs_btree_check_rec(cur->bc_btnum,
-                                   xfs_btree_rec_addr(cur, lrecs - 1, left),
-                                   lrp);
+               ASSERT(cur->bc_ops->recs_inorder(cur,
+                       xfs_btree_rec_addr(cur, lrecs - 1, left), lrp));
        }
 
        xfs_btree_set_numrecs(left, lrecs);
@@ -2122,7 +2005,7 @@ error0:
  * Move 1 record right from cur/level if possible.
  * Update cur to reflect the new path.
  */
-int                                    /* error */
+STATIC int                                     /* error */
 xfs_btree_rshift(
        struct xfs_btree_cur    *cur,
        int                     level,
@@ -2222,8 +2105,8 @@ xfs_btree_rshift(
                xfs_btree_log_keys(cur, rbp, 1, rrecs + 1);
                xfs_btree_log_ptrs(cur, rbp, 1, rrecs + 1);
 
-               xfs_btree_check_key(cur->bc_btnum, rkp,
-                                   xfs_btree_key_addr(cur, 2, right));
+               ASSERT(cur->bc_ops->keys_inorder(cur, rkp,
+                       xfs_btree_key_addr(cur, 2, right)));
        } else {
                /* It's a leaf. make a hole in the records */
                union xfs_btree_rec     *lrp;
@@ -2241,8 +2124,8 @@ xfs_btree_rshift(
                cur->bc_ops->init_key_from_rec(&key, rrp);
                rkp = &key;
 
-               xfs_btree_check_rec(cur->bc_btnum, rrp,
-                                   xfs_btree_rec_addr(cur, 2, right));
+               ASSERT(cur->bc_ops->recs_inorder(cur, rrp,
+                       xfs_btree_rec_addr(cur, 2, right)));
        }
 
        /*
@@ -2298,7 +2181,7 @@ error1:
  * Return new block number and the key to its first
  * record (to be inserted into parent).
  */
-int                                            /* error */
+STATIC int                                     /* error */
 xfs_btree_split(
        struct xfs_btree_cur    *cur,
        int                     level,
@@ -2583,7 +2466,7 @@ error0:
 /*
  * Allocate a new root block, fill it in.
  */
-int                            /* error */
+STATIC int                             /* error */
 xfs_btree_new_root(
        struct xfs_btree_cur    *cur,   /* btree cursor */
        int                     *stat)  /* success/failure */
@@ -2849,11 +2732,11 @@ xfs_btree_insrec(
        /* Check that the new entry is being inserted in the right place. */
        if (ptr <= numrecs) {
                if (level == 0) {
-                       xfs_btree_check_rec(cur->bc_btnum, recp,
-                                       xfs_btree_rec_addr(cur, ptr, block));
+                       ASSERT(cur->bc_ops->recs_inorder(cur, recp,
+                               xfs_btree_rec_addr(cur, ptr, block)));
                } else {
-                       xfs_btree_check_key(cur->bc_btnum, &key,
-                                       xfs_btree_key_addr(cur, ptr, block));
+                       ASSERT(cur->bc_ops->keys_inorder(cur, &key,
+                               xfs_btree_key_addr(cur, ptr, block)));
                }
        }
 #endif
@@ -2923,8 +2806,8 @@ xfs_btree_insrec(
                xfs_btree_log_keys(cur, bp, ptr, numrecs);
 #ifdef DEBUG
                if (ptr < numrecs) {
-                       xfs_btree_check_key(cur->bc_btnum, kp,
-                               xfs_btree_key_addr(cur, ptr + 1, block));
+                       ASSERT(cur->bc_ops->keys_inorder(cur, kp,
+                               xfs_btree_key_addr(cur, ptr + 1, block)));
                }
 #endif
        } else {
@@ -2941,8 +2824,8 @@ xfs_btree_insrec(
                xfs_btree_log_recs(cur, bp, ptr, numrecs);
 #ifdef DEBUG
                if (ptr < numrecs) {
-                       xfs_btree_check_rec(cur->bc_btnum, rp,
-                               xfs_btree_rec_addr(cur, ptr + 1, block));
+                       ASSERT(cur->bc_ops->recs_inorder(cur, rp,
+                               xfs_btree_rec_addr(cur, ptr + 1, block)));
                }
 #endif
        }
@@ -3134,7 +3017,7 @@ xfs_btree_kill_iroot(
        if (index) {
                xfs_iroot_realloc(cur->bc_private.b.ip, index,
                                  cur->bc_private.b.whichfork);
-               block = (struct xfs_btree_block *)ifp->if_broot;
+               block = ifp->if_broot;
        }
 
        be16_add_cpu(&block->bb_numrecs, index);
@@ -3764,3 +3647,44 @@ error0:
        XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);
        return error;
 }
+
+/*
+ * Get the data from the pointed-to record.
+ */
+int                                    /* error */
+xfs_btree_get_rec(
+       struct xfs_btree_cur    *cur,   /* btree cursor */
+       union xfs_btree_rec     **recp, /* output: btree record */
+       int                     *stat)  /* output: success/failure */
+{
+       struct xfs_btree_block  *block; /* btree block */
+       struct xfs_buf          *bp;    /* buffer pointer */
+       int                     ptr;    /* record number */
+#ifdef DEBUG
+       int                     error;  /* error return value */
+#endif
+
+       ptr = cur->bc_ptrs[0];
+       block = xfs_btree_get_block(cur, 0, &bp);
+
+#ifdef DEBUG
+       error = xfs_btree_check_block(cur, block, 0, bp);
+       if (error)
+               return error;
+#endif
+
+       /*
+        * Off the right end or left end, return failure.
+        */
+       if (ptr > xfs_btree_get_numrecs(block) || ptr <= 0) {
+               *stat = 0;
+               return 0;
+       }
+
+       /*
+        * Point to the record and extract its data.
+        */
+       *recp = xfs_btree_rec_addr(cur, ptr, block);
+       *stat = 1;
+       return 0;
+}