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); |
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 | void xfs_btree_commit_ifakeroot(struct xfs_btree_cur *cur, struct xfs_trans *tp, |
46 | int whichfork); |
47 | |
48 | /* Bulk loading of staged btrees. */ |
49 | typedef int (*xfs_btree_bload_get_records_fn)(struct xfs_btree_cur *cur, |
50 | unsigned int idx, struct xfs_btree_block *block, |
51 | unsigned int nr_wanted, void *priv); |
52 | typedef int (*xfs_btree_bload_claim_block_fn)(struct xfs_btree_cur *cur, |
53 | union xfs_btree_ptr *ptr, void *priv); |
54 | typedef size_t (*xfs_btree_bload_iroot_size_fn)(struct xfs_btree_cur *cur, |
55 | unsigned int level, unsigned int nr_this_level, void *priv); |
56 | |
57 | struct xfs_btree_bload { |
58 | /* |
59 | * This function will be called to load @nr_wanted records into the |
60 | * btree. The implementation does this by setting the cursor's bc_rec |
61 | * field in in-core format and using init_rec_from_cur to set the |
62 | * records in the btree block. Records must be returned in sort order. |
63 | * The function must return the number of records loaded or the usual |
64 | * negative errno. |
65 | */ |
66 | xfs_btree_bload_get_records_fn get_records; |
67 | |
68 | /* |
69 | * This function will be called nr_blocks times to obtain a pointer |
70 | * to a new btree block on disk. Callers must preallocate all space |
71 | * for the new btree before calling xfs_btree_bload, and this function |
72 | * is what claims that reservation. |
73 | */ |
74 | xfs_btree_bload_claim_block_fn claim_block; |
75 | |
76 | /* |
77 | * This function should return the size of the in-core btree root |
78 | * block. It is only necessary for XFS_BTREE_TYPE_INODE btrees. |
79 | */ |
80 | xfs_btree_bload_iroot_size_fn iroot_size; |
81 | |
82 | /* |
83 | * The caller should set this to the number of records that will be |
84 | * stored in the new btree. |
85 | */ |
86 | uint64_t nr_records; |
87 | |
88 | /* |
89 | * Number of free records to leave in each leaf block. If the caller |
90 | * sets this to -1, the slack value will be calculated to be halfway |
91 | * between maxrecs and minrecs. This typically leaves the block 75% |
92 | * full. Note that slack values are not enforced on inode root blocks. |
93 | */ |
94 | int leaf_slack; |
95 | |
96 | /* |
97 | * Number of free key/ptrs pairs to leave in each node block. This |
98 | * field has the same semantics as leaf_slack. |
99 | */ |
100 | int node_slack; |
101 | |
102 | /* |
103 | * The xfs_btree_bload_compute_geometry function will set this to the |
104 | * number of btree blocks needed to store nr_records records. |
105 | */ |
106 | uint64_t nr_blocks; |
107 | |
108 | /* |
109 | * The xfs_btree_bload_compute_geometry function will set this to the |
110 | * height of the new btree. |
111 | */ |
112 | unsigned int btree_height; |
113 | |
114 | /* |
115 | * Flush the new btree block buffer list to disk after this many blocks |
116 | * have been formatted. Zero prohibits writing any buffers until all |
117 | * blocks have been formatted. |
118 | */ |
119 | uint16_t max_dirty; |
120 | |
121 | /* Number of dirty buffers. */ |
122 | uint16_t nr_dirty; |
123 | }; |
124 | |
125 | int xfs_btree_bload_compute_geometry(struct xfs_btree_cur *cur, |
126 | struct xfs_btree_bload *bbl, uint64_t nr_records); |
127 | int xfs_btree_bload(struct xfs_btree_cur *cur, struct xfs_btree_bload *bbl, |
128 | void *priv); |
129 | |
130 | #endif /* __XFS_BTREE_STAGING_H__ */ |
131 | |