summaryrefslogtreecommitdiff
path: root/fs/xfs/libxfs/xfs_bmap_btree.h
blob: b189fc2024e98ca07ab45f3310f78e29c463ddfd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2000,2002-2005 Silicon Graphics, Inc.
 * All Rights Reserved.
 */
#ifndef __XFS_BMAP_BTREE_H__
#define __XFS_BMAP_BTREE_H__

struct xfs_btree_cur;
struct xfs_btree_block;
struct xfs_mount;
struct xfs_inode;
struct xfs_trans;
struct xbtree_ifakeroot;

/*
 * Maximum number of bmap btree levels.
 */
#define XFS_BM_MAXLEVELS(mp,w)		((mp)->m_bm_maxlevels[(w)])

/*
 * Prototypes for xfs_bmap.c to call.
 */
extern void xfs_bmdr_to_bmbt(struct xfs_inode *, xfs_bmdr_block_t *, int,
			struct xfs_btree_block *, int);

void xfs_bmbt_disk_set_all(struct xfs_bmbt_rec *r, struct xfs_bmbt_irec *s);
extern xfs_filblks_t xfs_bmbt_disk_get_blockcount(xfs_bmbt_rec_t *r);
extern xfs_fileoff_t xfs_bmbt_disk_get_startoff(xfs_bmbt_rec_t *r);
extern void xfs_bmbt_disk_get_all(const struct xfs_bmbt_rec *r,
		struct xfs_bmbt_irec *s);

extern void xfs_bmbt_to_bmdr(struct xfs_mount *, struct xfs_btree_block *, int,
			xfs_bmdr_block_t *, int);

extern int xfs_bmbt_get_maxrecs(struct xfs_btree_cur *, int level);
extern int xfs_bmdr_maxrecs(int blocklen, int leaf);
extern int xfs_bmbt_maxrecs(struct xfs_mount *, int blocklen, int leaf);

extern int xfs_bmbt_change_owner(struct xfs_trans *tp, struct xfs_inode *ip,
				 int whichfork, xfs_ino_t new_owner,
				 struct list_head *buffer_list);

extern struct xfs_btree_cur *xfs_bmbt_init_cursor(struct xfs_mount *,
		struct xfs_trans *, struct xfs_inode *, int);
struct xfs_btree_cur *xfs_bmbt_stage_cursor(struct xfs_mount *mp,
		struct xfs_inode *ip, struct xbtree_ifakeroot *ifake);
void xfs_bmbt_commit_staged_btree(struct xfs_btree_cur *cur,
		struct xfs_trans *tp, int whichfork);

extern unsigned long long xfs_bmbt_calc_size(struct xfs_mount *mp,
		unsigned long long len);

/*
 * Btree block header size depends on a superblock flag.
 */
static inline size_t
xfs_bmbt_block_len(struct xfs_mount *mp)
{
	return xfs_sb_version_hascrc(&mp->m_sb) ?
			XFS_BTREE_LBLOCK_CRC_LEN : XFS_BTREE_LBLOCK_LEN;
}

/* Addresses of key, pointers, and records within an incore bmbt block. */

static inline struct xfs_bmbt_rec *
xfs_bmbt_rec_addr(
	struct xfs_mount	*mp,
	struct xfs_btree_block	*block,
	unsigned int		index)
{
	return (struct xfs_bmbt_rec *)
		((char *)block + xfs_bmbt_block_len(mp) +
		 (index - 1) * sizeof(struct xfs_bmbt_rec));
}

static inline struct xfs_bmbt_key *
xfs_bmbt_key_addr(
	struct xfs_mount	*mp,
	struct xfs_btree_block	*block,
	unsigned int		index)
{
	return (struct xfs_bmbt_key *)
		((char *)block + xfs_bmbt_block_len(mp) +
		 (index - 1) * sizeof(struct xfs_bmbt_key *));
}

static inline xfs_bmbt_ptr_t *
xfs_bmbt_ptr_addr(
	struct xfs_mount	*mp,
	struct xfs_btree_block	*block,
	unsigned int		index,
	unsigned int		maxrecs)
{
	return (xfs_bmbt_ptr_t *)
		((char *)block + xfs_bmbt_block_len(mp) +
		 maxrecs * sizeof(struct xfs_bmbt_key) +
		 (index - 1) * sizeof(xfs_bmbt_ptr_t));
}

/* Addresses of key, pointers, and records within an ondisk bmbt block. */

static inline struct xfs_bmbt_rec *
xfs_bmdr_rec_addr(
	struct xfs_bmdr_block	*block,
	unsigned int		index)
{
	return (struct xfs_bmbt_rec *)
		((char *)(block + 1) +
		 (index - 1) * sizeof(struct xfs_bmbt_rec));
}

static inline struct xfs_bmbt_key *
xfs_bmdr_key_addr(
	struct xfs_bmdr_block	*block,
	unsigned int		index)
{
	return (struct xfs_bmbt_key *)
		((char *)(block + 1) +
		 (index - 1) * sizeof(struct xfs_bmbt_key));
}

static inline xfs_bmbt_ptr_t *
xfs_bmdr_ptr_addr(
	struct xfs_bmdr_block	*block,
	unsigned int		index,
	unsigned int		maxrecs)
{
	return (xfs_bmbt_ptr_t *)
		((char *)(block + 1) +
		 maxrecs * sizeof(struct xfs_bmbt_key) +
		 (index - 1) * sizeof(xfs_bmbt_ptr_t));
}

/*
 * Address of pointers within the incore btree root.
 *
 * These are to be used when we know the size of the block and
 * we don't have a cursor.
 */
static inline xfs_bmbt_ptr_t *
xfs_bmap_broot_ptr_addr(
	struct xfs_mount	*mp,
	struct xfs_btree_block	*bb,
	unsigned int		i,
	unsigned int		sz)
{
	return xfs_bmbt_ptr_addr(mp, bb, i, xfs_bmbt_maxrecs(mp, sz, 0));
}

/*
 * Compute the space required for the incore btree root containing the given
 * number of records.
 */
static inline size_t
xfs_bmap_broot_space_calc(
	struct xfs_mount	*mp,
	unsigned int		nrecs)
{
	/*
	 * If the bmbt root block is empty, we should be converting the fork
	 * to extents format.  Hence, the size is zero.
	 */
	if (nrecs == 0)
		return 0;

	return xfs_bmbt_block_len(mp) + \
	       (nrecs * (sizeof(struct xfs_bmbt_key) + sizeof(xfs_bmbt_ptr_t)));
}

/*
 * Compute the space required for the incore btree root given the ondisk
 * btree root block.
 */
static inline size_t
xfs_bmap_broot_space(
	struct xfs_mount	*mp,
	struct xfs_bmdr_block	*bb)
{
	return xfs_bmap_broot_space_calc(mp, be16_to_cpu(bb->bb_numrecs));
}

/* Compute the space required for the ondisk root block. */
static inline size_t
xfs_bmdr_space_calc(unsigned int nrecs)
{
	return sizeof(struct xfs_bmdr_block) +
	       (nrecs * (sizeof(struct xfs_bmbt_key) + sizeof(xfs_bmbt_ptr_t)));
}

/*
 * Compute the space required for the ondisk root block given an incore root
 * block.
 */
static inline size_t
xfs_bmap_bmdr_space(struct xfs_btree_block *bb)
{
	return xfs_bmdr_space_calc(be16_to_cpu(bb->bb_numrecs));
}

void xfs_bmbt_iroot_alloc(struct xfs_inode *ip, int whichfork);

#endif	/* __XFS_BMAP_BTREE_H__ */