Commit 8186e517fab1854554c48955cdbcbb6710e7baef
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
fs/xfs/xfs_btree.c
... | ... | @@ -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 | /* |
fs/xfs/xfs_btree.h
... | ... | @@ -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 |