[XFS] implement generic xfs_btree_delete/delrec
[safe/jmp/linux-2.6] / fs / xfs / xfs_bmap_btree.c
index 6b7774e..5b80305 100644 (file)
 #include "xfs_error.h"
 #include "xfs_quota.h"
 
-/*
- * Prototypes for internal btree functions.
- */
-
-
-STATIC void xfs_bmbt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int);
-STATIC void xfs_bmbt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
-
 #undef EXIT
 
 #define ENTRY  XBT_ENTRY
@@ -80,453 +72,6 @@ STATIC void xfs_bmbt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);
 #define        XFS_BMBT_TRACE_CURSOR(c,s) \
        XFS_BTREE_TRACE_CURSOR(c,s)
 
-
-/*
- * Internal functions.
- */
-
-/*
- * Delete record pointed to by cur/level.
- */
-STATIC int                                     /* error */
-xfs_bmbt_delrec(
-       xfs_btree_cur_t         *cur,
-       int                     level,
-       int                     *stat)          /* success/failure */
-{
-       xfs_bmbt_block_t        *block;         /* bmap btree block */
-       xfs_fsblock_t           bno;            /* fs-relative block number */
-       xfs_buf_t               *bp;            /* buffer for block */
-       int                     error;          /* error return value */
-       int                     i;              /* loop counter */
-       int                     j;              /* temp state */
-       xfs_bmbt_key_t          key;            /* bmap btree key */
-       xfs_bmbt_key_t          *kp=NULL;       /* pointer to bmap btree key */
-       xfs_fsblock_t           lbno;           /* left sibling block number */
-       xfs_buf_t               *lbp;           /* left buffer pointer */
-       xfs_bmbt_block_t        *left;          /* left btree block */
-       xfs_bmbt_key_t          *lkp;           /* left btree key */
-       xfs_bmbt_ptr_t          *lpp;           /* left address pointer */
-       int                     lrecs=0;        /* left record count */
-       xfs_bmbt_rec_t          *lrp;           /* left record pointer */
-       xfs_mount_t             *mp;            /* file system mount point */
-       xfs_bmbt_ptr_t          *pp;            /* pointer to bmap block addr */
-       int                     ptr;            /* key/record index */
-       xfs_fsblock_t           rbno;           /* right sibling block number */
-       xfs_buf_t               *rbp;           /* right buffer pointer */
-       xfs_bmbt_block_t        *right;         /* right btree block */
-       xfs_bmbt_key_t          *rkp;           /* right btree key */
-       xfs_bmbt_rec_t          *rp;            /* pointer to bmap btree rec */
-       xfs_bmbt_ptr_t          *rpp;           /* right address pointer */
-       xfs_bmbt_block_t        *rrblock;       /* right-right btree block */
-       xfs_buf_t               *rrbp;          /* right-right buffer pointer */
-       int                     rrecs=0;        /* right record count */
-       xfs_bmbt_rec_t          *rrp;           /* right record pointer */
-       xfs_btree_cur_t         *tcur;          /* temporary btree cursor */
-       int                     numrecs;        /* temporary numrec count */
-       int                     numlrecs, numrrecs;
-
-       XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
-       XFS_BMBT_TRACE_ARGI(cur, level);
-       ptr = cur->bc_ptrs[level];
-       tcur = NULL;
-       if (ptr == 0) {
-               XFS_BMBT_TRACE_CURSOR(cur, EXIT);
-               *stat = 0;
-               return 0;
-       }
-       block = xfs_bmbt_get_block(cur, level, &bp);
-       numrecs = be16_to_cpu(block->bb_numrecs);
-#ifdef DEBUG
-       if ((error = xfs_btree_check_lblock(cur, block, level, bp))) {
-               XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-               goto error0;
-       }
-#endif
-       if (ptr > numrecs) {
-               XFS_BMBT_TRACE_CURSOR(cur, EXIT);
-               *stat = 0;
-               return 0;
-       }
-       XFS_STATS_INC(xs_bmbt_delrec);
-       if (level > 0) {
-               kp = XFS_BMAP_KEY_IADDR(block, 1, cur);
-               pp = XFS_BMAP_PTR_IADDR(block, 1, cur);
-#ifdef DEBUG
-               for (i = ptr; i < numrecs; i++) {
-                       if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) {
-                               XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                               goto error0;
-                       }
-               }
-#endif
-               if (ptr < numrecs) {
-                       memmove(&kp[ptr - 1], &kp[ptr],
-                               (numrecs - ptr) * sizeof(*kp));
-                       memmove(&pp[ptr - 1], &pp[ptr],
-                               (numrecs - ptr) * sizeof(*pp));
-                       xfs_bmbt_log_ptrs(cur, bp, ptr, numrecs - 1);
-                       xfs_bmbt_log_keys(cur, bp, ptr, numrecs - 1);
-               }
-       } else {
-               rp = XFS_BMAP_REC_IADDR(block, 1, cur);
-               if (ptr < numrecs) {
-                       memmove(&rp[ptr - 1], &rp[ptr],
-                               (numrecs - ptr) * sizeof(*rp));
-                       xfs_bmbt_log_recs(cur, bp, ptr, numrecs - 1);
-               }
-               if (ptr == 1) {
-                       key.br_startoff =
-                               cpu_to_be64(xfs_bmbt_disk_get_startoff(rp));
-                       kp = &key;
-               }
-       }
-       numrecs--;
-       block->bb_numrecs = cpu_to_be16(numrecs);
-       xfs_bmbt_log_block(cur, bp, XFS_BB_NUMRECS);
-       /*
-        * We're at the root level.
-        * First, shrink the root block in-memory.
-        * Try to get rid of the next level down.
-        * If we can't then there's nothing left to do.
-        */
-       if (level == cur->bc_nlevels - 1) {
-               xfs_iroot_realloc(cur->bc_private.b.ip, -1,
-                       cur->bc_private.b.whichfork);
-               if ((error = xfs_btree_kill_iroot(cur))) {
-                       XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                       goto error0;
-               }
-               if (level > 0 && (error = xfs_btree_decrement(cur, level, &j))) {
-                       XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                       goto error0;
-               }
-               XFS_BMBT_TRACE_CURSOR(cur, EXIT);
-               *stat = 1;
-               return 0;
-       }
-       if (ptr == 1 && (error = xfs_btree_updkey(cur, (union xfs_btree_key *)kp, level + 1))) {
-               XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-               goto error0;
-       }
-       if (numrecs >= XFS_BMAP_BLOCK_IMINRECS(level, cur)) {
-               if (level > 0 && (error = xfs_btree_decrement(cur, level, &j))) {
-                       XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                       goto error0;
-               }
-               XFS_BMBT_TRACE_CURSOR(cur, EXIT);
-               *stat = 1;
-               return 0;
-       }
-       rbno = be64_to_cpu(block->bb_rightsib);
-       lbno = be64_to_cpu(block->bb_leftsib);
-       /*
-        * One child of root, need to get a chance to copy its contents
-        * into the root and delete it. Can't go up to next level,
-        * there's nothing to delete there.
-        */
-       if (lbno == NULLFSBLOCK && rbno == NULLFSBLOCK &&
-           level == cur->bc_nlevels - 2) {
-               if ((error = xfs_btree_kill_iroot(cur))) {
-                       XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                       goto error0;
-               }
-               if (level > 0 && (error = xfs_btree_decrement(cur, level, &i))) {
-                       XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                       goto error0;
-               }
-               XFS_BMBT_TRACE_CURSOR(cur, EXIT);
-               *stat = 1;
-               return 0;
-       }
-       ASSERT(rbno != NULLFSBLOCK || lbno != NULLFSBLOCK);
-       if ((error = xfs_btree_dup_cursor(cur, &tcur))) {
-               XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-               goto error0;
-       }
-       bno = NULLFSBLOCK;
-       if (rbno != NULLFSBLOCK) {
-               i = xfs_btree_lastrec(tcur, level);
-               XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
-               if ((error = xfs_btree_increment(tcur, level, &i))) {
-                       XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                       goto error0;
-               }
-               XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
-               i = xfs_btree_lastrec(tcur, level);
-               XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
-               rbp = tcur->bc_bufs[level];
-               right = XFS_BUF_TO_BMBT_BLOCK(rbp);
-#ifdef DEBUG
-               if ((error = xfs_btree_check_lblock(cur, right, level, rbp))) {
-                       XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                       goto error0;
-               }
-#endif
-               bno = be64_to_cpu(right->bb_leftsib);
-               if (be16_to_cpu(right->bb_numrecs) - 1 >=
-                   XFS_BMAP_BLOCK_IMINRECS(level, cur)) {
-                       if ((error = xfs_btree_lshift(tcur, level, &i))) {
-                               XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                               goto error0;
-                       }
-                       if (i) {
-                               ASSERT(be16_to_cpu(block->bb_numrecs) >=
-                                      XFS_BMAP_BLOCK_IMINRECS(level, tcur));
-                               xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
-                               tcur = NULL;
-                               if (level > 0) {
-                                       if ((error = xfs_btree_decrement(cur,
-                                                       level, &i))) {
-                                               XFS_BMBT_TRACE_CURSOR(cur,
-                                                       ERROR);
-                                               goto error0;
-                                       }
-                               }
-                               XFS_BMBT_TRACE_CURSOR(cur, EXIT);
-                               *stat = 1;
-                               return 0;
-                       }
-               }
-               rrecs = be16_to_cpu(right->bb_numrecs);
-               if (lbno != NULLFSBLOCK) {
-                       i = xfs_btree_firstrec(tcur, level);
-                       XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
-                       if ((error = xfs_btree_decrement(tcur, level, &i))) {
-                               XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                               goto error0;
-                       }
-                       XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
-               }
-       }
-       if (lbno != NULLFSBLOCK) {
-               i = xfs_btree_firstrec(tcur, level);
-               XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
-               /*
-                * decrement to last in block
-                */
-               if ((error = xfs_btree_decrement(tcur, level, &i))) {
-                       XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                       goto error0;
-               }
-               i = xfs_btree_firstrec(tcur, level);
-               XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
-               lbp = tcur->bc_bufs[level];
-               left = XFS_BUF_TO_BMBT_BLOCK(lbp);
-#ifdef DEBUG
-               if ((error = xfs_btree_check_lblock(cur, left, level, lbp))) {
-                       XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                       goto error0;
-               }
-#endif
-               bno = be64_to_cpu(left->bb_rightsib);
-               if (be16_to_cpu(left->bb_numrecs) - 1 >=
-                   XFS_BMAP_BLOCK_IMINRECS(level, cur)) {
-                       if ((error = xfs_btree_rshift(tcur, level, &i))) {
-                               XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                               goto error0;
-                       }
-                       if (i) {
-                               ASSERT(be16_to_cpu(block->bb_numrecs) >=
-                                      XFS_BMAP_BLOCK_IMINRECS(level, tcur));
-                               xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
-                               tcur = NULL;
-                               if (level == 0)
-                                       cur->bc_ptrs[0]++;
-                               XFS_BMBT_TRACE_CURSOR(cur, EXIT);
-                               *stat = 1;
-                               return 0;
-                       }
-               }
-               lrecs = be16_to_cpu(left->bb_numrecs);
-       }
-       xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
-       tcur = NULL;
-       mp = cur->bc_mp;
-       ASSERT(bno != NULLFSBLOCK);
-       if (lbno != NULLFSBLOCK &&
-           lrecs + be16_to_cpu(block->bb_numrecs) <= XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
-               rbno = bno;
-               right = block;
-               rbp = bp;
-               if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, lbno, 0, &lbp,
-                               XFS_BMAP_BTREE_REF))) {
-                       XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                       goto error0;
-               }
-               left = XFS_BUF_TO_BMBT_BLOCK(lbp);
-               if ((error = xfs_btree_check_lblock(cur, left, level, lbp))) {
-                       XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                       goto error0;
-               }
-       } else if (rbno != NULLFSBLOCK &&
-                  rrecs + be16_to_cpu(block->bb_numrecs) <=
-                  XFS_BMAP_BLOCK_IMAXRECS(level, cur)) {
-               lbno = bno;
-               left = block;
-               lbp = bp;
-               if ((error = xfs_btree_read_bufl(mp, cur->bc_tp, rbno, 0, &rbp,
-                               XFS_BMAP_BTREE_REF))) {
-                       XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                       goto error0;
-               }
-               right = XFS_BUF_TO_BMBT_BLOCK(rbp);
-               if ((error = xfs_btree_check_lblock(cur, right, level, rbp))) {
-                       XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                       goto error0;
-               }
-               lrecs = be16_to_cpu(left->bb_numrecs);
-       } else {
-               if (level > 0 && (error = xfs_btree_decrement(cur, level, &i))) {
-                       XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                       goto error0;
-               }
-               XFS_BMBT_TRACE_CURSOR(cur, EXIT);
-               *stat = 1;
-               return 0;
-       }
-       numlrecs = be16_to_cpu(left->bb_numrecs);
-       numrrecs = be16_to_cpu(right->bb_numrecs);
-       if (level > 0) {
-               lkp = XFS_BMAP_KEY_IADDR(left, numlrecs + 1, cur);
-               lpp = XFS_BMAP_PTR_IADDR(left, numlrecs + 1, cur);
-               rkp = XFS_BMAP_KEY_IADDR(right, 1, cur);
-               rpp = XFS_BMAP_PTR_IADDR(right, 1, cur);
-#ifdef DEBUG
-               for (i = 0; i < numrrecs; i++) {
-                       if ((error = xfs_btree_check_lptr_disk(cur, rpp[i], level))) {
-                               XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                               goto error0;
-                       }
-               }
-#endif
-               memcpy(lkp, rkp, numrrecs * sizeof(*lkp));
-               memcpy(lpp, rpp, numrrecs * sizeof(*lpp));
-               xfs_bmbt_log_keys(cur, lbp, numlrecs + 1, numlrecs + numrrecs);
-               xfs_bmbt_log_ptrs(cur, lbp, numlrecs + 1, numlrecs + numrrecs);
-       } else {
-               lrp = XFS_BMAP_REC_IADDR(left, numlrecs + 1, cur);
-               rrp = XFS_BMAP_REC_IADDR(right, 1, cur);
-               memcpy(lrp, rrp, numrrecs * sizeof(*lrp));
-               xfs_bmbt_log_recs(cur, lbp, numlrecs + 1, numlrecs + numrrecs);
-       }
-       be16_add_cpu(&left->bb_numrecs, numrrecs);
-       left->bb_rightsib = right->bb_rightsib;
-       xfs_bmbt_log_block(cur, lbp, XFS_BB_RIGHTSIB | XFS_BB_NUMRECS);
-       if (be64_to_cpu(left->bb_rightsib) != NULLDFSBNO) {
-               if ((error = xfs_btree_read_bufl(mp, cur->bc_tp,
-                               be64_to_cpu(left->bb_rightsib),
-                               0, &rrbp, XFS_BMAP_BTREE_REF))) {
-                       XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                       goto error0;
-               }
-               rrblock = XFS_BUF_TO_BMBT_BLOCK(rrbp);
-               if ((error = xfs_btree_check_lblock(cur, rrblock, level, rrbp))) {
-                       XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                       goto error0;
-               }
-               rrblock->bb_leftsib = cpu_to_be64(lbno);
-               xfs_bmbt_log_block(cur, rrbp, XFS_BB_LEFTSIB);
-       }
-       xfs_bmap_add_free(XFS_DADDR_TO_FSB(mp, XFS_BUF_ADDR(rbp)), 1,
-               cur->bc_private.b.flist, mp);
-       cur->bc_private.b.ip->i_d.di_nblocks--;
-       xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, XFS_ILOG_CORE);
-       XFS_TRANS_MOD_DQUOT_BYINO(mp, cur->bc_tp, cur->bc_private.b.ip,
-                       XFS_TRANS_DQ_BCOUNT, -1L);
-       xfs_trans_binval(cur->bc_tp, rbp);
-       if (bp != lbp) {
-               cur->bc_bufs[level] = lbp;
-               cur->bc_ptrs[level] += lrecs;
-               cur->bc_ra[level] = 0;
-       } else if ((error = xfs_btree_increment(cur, level + 1, &i))) {
-               XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-               goto error0;
-       }
-       if (level > 0)
-               cur->bc_ptrs[level]--;
-       XFS_BMBT_TRACE_CURSOR(cur, EXIT);
-       *stat = 2;
-       return 0;
-
-error0:
-       if (tcur)
-               xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
-       return error;
-}
-
-/*
- * Log key values from the btree block.
- */
-STATIC void
-xfs_bmbt_log_keys(
-       xfs_btree_cur_t *cur,
-       xfs_buf_t       *bp,
-       int             kfirst,
-       int             klast)
-{
-       xfs_trans_t     *tp;
-
-       XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
-       XFS_BMBT_TRACE_ARGBII(cur, bp, kfirst, klast);
-       tp = cur->bc_tp;
-       if (bp) {
-               xfs_bmbt_block_t        *block;
-               int                     first;
-               xfs_bmbt_key_t          *kp;
-               int                     last;
-
-               block = XFS_BUF_TO_BMBT_BLOCK(bp);
-               kp = XFS_BMAP_KEY_DADDR(block, 1, cur);
-               first = (int)((xfs_caddr_t)&kp[kfirst - 1] - (xfs_caddr_t)block);
-               last = (int)(((xfs_caddr_t)&kp[klast] - 1) - (xfs_caddr_t)block);
-               xfs_trans_log_buf(tp, bp, first, last);
-       } else {
-               xfs_inode_t              *ip;
-
-               ip = cur->bc_private.b.ip;
-               xfs_trans_log_inode(tp, ip,
-                       XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));
-       }
-       XFS_BMBT_TRACE_CURSOR(cur, EXIT);
-}
-
-/*
- * Log pointer values from the btree block.
- */
-STATIC void
-xfs_bmbt_log_ptrs(
-       xfs_btree_cur_t *cur,
-       xfs_buf_t       *bp,
-       int             pfirst,
-       int             plast)
-{
-       xfs_trans_t     *tp;
-
-       XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
-       XFS_BMBT_TRACE_ARGBII(cur, bp, pfirst, plast);
-       tp = cur->bc_tp;
-       if (bp) {
-               xfs_bmbt_block_t        *block;
-               int                     first;
-               int                     last;
-               xfs_bmbt_ptr_t          *pp;
-
-               block = XFS_BUF_TO_BMBT_BLOCK(bp);
-               pp = XFS_BMAP_PTR_DADDR(block, 1, cur);
-               first = (int)((xfs_caddr_t)&pp[pfirst - 1] - (xfs_caddr_t)block);
-               last = (int)(((xfs_caddr_t)&pp[plast] - 1) - (xfs_caddr_t)block);
-               xfs_trans_log_buf(tp, bp, first, last);
-       } else {
-               xfs_inode_t             *ip;
-
-               ip = cur->bc_private.b.ip;
-               xfs_trans_log_inode(tp, ip,
-                       XFS_ILOG_FBROOT(cur->bc_private.b.whichfork));
-       }
-       XFS_BMBT_TRACE_CURSOR(cur, EXIT);
-}
-
 /*
  * Determine the extent state.
  */
