diff options
author | Christoph Hellwig <hch@infradead.org> | 2008-10-30 01:54:22 -0400 |
---|---|---|
committer | Lachlan McIlroy <lachlan@sgi.com> | 2008-10-30 01:54:22 -0400 |
commit | 8186e517fab1854554c48955cdbcbb6710e7baef (patch) | |
tree | c948ac3cc49516c256ed9ab9355eb49c9f7c2a43 /fs/xfs | |
parent | de227dd9604934d2a6d33cd332d1be431719c93e (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>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_bmap_btree.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_btree.c | 47 | ||||
-rw-r--r-- | fs/xfs/xfs_btree.h | 5 |
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 | */ | ||
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 | * 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 | */ |
428 | STATIC xfs_btree_block_t * /* generic btree block pointer */ | 444 | STATIC struct xfs_btree_block * /* generic btree block pointer */ |
429 | xfs_btree_get_block( | 445 | xfs_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 | ||