[XFS] add helpers for addressing entities inside a btree block
Add new helpers in xfs_btree.c to find the record, key and block pointer entries inside a btree block. To implement this genericly the ->get_maxrecs methods and two new xfs_btree_ops entries for the key and record sizes are used. Also add a big comment describing how the addressing inside a btree block works. Note that these helpers are unused until users are introduced in the next patches and this patch will thus cause some harmless compiler warnings. SGI-PV: 985583 SGI-Modid: xfs-linux-melb:xfs-kern:32189a 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>
This commit is contained in:
Родитель
ce5e42db42
Коммит
65f1eaeac0
|
@ -2294,6 +2294,9 @@ xfs_allocbt_trace_record(
|
||||||
#endif /* XFS_BTREE_TRACE */
|
#endif /* XFS_BTREE_TRACE */
|
||||||
|
|
||||||
static const struct xfs_btree_ops xfs_allocbt_ops = {
|
static const struct xfs_btree_ops xfs_allocbt_ops = {
|
||||||
|
.rec_len = sizeof(xfs_alloc_rec_t),
|
||||||
|
.key_len = sizeof(xfs_alloc_key_t),
|
||||||
|
|
||||||
.dup_cursor = xfs_allocbt_dup_cursor,
|
.dup_cursor = xfs_allocbt_dup_cursor,
|
||||||
.get_maxrecs = xfs_allocbt_get_maxrecs,
|
.get_maxrecs = xfs_allocbt_get_maxrecs,
|
||||||
|
|
||||||
|
|
|
@ -2509,6 +2509,9 @@ xfs_bmbt_trace_record(
|
||||||
#endif /* XFS_BTREE_TRACE */
|
#endif /* XFS_BTREE_TRACE */
|
||||||
|
|
||||||
static const struct xfs_btree_ops xfs_bmbt_ops = {
|
static const struct xfs_btree_ops xfs_bmbt_ops = {
|
||||||
|
.rec_len = sizeof(xfs_bmbt_rec_t),
|
||||||
|
.key_len = sizeof(xfs_bmbt_key_t),
|
||||||
|
|
||||||
.dup_cursor = xfs_bmbt_dup_cursor,
|
.dup_cursor = xfs_bmbt_dup_cursor,
|
||||||
.get_maxrecs = xfs_bmbt_get_maxrecs,
|
.get_maxrecs = xfs_bmbt_get_maxrecs,
|
||||||
|
|
||||||
|
|
|
@ -402,6 +402,136 @@ xfs_btree_dup_cursor(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XFS btree block layout and addressing:
|
||||||
|
*
|
||||||
|
* There are two types of blocks in the btree: leaf and non-leaf blocks.
|
||||||
|
*
|
||||||
|
* The leaf record start with a header then followed by records containing
|
||||||
|
* the values. A non-leaf block also starts with the same header, and
|
||||||
|
* then first contains lookup keys followed by an equal number of pointers
|
||||||
|
* to the btree blocks at the previous level.
|
||||||
|
*
|
||||||
|
* +--------+-------+-------+-------+-------+-------+-------+
|
||||||
|
* Leaf: | header | rec 1 | rec 2 | rec 3 | rec 4 | rec 5 | rec N |
|
||||||
|
* +--------+-------+-------+-------+-------+-------+-------+
|
||||||
|
*
|
||||||
|
* +--------+-------+-------+-------+-------+-------+-------+
|
||||||
|
* Non-Leaf: | header | key 1 | key 2 | key N | ptr 1 | ptr 2 | ptr N |
|
||||||
|
* +--------+-------+-------+-------+-------+-------+-------+
|
||||||
|
*
|
||||||
|
* The header is called struct xfs_btree_block for reasons better left unknown
|
||||||
|
* and comes in different versions for short (32bit) and long (64bit) block
|
||||||
|
* pointers. The record and key structures are defined by the btree instances
|
||||||
|
* and opaque to the btree core. The block pointers are simple disk endian
|
||||||
|
* integers, available in a short (32bit) and long (64bit) variant.
|
||||||
|
*
|
||||||
|
* The helpers below calculate the offset of a given record, key or pointer
|
||||||
|
* into a btree block (xfs_btree_*_offset) or return a pointer to the given
|
||||||
|
* record, key or pointer (xfs_btree_*_addr). Note that all addressing
|
||||||
|
* inside the btree block is done using indices starting at one, not zero!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return size of the btree block header for this btree instance.
|
||||||
|
*/
|
||||||
|
static inline size_t xfs_btree_block_len(struct xfs_btree_cur *cur)
|
||||||
|
{
|
||||||
|
return (cur->bc_flags & XFS_BTREE_LONG_PTRS) ?
|
||||||
|
sizeof(struct xfs_btree_lblock) :
|
||||||
|
sizeof(struct xfs_btree_sblock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return size of btree block pointers for this btree instance.
|
||||||
|
*/
|
||||||
|
static inline size_t xfs_btree_ptr_len(struct xfs_btree_cur *cur)
|
||||||
|
{
|
||||||
|
return (cur->bc_flags & XFS_BTREE_LONG_PTRS) ?
|
||||||
|
sizeof(__be64) : sizeof(__be32);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate offset of the n-th record in a btree block.
|
||||||
|
*/
|
||||||
|
STATIC size_t
|
||||||
|
xfs_btree_rec_offset(
|
||||||
|
struct xfs_btree_cur *cur,
|
||||||
|
int n)
|
||||||
|
{
|
||||||
|
return xfs_btree_block_len(cur) +
|
||||||
|
(n - 1) * cur->bc_ops->rec_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate offset of the n-th key in a btree block.
|
||||||
|
*/
|
||||||
|
STATIC size_t
|
||||||
|
xfs_btree_key_offset(
|
||||||
|
struct xfs_btree_cur *cur,
|
||||||
|
int n)
|
||||||
|
{
|
||||||
|
return xfs_btree_block_len(cur) +
|
||||||
|
(n - 1) * cur->bc_ops->key_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Calculate offset of the n-th block pointer in a btree block.
|
||||||
|
*/
|
||||||
|
STATIC size_t
|
||||||
|
xfs_btree_ptr_offset(
|
||||||
|
struct xfs_btree_cur *cur,
|
||||||
|
int n,
|
||||||
|
int level)
|
||||||
|
{
|
||||||
|
return xfs_btree_block_len(cur) +
|
||||||
|
cur->bc_ops->get_maxrecs(cur, level) * cur->bc_ops->key_len +
|
||||||
|
(n - 1) * xfs_btree_ptr_len(cur);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a pointer to the n-th record in the btree block.
|
||||||
|
*/
|
||||||
|
STATIC union xfs_btree_rec *
|
||||||
|
xfs_btree_rec_addr(
|
||||||
|
struct xfs_btree_cur *cur,
|
||||||
|
int n,
|
||||||
|
struct xfs_btree_block *block)
|
||||||
|
{
|
||||||
|
return (union xfs_btree_rec *)
|
||||||
|
((char *)block + xfs_btree_rec_offset(cur, n));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a pointer to the n-th key in the btree block.
|
||||||
|
*/
|
||||||
|
STATIC union xfs_btree_key *
|
||||||
|
xfs_btree_key_addr(
|
||||||
|
struct xfs_btree_cur *cur,
|
||||||
|
int n,
|
||||||
|
struct xfs_btree_block *block)
|
||||||
|
{
|
||||||
|
return (union xfs_btree_key *)
|
||||||
|
((char *)block + xfs_btree_key_offset(cur, n));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return a pointer to the n-th block pointer in the btree block.
|
||||||
|
*/
|
||||||
|
STATIC union xfs_btree_ptr *
|
||||||
|
xfs_btree_ptr_addr(
|
||||||
|
struct xfs_btree_cur *cur,
|
||||||
|
int n,
|
||||||
|
struct xfs_btree_block *block)
|
||||||
|
{
|
||||||
|
int level = xfs_btree_get_level(block);
|
||||||
|
|
||||||
|
ASSERT(block->bb_level != 0);
|
||||||
|
|
||||||
|
return (union xfs_btree_ptr *)
|
||||||
|
((char *)block + xfs_btree_ptr_offset(cur, n, level));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get a the root block which is stored in the inode.
|
* Get a the root block which is stored in the inode.
|
||||||
*
|
*
|
||||||
|
|
|
@ -180,6 +180,10 @@ do { \
|
||||||
#define XFS_BTREE_MAXLEVELS 8 /* max of all btrees */
|
#define XFS_BTREE_MAXLEVELS 8 /* max of all btrees */
|
||||||
|
|
||||||
struct xfs_btree_ops {
|
struct xfs_btree_ops {
|
||||||
|
/* size of the key and record structures */
|
||||||
|
size_t key_len;
|
||||||
|
size_t rec_len;
|
||||||
|
|
||||||
/* cursor operations */
|
/* cursor operations */
|
||||||
struct xfs_btree_cur *(*dup_cursor)(struct xfs_btree_cur *);
|
struct xfs_btree_cur *(*dup_cursor)(struct xfs_btree_cur *);
|
||||||
|
|
||||||
|
@ -497,6 +501,15 @@ xfs_btree_setbuf(
|
||||||
int lev, /* level in btree */
|
int lev, /* level in btree */
|
||||||
struct xfs_buf *bp); /* new buffer to set */
|
struct xfs_buf *bp); /* new buffer to set */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helpers.
|
||||||
|
*/
|
||||||
|
static inline int xfs_btree_get_level(struct xfs_btree_block *block)
|
||||||
|
{
|
||||||
|
return be16_to_cpu(block->bb_level);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* __KERNEL__ */
|
#endif /* __KERNEL__ */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2160,6 +2160,9 @@ xfs_inobt_trace_record(
|
||||||
#endif /* XFS_BTREE_TRACE */
|
#endif /* XFS_BTREE_TRACE */
|
||||||
|
|
||||||
static const struct xfs_btree_ops xfs_inobt_ops = {
|
static const struct xfs_btree_ops xfs_inobt_ops = {
|
||||||
|
.rec_len = sizeof(xfs_inobt_rec_t),
|
||||||
|
.key_len = sizeof(xfs_inobt_key_t),
|
||||||
|
|
||||||
.dup_cursor = xfs_inobt_dup_cursor,
|
.dup_cursor = xfs_inobt_dup_cursor,
|
||||||
.get_maxrecs = xfs_inobt_get_maxrecs,
|
.get_maxrecs = xfs_inobt_get_maxrecs,
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче