Commit 8186e517fab1854554c48955cdbcbb6710e7baef

Authored by Christoph Hellwig
Committed by Lachlan McIlroy
1 parent de227dd960

[XFS] make btree root in inode support generic

The bmap btree is rooted in the inode and not in a disk block. Make the
support for this feature more generic by adding a btree flag to for this
feature instead of relying on the XFS_BTNUM_BMAP btnum check.

Also clean up xfs_btree_get_block where this new flag is used.

Based upon a patch from Dave Chinner.

SGI-PV: 985583

SGI-Modid: xfs-linux-melb:xfs-kern:32180a

Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Signed-off-by: Bill O'Donnell <billodo@sgi.com>
Signed-off-by: David Chinner <david@fromorbit.com>

Showing 3 changed files with 33 additions and 20 deletions Side-by-side Diff

fs/xfs/xfs_bmap_btree.c
... ... @@ -2656,6 +2656,7 @@
2656 2656 cur->bc_blocklog = mp->m_sb.sb_blocklog;
2657 2657  
2658 2658 cur->bc_ops = &xfs_bmbt_ops;
  2659 + cur->bc_flags = XFS_BTREE_ROOT_IN_INODE;
2659 2660  
2660 2661 cur->bc_private.b.forksize = XFS_IFORK_SIZE(ip, whichfork);
2661 2662 cur->bc_private.b.ip = ip;
... ... @@ -422,32 +422,39 @@
422 422 }
423 423  
424 424 /*
  425 + * Get a the root block which is stored in the inode.
  426 + *
  427 + * For now this btree implementation assumes the btree root is always
  428 + * stored in the if_broot field of an inode fork.
  429 + */
  430 +STATIC struct xfs_btree_block *
  431 +xfs_btree_get_iroot(
  432 + struct xfs_btree_cur *cur)
  433 +{
  434 + struct xfs_ifork *ifp;
  435 +
  436 + ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, cur->bc_private.b.whichfork);
  437 + return (struct xfs_btree_block *)ifp->if_broot;
  438 +}
  439 +
  440 +/*
425 441 * Retrieve the block pointer from the cursor at the given level.
426   - * This may be a bmap btree root or from a buffer.
  442 + * This may be an inode btree root or from a buffer.
427 443 */
428   -STATIC xfs_btree_block_t * /* generic btree block pointer */
  444 +STATIC struct xfs_btree_block * /* generic btree block pointer */
429 445 xfs_btree_get_block(
430   - xfs_btree_cur_t *cur, /* btree cursor */
  446 + struct xfs_btree_cur *cur, /* btree cursor */
431 447 int level, /* level in btree */
432   - xfs_buf_t **bpp) /* buffer containing the block */
  448 + struct xfs_buf **bpp) /* buffer containing the block */
433 449 {
434   - xfs_btree_block_t *block; /* return value */
435   - xfs_buf_t *bp; /* return buffer */
436   - xfs_ifork_t *ifp; /* inode fork pointer */
437   - int whichfork; /* data or attr fork */
438   -
439   - if (cur->bc_btnum == XFS_BTNUM_BMAP && level == cur->bc_nlevels - 1) {
440   - whichfork = cur->bc_private.b.whichfork;
441   - ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, whichfork);
442   - block = (xfs_btree_block_t *)ifp->if_broot;
443   - bp = NULL;
444   - } else {
445   - bp = cur->bc_bufs[level];
446   - block = XFS_BUF_TO_BLOCK(bp);
  450 + if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
  451 + (level == cur->bc_nlevels - 1)) {
  452 + *bpp = NULL;
  453 + return xfs_btree_get_iroot(cur);
447 454 }
448   - ASSERT(block != NULL);
449   - *bpp = bp;
450   - return block;
  455 +
  456 + *bpp = cur->bc_bufs[level];
  457 + return XFS_BUF_TO_BLOCK(*bpp);
451 458 }
452 459  
453 460 /*
... ... @@ -170,6 +170,7 @@
170 170 struct xfs_trans *bc_tp; /* transaction we're in, if any */
171 171 struct xfs_mount *bc_mp; /* file system mount struct */
172 172 const struct xfs_btree_ops *bc_ops;
  173 + uint bc_flags; /* btree features - below */
173 174 union {
174 175 xfs_alloc_rec_incore_t a;
175 176 xfs_bmbt_irec_t b;
... ... @@ -200,6 +201,10 @@
200 201 } b;
201 202 } bc_private; /* per-btree type data */
202 203 } xfs_btree_cur_t;
  204 +
  205 +/* cursor flags */
  206 +#define XFS_BTREE_ROOT_IN_INODE (1<<1) /* root may be variable size */
  207 +
203 208  
204 209 #define XFS_BTREE_NOERROR 0
205 210 #define XFS_BTREE_ERROR 1