@@ -576,42 +121,6 @@ xfs_bmdr_to_bmbt(
 }
 
 /*
- * Delete the record pointed to by cur.
- */
-int                                    /* error */
-xfs_bmbt_delete(
-       xfs_btree_cur_t *cur,
-       int             *stat)          /* success/failure */
-{
-       int             error;          /* error return value */
-       int             i;
-       int             level;
-
-       XFS_BMBT_TRACE_CURSOR(cur, ENTRY);
-       for (level = 0, i = 2; i == 2; level++) {
-               if ((error = xfs_bmbt_delrec(cur, level, &i))) {
-                       XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                       return error;
-               }
-       }
-       if (i == 0) {
-               for (level = 1; level < cur->bc_nlevels; level++) {
-                       if (cur->bc_ptrs[level] == 0) {
-                               if ((error = xfs_btree_decrement(cur, level,
-                                               &i))) {
-                                       XFS_BMBT_TRACE_CURSOR(cur, ERROR);
-                                       return error;
-                               }
-                               break;
-                       }
-               }
-       }
-       XFS_BMBT_TRACE_CURSOR(cur, EXIT);
-       *stat = i;
-       return 0;
-}
-
-/*
  * Convert a compressed bmap extent record to an uncompressed form.
  * This code must be in sync with the routines xfs_bmbt_get_startoff,
  * xfs_bmbt_get_startblock, xfs_bmbt_get_blockcount and xfs_bmbt_get_state.
@@ -665,31 +174,6 @@ xfs_bmbt_get_all(
 }
 
 /*
- * Get the block pointer for the given level of the cursor.
- * Fill in the buffer pointer, if applicable.
- */
-xfs_bmbt_block_t *
-xfs_bmbt_get_block(
-       xfs_btree_cur_t         *cur,
-       int                     level,
-       xfs_buf_t               **bpp)
-{
-       xfs_ifork_t             *ifp;
-       xfs_bmbt_block_t        *rval;
-
-       if (level < cur->bc_nlevels - 1) {
-               *bpp = cur->bc_bufs[level];
-               rval = XFS_BUF_TO_BMBT_BLOCK(*bpp);
-       } else {
-               *bpp = NULL;
-               ifp = XFS_IFORK_PTR(cur->bc_private.b.ip,
-                       cur->bc_private.b.whichfork);
-               rval = ifp->if_broot;
-       }
-       return rval;
-}
-
-/*
  * Extract the blockcount field from an in memory bmap extent record.
  */
 xfs_filblks_t
@@ -1226,6 +710,14 @@ xfs_bmbt_free_block(
 }
 
 STATIC int
+xfs_bmbt_get_minrecs(
+       struct xfs_btree_cur    *cur,
+       int                     level)
+{
+       return XFS_BMAP_BLOCK_IMINRECS(level, cur);
+}
+
+STATIC int
 xfs_bmbt_get_maxrecs(
        struct xfs_btree_cur    *cur,
        int                     level)
@@ -1389,6 +881,7 @@ static const struct xfs_btree_ops xfs_bmbt_ops = {
        .alloc_block            = xfs_bmbt_alloc_block,
        .free_block             = xfs_bmbt_free_block,
        .get_maxrecs            = xfs_bmbt_get_maxrecs,
+       .get_minrecs            = xfs_bmbt_get_minrecs,
        .get_dmaxrecs           = xfs_bmbt_get_dmaxrecs,
        .init_key_from_rec      = xfs_bmbt_init_key_from_rec,
        .init_rec_from_key      = xfs_bmbt_init_rec_from_key,