aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2008-10-30 01:54:22 -0400
committerLachlan McIlroy <lachlan@sgi.com>2008-10-30 01:54:22 -0400
commit8186e517fab1854554c48955cdbcbb6710e7baef (patch)
treec948ac3cc49516c256ed9ab9355eb49c9f7c2a43
parentde227dd9604934d2a6d33cd332d1be431719c93e (diff)
[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>
-rw-r--r--fs/xfs/xfs_bmap_btree.c1
-rw-r--r--fs/xfs/xfs_btree.c47
-rw-r--r--fs/xfs/xfs_btree.h5
3 files changed, 33 insertions, 20 deletions
diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c
index cfbdd00045cf..d9bbed676e0c 100644
--- a/fs/xfs/xfs_bmap_btree.c
+++ b/fs/xfs/xfs_bmap_btree.c
@@ -2656,6 +2656,7 @@ xfs_bmbt_init_cursor(
2656 cur->bc_blocklog = mp->m_sb.sb_blocklog; 2656 cur->bc_blocklog = mp->m_sb.sb_blocklog;
2657 2657
2658 cur->bc_ops = &xfs_bmbt_ops; 2658 cur->bc_ops = &xfs_bmbt_ops;
2659 cur->bc_flags = XFS_BTREE_ROOT_IN_INODE;
2659 2660
2660 cur->bc_private.b.forksize = XFS_IFORK_SIZE(ip, whichfork); 2661 cur->bc_private.b.forksize = XFS_IFORK_SIZE(ip, whichfork);
2661 cur->bc_private.b.ip = ip; 2662 cur->bc_private.b.ip = ip;
diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c
index 074f7f6aa27c..57e858fbf683 100644
--- a/fs/xfs/xfs_btree.c
+++ b/fs/xfs/xfs_btree.c
@@ -422,32 +422,39 @@ xfs_btree_dup_cursor(
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 */
430STATIC struct xfs_btree_block *
431xfs_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 * Retrieve the block pointer from the cursor at the given level. 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 */
428STATIC xfs_btree_block_t * /* generic btree block pointer */ 444STATIC struct xfs_btree_block * /* generic btree block pointer */
429xfs_btree_get_block( 445xfs_btree_get_block(
430 xfs_btree_cur_t *cur, /* btree cursor */ 446 struct xfs_btree_cur *cur, /* btree cursor */
431 int level, /* level in btree */ 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 */ 450 if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
435 xfs_buf_t *bp; /* return buffer */ 451 (level == cur->bc_nlevels - 1)) {
436 xfs_ifork_t *ifp; /* inode fork pointer */ 452 *bpp = NULL;
437 int whichfork; /* data or attr fork */ 453 return xfs_btree_get_iroot(cur);
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);
447 } 454 }
448 ASSERT(block != NULL); 455
449 *bpp = bp; 456 *bpp = cur->bc_bufs[level];
450 return block; 457 return XFS_BUF_TO_BLOCK(*bpp);
451} 458}
452 459
453/* 460/*
diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h
index 428e81f0e27e..fefbc69e500e 100644
--- a/fs/xfs/xfs_btree.h
+++ b/fs/xfs/xfs_btree.h
@@ -170,6 +170,7 @@ typedef struct xfs_btree_cur
170 struct xfs_trans *bc_tp; /* transaction we're in, if any */ 170 struct xfs_trans *bc_tp; /* transaction we're in, if any */
171 struct xfs_mount *bc_mp; /* file system mount struct */ 171 struct xfs_mount *bc_mp; /* file system mount struct */
172 const struct xfs_btree_ops *bc_ops; 172 const struct xfs_btree_ops *bc_ops;
173 uint bc_flags; /* btree features - below */
173 union { 174 union {
174 xfs_alloc_rec_incore_t a; 175 xfs_alloc_rec_incore_t a;
175 xfs_bmbt_irec_t b; 176 xfs_bmbt_irec_t b;
@@ -201,6 +202,10 @@ typedef struct xfs_btree_cur
201 } bc_private; /* per-btree type data */ 202 } bc_private; /* per-btree type data */
202} xfs_btree_cur_t; 203} xfs_btree_cur_t;
203 204
205/* cursor flags */
206#define XFS_BTREE_ROOT_IN_INODE (1<<1) /* root may be variable size */
207
208
204#define XFS_BTREE_NOERROR 0 209#define XFS_BTREE_NOERROR 0
205#define XFS_BTREE_ERROR 1 210#define XFS_BTREE_ERROR 1
206 211