diff options
Diffstat (limited to 'fs/ocfs2/alloc.h')
-rw-r--r-- | fs/ocfs2/alloc.h | 95 |
1 files changed, 88 insertions, 7 deletions
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h index 42ff94bd8011..70257c84cfbe 100644 --- a/fs/ocfs2/alloc.h +++ b/fs/ocfs2/alloc.h | |||
@@ -26,30 +26,102 @@ | |||
26 | #ifndef OCFS2_ALLOC_H | 26 | #ifndef OCFS2_ALLOC_H |
27 | #define OCFS2_ALLOC_H | 27 | #define OCFS2_ALLOC_H |
28 | 28 | ||
29 | |||
30 | /* | ||
31 | * For xattr tree leaf, we limit the leaf byte size to be 64K. | ||
32 | */ | ||
33 | #define OCFS2_MAX_XATTR_TREE_LEAF_SIZE 65536 | ||
34 | |||
35 | /* | ||
36 | * ocfs2_extent_tree and ocfs2_extent_tree_operations are used to abstract | ||
37 | * the b-tree operations in ocfs2. Now all the b-tree operations are not | ||
38 | * limited to ocfs2_dinode only. Any data which need to allocate clusters | ||
39 | * to store can use b-tree. And it only needs to implement its ocfs2_extent_tree | ||
40 | * and operation. | ||
41 | * | ||
42 | * ocfs2_extent_tree becomes the first-class object for extent tree | ||
43 | * manipulation. Callers of the alloc.c code need to fill it via one of | ||
44 | * the ocfs2_init_*_extent_tree() operations below. | ||
45 | * | ||
46 | * ocfs2_extent_tree contains info for the root of the b-tree, it must have a | ||
47 | * root ocfs2_extent_list and a root_bh so that they can be used in the b-tree | ||
48 | * functions. | ||
49 | * ocfs2_extent_tree_operations abstract the normal operations we do for | ||
50 | * the root of extent b-tree. | ||
51 | */ | ||
52 | struct ocfs2_extent_tree_operations; | ||
53 | struct ocfs2_extent_tree { | ||
54 | struct ocfs2_extent_tree_operations *et_ops; | ||
55 | struct buffer_head *et_root_bh; | ||
56 | struct ocfs2_extent_list *et_root_el; | ||
57 | void *et_object; | ||
58 | unsigned int et_max_leaf_clusters; | ||
59 | }; | ||
60 | |||
61 | /* | ||
62 | * ocfs2_init_*_extent_tree() will fill an ocfs2_extent_tree from the | ||
63 | * specified object buffer. | ||
64 | */ | ||
65 | void ocfs2_init_dinode_extent_tree(struct ocfs2_extent_tree *et, | ||
66 | struct inode *inode, | ||
67 | struct buffer_head *bh); | ||
68 | void ocfs2_init_xattr_tree_extent_tree(struct ocfs2_extent_tree *et, | ||
69 | struct inode *inode, | ||
70 | struct buffer_head *bh); | ||
71 | void ocfs2_init_xattr_value_extent_tree(struct ocfs2_extent_tree *et, | ||
72 | struct inode *inode, | ||
73 | struct buffer_head *bh, | ||
74 | struct ocfs2_xattr_value_root *xv); | ||
75 | |||
29 | struct ocfs2_alloc_context; | 76 | struct ocfs2_alloc_context; |
30 | int ocfs2_insert_extent(struct ocfs2_super *osb, | 77 | int ocfs2_insert_extent(struct ocfs2_super *osb, |
31 | handle_t *handle, | 78 | handle_t *handle, |
32 | struct inode *inode, | 79 | struct inode *inode, |
33 | struct buffer_head *fe_bh, | 80 | struct ocfs2_extent_tree *et, |
34 | u32 cpos, | 81 | u32 cpos, |
35 | u64 start_blk, | 82 | u64 start_blk, |
36 | u32 new_clusters, | 83 | u32 new_clusters, |
37 | u8 flags, | 84 | u8 flags, |
38 | struct ocfs2_alloc_context *meta_ac); | 85 | struct ocfs2_alloc_context *meta_ac); |
86 | |||
87 | enum ocfs2_alloc_restarted { | ||
88 | RESTART_NONE = 0, | ||
89 | RESTART_TRANS, | ||
90 | RESTART_META | ||
91 | }; | ||
92 | int ocfs2_add_clusters_in_btree(struct ocfs2_super *osb, | ||
93 | struct inode *inode, | ||
94 | u32 *logical_offset, | ||
95 | u32 clusters_to_add, | ||
96 | int mark_unwritten, | ||
97 | struct ocfs2_extent_tree *et, | ||
98 | handle_t *handle, | ||
99 | struct ocfs2_alloc_context *data_ac, | ||
100 | struct ocfs2_alloc_context *meta_ac, | ||
101 | enum ocfs2_alloc_restarted *reason_ret); | ||
39 | struct ocfs2_cached_dealloc_ctxt; | 102 | struct ocfs2_cached_dealloc_ctxt; |
40 | int ocfs2_mark_extent_written(struct inode *inode, struct buffer_head *di_bh, | 103 | int ocfs2_mark_extent_written(struct inode *inode, |
104 | struct ocfs2_extent_tree *et, | ||
41 | handle_t *handle, u32 cpos, u32 len, u32 phys, | 105 | handle_t *handle, u32 cpos, u32 len, u32 phys, |
42 | struct ocfs2_alloc_context *meta_ac, | 106 | struct ocfs2_alloc_context *meta_ac, |
43 | struct ocfs2_cached_dealloc_ctxt *dealloc); | 107 | struct ocfs2_cached_dealloc_ctxt *dealloc); |
44 | int ocfs2_remove_extent(struct inode *inode, struct buffer_head *di_bh, | 108 | int ocfs2_remove_extent(struct inode *inode, |
109 | struct ocfs2_extent_tree *et, | ||
45 | u32 cpos, u32 len, handle_t *handle, | 110 | u32 cpos, u32 len, handle_t *handle, |
46 | struct ocfs2_alloc_context *meta_ac, | 111 | struct ocfs2_alloc_context *meta_ac, |
47 | struct ocfs2_cached_dealloc_ctxt *dealloc); | 112 | struct ocfs2_cached_dealloc_ctxt *dealloc); |
48 | int ocfs2_num_free_extents(struct ocfs2_super *osb, | 113 | int ocfs2_num_free_extents(struct ocfs2_super *osb, |
49 | struct inode *inode, | 114 | struct inode *inode, |
50 | struct ocfs2_dinode *fe); | 115 | struct ocfs2_extent_tree *et); |
51 | /* how many new metadata chunks would an allocation need at maximum? */ | 116 | |
52 | static inline int ocfs2_extend_meta_needed(struct ocfs2_dinode *fe) | 117 | /* |
118 | * how many new metadata chunks would an allocation need at maximum? | ||
119 | * | ||
120 | * Please note that the caller must make sure that root_el is the root | ||
121 | * of extent tree. So for an inode, it should be &fe->id2.i_list. Otherwise | ||
122 | * the result may be wrong. | ||
123 | */ | ||
124 | static inline int ocfs2_extend_meta_needed(struct ocfs2_extent_list *root_el) | ||
53 | { | 125 | { |
54 | /* | 126 | /* |
55 | * Rather than do all the work of determining how much we need | 127 | * Rather than do all the work of determining how much we need |
@@ -59,7 +131,7 @@ static inline int ocfs2_extend_meta_needed(struct ocfs2_dinode *fe) | |||
59 | * new tree_depth==0 extent_block, and one block at the new | 131 | * new tree_depth==0 extent_block, and one block at the new |
60 | * top-of-the tree. | 132 | * top-of-the tree. |
61 | */ | 133 | */ |
62 | return le16_to_cpu(fe->id2.i_list.l_tree_depth) + 2; | 134 | return le16_to_cpu(root_el->l_tree_depth) + 2; |
63 | } | 135 | } |
64 | 136 | ||
65 | void ocfs2_dinode_new_extent_list(struct inode *inode, struct ocfs2_dinode *di); | 137 | void ocfs2_dinode_new_extent_list(struct inode *inode, struct ocfs2_dinode *di); |
@@ -146,4 +218,13 @@ static inline unsigned int ocfs2_rec_clusters(struct ocfs2_extent_list *el, | |||
146 | return le16_to_cpu(rec->e_leaf_clusters); | 218 | return le16_to_cpu(rec->e_leaf_clusters); |
147 | } | 219 | } |
148 | 220 | ||
221 | /* | ||
222 | * This is only valid for leaf nodes, which are the only ones that can | ||
223 | * have empty extents anyway. | ||
224 | */ | ||
225 | static inline int ocfs2_is_empty_extent(struct ocfs2_extent_rec *rec) | ||
226 | { | ||
227 | return !rec->e_leaf_clusters; | ||
228 | } | ||
229 | |||
149 | #endif /* OCFS2_ALLOC_H */ | 230 | #endif /* OCFS2_ALLOC_H */ |