1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Copyright (C) 2020 Oracle.  All Rights Reserved.
4  * Author: Darrick J. Wong <darrick.wong@oracle.com>
5  */
6 #ifndef __XFS_BTREE_STAGING_H__
7 #define __XFS_BTREE_STAGING_H__
8 
9 /* Fake root for an AG-rooted btree. */
10 struct xbtree_afakeroot {
11 	/* AG block number of the new btree root. */
12 	xfs_agblock_t		af_root;
13 
14 	/* Height of the new btree. */
15 	unsigned int		af_levels;
16 
17 	/* Number of blocks used by the btree. */
18 	unsigned int		af_blocks;
19 };
20 
21 /* Cursor interactions with fake roots for AG-rooted btrees. */
22 void xfs_btree_stage_afakeroot(struct xfs_btree_cur *cur,
23 		struct xbtree_afakeroot *afake);
24 void xfs_btree_commit_afakeroot(struct xfs_btree_cur *cur, struct xfs_trans *tp,
25 		struct xfs_buf *agbp, const struct xfs_btree_ops *ops);
26 
27 /* Fake root for an inode-rooted btree. */
28 struct xbtree_ifakeroot {
29 	/* Fake inode fork. */
30 	struct xfs_ifork	*if_fork;
31 
32 	/* Number of blocks used by the btree. */
33 	int64_t			if_blocks;
34 
35 	/* Height of the new btree. */
36 	unsigned int		if_levels;
37 
38 	/* Number of bytes available for this fork in the inode. */
39 	unsigned int		if_fork_size;
40 };
41 
42 /* Cursor interactions with fake roots for inode-rooted btrees. */
43 void xfs_btree_stage_ifakeroot(struct xfs_btree_cur *cur,
44 		struct xbtree_ifakeroot *ifake,
45 		struct xfs_btree_ops **new_ops);
46 void xfs_btree_commit_ifakeroot(struct xfs_btree_cur *cur, struct xfs_trans *tp,
47 		int whichfork, const struct xfs_btree_ops *ops);
48 
49 /* Bulk loading of staged btrees. */
50 typedef int (*xfs_btree_bload_get_records_fn)(struct xfs_btree_cur *cur,
51 		unsigned int idx, struct xfs_btree_block *block,
52 		unsigned int nr_wanted, void *priv);
53 typedef int (*xfs_btree_bload_claim_block_fn)(struct xfs_btree_cur *cur,
54 		union xfs_btree_ptr *ptr, void *priv);
55 typedef size_t (*xfs_btree_bload_iroot_size_fn)(struct xfs_btree_cur *cur,
56 		unsigned int level, unsigned int nr_this_level, void *priv);
57 
58 struct xfs_btree_bload {
59 	/*
60 	 * This function will be called to load @nr_wanted records into the
61 	 * btree.  The implementation does this by setting the cursor's bc_rec
62 	 * field in in-core format and using init_rec_from_cur to set the
63 	 * records in the btree block.  Records must be returned in sort order.
64 	 * The function must return the number of records loaded or the usual
65 	 * negative errno.
66 	 */
67 	xfs_btree_bload_get_records_fn	get_records;
68 
69 	/*
70 	 * This function will be called nr_blocks times to obtain a pointer
71 	 * to a new btree block on disk.  Callers must preallocate all space
72 	 * for the new btree before calling xfs_btree_bload, and this function
73 	 * is what claims that reservation.
74 	 */
75 	xfs_btree_bload_claim_block_fn	claim_block;
76 
77 	/*
78 	 * This function should return the size of the in-core btree root
79 	 * block.  It is only necessary for XFS_BTREE_ROOT_IN_INODE btree
80 	 * types.
81 	 */
82 	xfs_btree_bload_iroot_size_fn	iroot_size;
83 
84 	/*
85 	 * The caller should set this to the number of records that will be
86 	 * stored in the new btree.
87 	 */
88 	uint64_t			nr_records;
89 
90 	/*
91 	 * Number of free records to leave in each leaf block.  If the caller
92 	 * sets this to -1, the slack value will be calculated to be halfway
93 	 * between maxrecs and minrecs.  This typically leaves the block 75%
94 	 * full.  Note that slack values are not enforced on inode root blocks.
95 	 */
96 	int				leaf_slack;
97 
98 	/*
99 	 * Number of free key/ptrs pairs to leave in each node block.  This
100 	 * field has the same semantics as leaf_slack.
101 	 */
102 	int				node_slack;
103 
104 	/*
105 	 * The xfs_btree_bload_compute_geometry function will set this to the
106 	 * number of btree blocks needed to store nr_records records.
107 	 */
108 	uint64_t			nr_blocks;
109 
110 	/*
111 	 * The xfs_btree_bload_compute_geometry function will set this to the
112 	 * height of the new btree.
113 	 */
114 	unsigned int			btree_height;
115 
116 	/*
117 	 * Flush the new btree block buffer list to disk after this many blocks
118 	 * have been formatted.  Zero prohibits writing any buffers until all
119 	 * blocks have been formatted.
120 	 */
121 	uint16_t			max_dirty;
122 
123 	/* Number of dirty buffers. */
124 	uint16_t			nr_dirty;
125 };
126 
127 int xfs_btree_bload_compute_geometry(struct xfs_btree_cur *cur,
128 		struct xfs_btree_bload *bbl, uint64_t nr_records);
129 int xfs_btree_bload(struct xfs_btree_cur *cur, struct xfs_btree_bload *bbl,
130 		void *priv);
131 
132 #endif	/* __XFS_BTREE_STAGING_H__ */
133