Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 124789
b: refs/heads/master
c: 65f1eae
h: refs/heads/master
i:
  124787: 0e0cc70
v: v3
  • Loading branch information
Christoph Hellwig authored and Lachlan McIlroy committed Oct 30, 2008
1 parent b2ec6b2 commit faa2dc7
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ce5e42db421a41b1ad0cfd68c6058566b963e14b
refs/heads/master: 65f1eaeac0efc968797f3ac955b85ba3f5d4f9c8
3 changes: 3 additions & 0 deletions trunk/fs/xfs/xfs_alloc_btree.c
Original file line number Diff line number Diff line change
Expand Up @@ -2294,6 +2294,9 @@ xfs_allocbt_trace_record(
#endif /* XFS_BTREE_TRACE */

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,
.get_maxrecs = xfs_allocbt_get_maxrecs,

Expand Down
3 changes: 3 additions & 0 deletions trunk/fs/xfs/xfs_bmap_btree.c
Original file line number Diff line number Diff line change
Expand Up @@ -2509,6 +2509,9 @@ xfs_bmbt_trace_record(
#endif /* XFS_BTREE_TRACE */

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,
.get_maxrecs = xfs_bmbt_get_maxrecs,

Expand Down
130 changes: 130 additions & 0 deletions trunk/fs/xfs/xfs_btree.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,136 @@ xfs_btree_dup_cursor(
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.
*
Expand Down
13 changes: 13 additions & 0 deletions trunk/fs/xfs/xfs_btree.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ do { \
#define XFS_BTREE_MAXLEVELS 8 /* max of all btrees */

struct xfs_btree_ops {
/* size of the key and record structures */
size_t key_len;
size_t rec_len;

/* cursor operations */
struct xfs_btree_cur *(*dup_cursor)(struct xfs_btree_cur *);

Expand Down Expand Up @@ -497,6 +501,15 @@ xfs_btree_setbuf(
int lev, /* level in btree */
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__ */


Expand Down
3 changes: 3 additions & 0 deletions trunk/fs/xfs/xfs_ialloc_btree.c
Original file line number Diff line number Diff line change
Expand Up @@ -2160,6 +2160,9 @@ xfs_inobt_trace_record(
#endif /* XFS_BTREE_TRACE */

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,
.get_maxrecs = xfs_inobt_get_maxrecs,

Expand Down

0 comments on commit faa2dc7

Please sign in to comment.