• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 #ifndef __XFS_BTREE_H__
19 #define	__XFS_BTREE_H__
20 
21 struct xfs_buf;
22 struct xfs_bmap_free;
23 struct xfs_inode;
24 struct xfs_mount;
25 struct xfs_trans;
26 
27 extern kmem_zone_t	*xfs_btree_cur_zone;
28 
29 /*
30  * Generic key, ptr and record wrapper structures.
31  *
32  * These are disk format structures, and are converted where necessary
33  * by the btree specific code that needs to interpret them.
34  */
35 union xfs_btree_ptr {
36 	__be32			s;	/* short form ptr */
37 	__be64			l;	/* long form ptr */
38 };
39 
40 union xfs_btree_key {
41 	xfs_bmbt_key_t		bmbt;
42 	xfs_bmdr_key_t		bmbr;	/* bmbt root block */
43 	xfs_alloc_key_t		alloc;
44 	xfs_inobt_key_t		inobt;
45 };
46 
47 union xfs_btree_rec {
48 	xfs_bmbt_rec_t		bmbt;
49 	xfs_bmdr_rec_t		bmbr;	/* bmbt root block */
50 	xfs_alloc_rec_t		alloc;
51 	xfs_inobt_rec_t		inobt;
52 };
53 
54 /*
55  * This nonsense is to make -wlint happy.
56  */
57 #define	XFS_LOOKUP_EQ	((xfs_lookup_t)XFS_LOOKUP_EQi)
58 #define	XFS_LOOKUP_LE	((xfs_lookup_t)XFS_LOOKUP_LEi)
59 #define	XFS_LOOKUP_GE	((xfs_lookup_t)XFS_LOOKUP_GEi)
60 
61 #define	XFS_BTNUM_BNO	((xfs_btnum_t)XFS_BTNUM_BNOi)
62 #define	XFS_BTNUM_CNT	((xfs_btnum_t)XFS_BTNUM_CNTi)
63 #define	XFS_BTNUM_BMAP	((xfs_btnum_t)XFS_BTNUM_BMAPi)
64 #define	XFS_BTNUM_INO	((xfs_btnum_t)XFS_BTNUM_INOi)
65 #define	XFS_BTNUM_FINO	((xfs_btnum_t)XFS_BTNUM_FINOi)
66 
67 /*
68  * For logging record fields.
69  */
70 #define	XFS_BB_MAGIC		(1 << 0)
71 #define	XFS_BB_LEVEL		(1 << 1)
72 #define	XFS_BB_NUMRECS		(1 << 2)
73 #define	XFS_BB_LEFTSIB		(1 << 3)
74 #define	XFS_BB_RIGHTSIB		(1 << 4)
75 #define	XFS_BB_BLKNO		(1 << 5)
76 #define	XFS_BB_LSN		(1 << 6)
77 #define	XFS_BB_UUID		(1 << 7)
78 #define	XFS_BB_OWNER		(1 << 8)
79 #define	XFS_BB_NUM_BITS		5
80 #define	XFS_BB_ALL_BITS		((1 << XFS_BB_NUM_BITS) - 1)
81 #define	XFS_BB_NUM_BITS_CRC	9
82 #define	XFS_BB_ALL_BITS_CRC	((1 << XFS_BB_NUM_BITS_CRC) - 1)
83 
84 /*
85  * Generic stats interface
86  */
87 #define __XFS_BTREE_STATS_INC(type, stat) \
88 	XFS_STATS_INC(xs_ ## type ## _2_ ## stat)
89 #define XFS_BTREE_STATS_INC(cur, stat)  \
90 do {    \
91 	switch (cur->bc_btnum) {  \
92 	case XFS_BTNUM_BNO: __XFS_BTREE_STATS_INC(abtb, stat); break;	\
93 	case XFS_BTNUM_CNT: __XFS_BTREE_STATS_INC(abtc, stat); break;	\
94 	case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_INC(bmbt, stat); break;	\
95 	case XFS_BTNUM_INO: __XFS_BTREE_STATS_INC(ibt, stat); break;	\
96 	case XFS_BTNUM_FINO: __XFS_BTREE_STATS_INC(fibt, stat); break;	\
97 	case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break;	\
98 	}       \
99 } while (0)
100 
101 #define __XFS_BTREE_STATS_ADD(type, stat, val) \
102 	XFS_STATS_ADD(xs_ ## type ## _2_ ## stat, val)
103 #define XFS_BTREE_STATS_ADD(cur, stat, val)  \
104 do {    \
105 	switch (cur->bc_btnum) {  \
106 	case XFS_BTNUM_BNO: __XFS_BTREE_STATS_ADD(abtb, stat, val); break; \
107 	case XFS_BTNUM_CNT: __XFS_BTREE_STATS_ADD(abtc, stat, val); break; \
108 	case XFS_BTNUM_BMAP: __XFS_BTREE_STATS_ADD(bmbt, stat, val); break; \
109 	case XFS_BTNUM_INO: __XFS_BTREE_STATS_ADD(ibt, stat, val); break; \
110 	case XFS_BTNUM_FINO: __XFS_BTREE_STATS_ADD(fibt, stat, val); break; \
111 	case XFS_BTNUM_MAX: ASSERT(0); /* fucking gcc */ ; break;	\
112 	}       \
113 } while (0)
114 
115 #define	XFS_BTREE_MAXLEVELS	8	/* max of all btrees */
116 
117 struct xfs_btree_ops {
118 	/* size of the key and record structures */
119 	size_t	key_len;
120 	size_t	rec_len;
121 
122 	/* cursor operations */
123 	struct xfs_btree_cur *(*dup_cursor)(struct xfs_btree_cur *);
124 	void	(*update_cursor)(struct xfs_btree_cur *src,
125 				 struct xfs_btree_cur *dst);
126 
127 	/* update btree root pointer */
128 	void	(*set_root)(struct xfs_btree_cur *cur,
129 			    union xfs_btree_ptr *nptr, int level_change);
130 
131 	/* block allocation / freeing */
132 	int	(*alloc_block)(struct xfs_btree_cur *cur,
133 			       union xfs_btree_ptr *start_bno,
134 			       union xfs_btree_ptr *new_bno,
135 			       int *stat);
136 	int	(*free_block)(struct xfs_btree_cur *cur, struct xfs_buf *bp);
137 
138 	/* update last record information */
139 	void	(*update_lastrec)(struct xfs_btree_cur *cur,
140 				  struct xfs_btree_block *block,
141 				  union xfs_btree_rec *rec,
142 				  int ptr, int reason);
143 
144 	/* records in block/level */
145 	int	(*get_minrecs)(struct xfs_btree_cur *cur, int level);
146 	int	(*get_maxrecs)(struct xfs_btree_cur *cur, int level);
147 
148 	/* records on disk.  Matter for the root in inode case. */
149 	int	(*get_dmaxrecs)(struct xfs_btree_cur *cur, int level);
150 
151 	/* init values of btree structures */
152 	void	(*init_key_from_rec)(union xfs_btree_key *key,
153 				     union xfs_btree_rec *rec);
154 	void	(*init_rec_from_key)(union xfs_btree_key *key,
155 				     union xfs_btree_rec *rec);
156 	void	(*init_rec_from_cur)(struct xfs_btree_cur *cur,
157 				     union xfs_btree_rec *rec);
158 	void	(*init_ptr_from_cur)(struct xfs_btree_cur *cur,
159 				     union xfs_btree_ptr *ptr);
160 
161 	/* difference between key value and cursor value */
162 	__int64_t (*key_diff)(struct xfs_btree_cur *cur,
163 			      union xfs_btree_key *key);
164 
165 	const struct xfs_buf_ops	*buf_ops;
166 
167 #if defined(DEBUG) || defined(XFS_WARN)
168 	/* check that k1 is lower than k2 */
169 	int	(*keys_inorder)(struct xfs_btree_cur *cur,
170 				union xfs_btree_key *k1,
171 				union xfs_btree_key *k2);
172 
173 	/* check that r1 is lower than r2 */
174 	int	(*recs_inorder)(struct xfs_btree_cur *cur,
175 				union xfs_btree_rec *r1,
176 				union xfs_btree_rec *r2);
177 #endif
178 };
179 
180 /*
181  * Reasons for the update_lastrec method to be called.
182  */
183 #define LASTREC_UPDATE	0
184 #define LASTREC_INSREC	1
185 #define LASTREC_DELREC	2
186 
187 
188 /*
189  * Btree cursor structure.
190  * This collects all information needed by the btree code in one place.
191  */
192 typedef struct xfs_btree_cur
193 {
194 	struct xfs_trans	*bc_tp;	/* transaction we're in, if any */
195 	struct xfs_mount	*bc_mp;	/* file system mount struct */
196 	const struct xfs_btree_ops *bc_ops;
197 	uint			bc_flags; /* btree features - below */
198 	union {
199 		xfs_alloc_rec_incore_t	a;
200 		xfs_bmbt_irec_t		b;
201 		xfs_inobt_rec_incore_t	i;
202 	}		bc_rec;		/* current insert/search record value */
203 	struct xfs_buf	*bc_bufs[XFS_BTREE_MAXLEVELS];	/* buf ptr per level */
204 	int		bc_ptrs[XFS_BTREE_MAXLEVELS];	/* key/record # */
205 	__uint8_t	bc_ra[XFS_BTREE_MAXLEVELS];	/* readahead bits */
206 #define	XFS_BTCUR_LEFTRA	1	/* left sibling has been read-ahead */
207 #define	XFS_BTCUR_RIGHTRA	2	/* right sibling has been read-ahead */
208 	__uint8_t	bc_nlevels;	/* number of levels in the tree */
209 	__uint8_t	bc_blocklog;	/* log2(blocksize) of btree blocks */
210 	xfs_btnum_t	bc_btnum;	/* identifies which btree type */
211 	union {
212 		struct {			/* needed for BNO, CNT, INO */
213 			struct xfs_buf	*agbp;	/* agf/agi buffer pointer */
214 			xfs_agnumber_t	agno;	/* ag number */
215 		} a;
216 		struct {			/* needed for BMAP */
217 			struct xfs_inode *ip;	/* pointer to our inode */
218 			struct xfs_bmap_free *flist;	/* list to free after */
219 			xfs_fsblock_t	firstblock;	/* 1st blk allocated */
220 			int		allocated;	/* count of alloced */
221 			short		forksize;	/* fork's inode space */
222 			char		whichfork;	/* data or attr fork */
223 			char		flags;		/* flags */
224 #define	XFS_BTCUR_BPRV_WASDEL	1			/* was delayed */
225 		} b;
226 	}		bc_private;	/* per-btree type data */
227 } xfs_btree_cur_t;
228 
229 /* cursor flags */
230 #define XFS_BTREE_LONG_PTRS		(1<<0)	/* pointers are 64bits long */
231 #define XFS_BTREE_ROOT_IN_INODE		(1<<1)	/* root may be variable size */
232 #define XFS_BTREE_LASTREC_UPDATE	(1<<2)	/* track last rec externally */
233 #define XFS_BTREE_CRC_BLOCKS		(1<<3)	/* uses extended btree blocks */
234 
235 
236 #define	XFS_BTREE_NOERROR	0
237 #define	XFS_BTREE_ERROR		1
238 
239 /*
240  * Convert from buffer to btree block header.
241  */
242 #define	XFS_BUF_TO_BLOCK(bp)	((struct xfs_btree_block *)((bp)->b_addr))
243 
244 
245 /*
246  * Check that block header is ok.
247  */
248 int
249 xfs_btree_check_block(
250 	struct xfs_btree_cur	*cur,	/* btree cursor */
251 	struct xfs_btree_block	*block,	/* generic btree block pointer */
252 	int			level,	/* level of the btree block */
253 	struct xfs_buf		*bp);	/* buffer containing block, if any */
254 
255 /*
256  * Check that (long) pointer is ok.
257  */
258 int					/* error (0 or EFSCORRUPTED) */
259 xfs_btree_check_lptr(
260 	struct xfs_btree_cur	*cur,	/* btree cursor */
261 	xfs_fsblock_t		ptr,	/* btree block disk address */
262 	int			level);	/* btree block level */
263 
264 /*
265  * Delete the btree cursor.
266  */
267 void
268 xfs_btree_del_cursor(
269 	xfs_btree_cur_t		*cur,	/* btree cursor */
270 	int			error);	/* del because of error */
271 
272 /*
273  * Duplicate the btree cursor.
274  * Allocate a new one, copy the record, re-get the buffers.
275  */
276 int					/* error */
277 xfs_btree_dup_cursor(
278 	xfs_btree_cur_t		*cur,	/* input cursor */
279 	xfs_btree_cur_t		**ncur);/* output cursor */
280 
281 /*
282  * Get a buffer for the block, return it with no data read.
283  * Long-form addressing.
284  */
285 struct xfs_buf *				/* buffer for fsbno */
286 xfs_btree_get_bufl(
287 	struct xfs_mount	*mp,	/* file system mount point */
288 	struct xfs_trans	*tp,	/* transaction pointer */
289 	xfs_fsblock_t		fsbno,	/* file system block number */
290 	uint			lock);	/* lock flags for get_buf */
291 
292 /*
293  * Get a buffer for the block, return it with no data read.
294  * Short-form addressing.
295  */
296 struct xfs_buf *				/* buffer for agno/agbno */
297 xfs_btree_get_bufs(
298 	struct xfs_mount	*mp,	/* file system mount point */
299 	struct xfs_trans	*tp,	/* transaction pointer */
300 	xfs_agnumber_t		agno,	/* allocation group number */
301 	xfs_agblock_t		agbno,	/* allocation group block number */
302 	uint			lock);	/* lock flags for get_buf */
303 
304 /*
305  * Check for the cursor referring to the last block at the given level.
306  */
307 int					/* 1=is last block, 0=not last block */
308 xfs_btree_islastblock(
309 	xfs_btree_cur_t		*cur,	/* btree cursor */
310 	int			level);	/* level to check */
311 
312 /*
313  * Compute first and last byte offsets for the fields given.
314  * Interprets the offsets table, which contains struct field offsets.
315  */
316 void
317 xfs_btree_offsets(
318 	__int64_t		fields,	/* bitmask of fields */
319 	const short		*offsets,/* table of field offsets */
320 	int			nbits,	/* number of bits to inspect */
321 	int			*first,	/* output: first byte offset */
322 	int			*last);	/* output: last byte offset */
323 
324 /*
325  * Get a buffer for the block, return it read in.
326  * Long-form addressing.
327  */
328 int					/* error */
329 xfs_btree_read_bufl(
330 	struct xfs_mount	*mp,	/* file system mount point */
331 	struct xfs_trans	*tp,	/* transaction pointer */
332 	xfs_fsblock_t		fsbno,	/* file system block number */
333 	uint			lock,	/* lock flags for read_buf */
334 	struct xfs_buf		**bpp,	/* buffer for fsbno */
335 	int			refval,	/* ref count value for buffer */
336 	const struct xfs_buf_ops *ops);
337 
338 /*
339  * Read-ahead the block, don't wait for it, don't return a buffer.
340  * Long-form addressing.
341  */
342 void					/* error */
343 xfs_btree_reada_bufl(
344 	struct xfs_mount	*mp,	/* file system mount point */
345 	xfs_fsblock_t		fsbno,	/* file system block number */
346 	xfs_extlen_t		count,	/* count of filesystem blocks */
347 	const struct xfs_buf_ops *ops);
348 
349 /*
350  * Read-ahead the block, don't wait for it, don't return a buffer.
351  * Short-form addressing.
352  */
353 void					/* error */
354 xfs_btree_reada_bufs(
355 	struct xfs_mount	*mp,	/* file system mount point */
356 	xfs_agnumber_t		agno,	/* allocation group number */
357 	xfs_agblock_t		agbno,	/* allocation group block number */
358 	xfs_extlen_t		count,	/* count of filesystem blocks */
359 	const struct xfs_buf_ops *ops);
360 
361 /*
362  * Initialise a new btree block header
363  */
364 void
365 xfs_btree_init_block(
366 	struct xfs_mount *mp,
367 	struct xfs_buf	*bp,
368 	__u32		magic,
369 	__u16		level,
370 	__u16		numrecs,
371 	__u64		owner,
372 	unsigned int	flags);
373 
374 void
375 xfs_btree_init_block_int(
376 	struct xfs_mount	*mp,
377 	struct xfs_btree_block	*buf,
378 	xfs_daddr_t		blkno,
379 	__u32			magic,
380 	__u16			level,
381 	__u16			numrecs,
382 	__u64			owner,
383 	unsigned int		flags);
384 
385 /*
386  * Common btree core entry points.
387  */
388 int xfs_btree_increment(struct xfs_btree_cur *, int, int *);
389 int xfs_btree_decrement(struct xfs_btree_cur *, int, int *);
390 int xfs_btree_lookup(struct xfs_btree_cur *, xfs_lookup_t, int *);
391 int xfs_btree_update(struct xfs_btree_cur *, union xfs_btree_rec *);
392 int xfs_btree_new_iroot(struct xfs_btree_cur *, int *, int *);
393 int xfs_btree_insert(struct xfs_btree_cur *, int *);
394 int xfs_btree_delete(struct xfs_btree_cur *, int *);
395 int xfs_btree_get_rec(struct xfs_btree_cur *, union xfs_btree_rec **, int *);
396 int xfs_btree_change_owner(struct xfs_btree_cur *cur, __uint64_t new_owner,
397 			   struct list_head *buffer_list);
398 
399 /*
400  * btree block CRC helpers
401  */
402 void xfs_btree_lblock_calc_crc(struct xfs_buf *);
403 bool xfs_btree_lblock_verify_crc(struct xfs_buf *);
404 void xfs_btree_sblock_calc_crc(struct xfs_buf *);
405 bool xfs_btree_sblock_verify_crc(struct xfs_buf *);
406 
407 /*
408  * Internal btree helpers also used by xfs_bmap.c.
409  */
410 void xfs_btree_log_block(struct xfs_btree_cur *, struct xfs_buf *, int);
411 void xfs_btree_log_recs(struct xfs_btree_cur *, struct xfs_buf *, int, int);
412 
413 /*
414  * Helpers.
415  */
xfs_btree_get_numrecs(struct xfs_btree_block * block)416 static inline int xfs_btree_get_numrecs(struct xfs_btree_block *block)
417 {
418 	return be16_to_cpu(block->bb_numrecs);
419 }
420 
xfs_btree_set_numrecs(struct xfs_btree_block * block,__uint16_t numrecs)421 static inline void xfs_btree_set_numrecs(struct xfs_btree_block *block,
422 		__uint16_t numrecs)
423 {
424 	block->bb_numrecs = cpu_to_be16(numrecs);
425 }
426 
xfs_btree_get_level(struct xfs_btree_block * block)427 static inline int xfs_btree_get_level(struct xfs_btree_block *block)
428 {
429 	return be16_to_cpu(block->bb_level);
430 }
431 
432 
433 /*
434  * Min and max functions for extlen, agblock, fileoff, and filblks types.
435  */
436 #define	XFS_EXTLEN_MIN(a,b)	min_t(xfs_extlen_t, (a), (b))
437 #define	XFS_EXTLEN_MAX(a,b)	max_t(xfs_extlen_t, (a), (b))
438 #define	XFS_AGBLOCK_MIN(a,b)	min_t(xfs_agblock_t, (a), (b))
439 #define	XFS_AGBLOCK_MAX(a,b)	max_t(xfs_agblock_t, (a), (b))
440 #define	XFS_FILEOFF_MIN(a,b)	min_t(xfs_fileoff_t, (a), (b))
441 #define	XFS_FILEOFF_MAX(a,b)	max_t(xfs_fileoff_t, (a), (b))
442 #define	XFS_FILBLKS_MIN(a,b)	min_t(xfs_filblks_t, (a), (b))
443 #define	XFS_FILBLKS_MAX(a,b)	max_t(xfs_filblks_t, (a), (b))
444 
445 #define	XFS_FSB_SANITY_CHECK(mp,fsb)	\
446 	(XFS_FSB_TO_AGNO(mp, fsb) < mp->m_sb.sb_agcount && \
447 		XFS_FSB_TO_AGBNO(mp, fsb) < mp->m_sb.sb_agblocks)
448 
449 /*
450  * Trace hooks.  Currently not implemented as they need to be ported
451  * over to the generic tracing functionality, which is some effort.
452  *
453  * i,j = integer (32 bit)
454  * b = btree block buffer (xfs_buf_t)
455  * p = btree ptr
456  * r = btree record
457  * k = btree key
458  */
459 #define	XFS_BTREE_TRACE_ARGBI(c, b, i)
460 #define	XFS_BTREE_TRACE_ARGBII(c, b, i, j)
461 #define	XFS_BTREE_TRACE_ARGI(c, i)
462 #define	XFS_BTREE_TRACE_ARGIPK(c, i, p, s)
463 #define	XFS_BTREE_TRACE_ARGIPR(c, i, p, r)
464 #define	XFS_BTREE_TRACE_ARGIK(c, i, k)
465 #define XFS_BTREE_TRACE_ARGR(c, r)
466 #define	XFS_BTREE_TRACE_CURSOR(c, t)
467 
468 #endif	/* __XFS_BTREE_H__ */
469