xref: /openbmc/linux/fs/ocfs2/suballoc.h (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1328970deSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
2fa60ce2cSMasahiro Yamada /*
3ccd979bdSMark Fasheh  * suballoc.h
4ccd979bdSMark Fasheh  *
5ccd979bdSMark Fasheh  * Defines sub allocator api
6ccd979bdSMark Fasheh  *
7ccd979bdSMark Fasheh  * Copyright (C) 2003, 2004 Oracle.  All rights reserved.
8ccd979bdSMark Fasheh  */
9ccd979bdSMark Fasheh 
10ccd979bdSMark Fasheh #ifndef _CHAINALLOC_H_
11ccd979bdSMark Fasheh #define _CHAINALLOC_H_
12ccd979bdSMark Fasheh 
137d1fe093SJoel Becker struct ocfs2_suballoc_result;
14ccd979bdSMark Fasheh typedef int (group_search_t)(struct inode *,
15ccd979bdSMark Fasheh 			     struct buffer_head *,
161187c968SJoel Becker 			     u32,			/* bits_wanted */
171187c968SJoel Becker 			     u32,			/* min_bits */
181187c968SJoel Becker 			     u64,			/* max_block */
197d1fe093SJoel Becker 			     struct ocfs2_suballoc_result *);
207d1fe093SJoel Becker 							/* found bits */
21ccd979bdSMark Fasheh 
22ccd979bdSMark Fasheh struct ocfs2_alloc_context {
23ccd979bdSMark Fasheh 	struct inode *ac_inode;    /* which bitmap are we allocating from? */
24ccd979bdSMark Fasheh 	struct buffer_head *ac_bh; /* file entry bh */
25a4a48911STao Ma 	u32    ac_alloc_slot;   /* which slot are we allocating from? */
26ccd979bdSMark Fasheh 	u32    ac_bits_wanted;
27ccd979bdSMark Fasheh 	u32    ac_bits_given;
28ccd979bdSMark Fasheh #define OCFS2_AC_USE_LOCAL 1
29ccd979bdSMark Fasheh #define OCFS2_AC_USE_MAIN  2
30ccd979bdSMark Fasheh #define OCFS2_AC_USE_INODE 3
31ccd979bdSMark Fasheh #define OCFS2_AC_USE_META  4
32ccd979bdSMark Fasheh 	u32    ac_which;
33ccd979bdSMark Fasheh 
34ccd979bdSMark Fasheh 	/* these are used by the chain search */
35ccd979bdSMark Fasheh 	u16    ac_chain;
36309a85b6SXiaowei.Hu 	int    ac_disable_chain_relink;
37ccd979bdSMark Fasheh 	group_search_t *ac_group_search;
38883d4caeSMark Fasheh 
39883d4caeSMark Fasheh 	u64    ac_last_group;
401187c968SJoel Becker 	u64    ac_max_block;  /* Highest block number to allocate. 0 is
417eba77d5SRandy Dunlap 				 the same as ~0 - unlimited */
42d02f00ccSMark Fasheh 
43e49e2767SMark Fasheh 	int    ac_find_loc_only;  /* hack for reflink operation ordering */
44e49e2767SMark Fasheh 	struct ocfs2_suballoc_result *ac_find_loc_priv; /* */
45e49e2767SMark Fasheh 
46d02f00ccSMark Fasheh 	struct ocfs2_alloc_reservation	*ac_resv;
47ccd979bdSMark Fasheh };
48ccd979bdSMark Fasheh 
49b89c5428STiger Yang void ocfs2_init_steal_slots(struct ocfs2_super *osb);
50ccd979bdSMark Fasheh void ocfs2_free_alloc_context(struct ocfs2_alloc_context *ac);
ocfs2_alloc_context_bits_left(struct ocfs2_alloc_context * ac)51ccd979bdSMark Fasheh static inline int ocfs2_alloc_context_bits_left(struct ocfs2_alloc_context *ac)
52ccd979bdSMark Fasheh {
53ccd979bdSMark Fasheh 	return ac->ac_bits_wanted - ac->ac_bits_given;
54ccd979bdSMark Fasheh }
55ccd979bdSMark Fasheh 
56811f933dSTao Ma /*
57811f933dSTao Ma  * Please note that the caller must make sure that root_el is the root
58811f933dSTao Ma  * of extent tree. So for an inode, it should be &fe->id2.i_list. Otherwise
59811f933dSTao Ma  * the result may be wrong.
60811f933dSTao Ma  */
61ccd979bdSMark Fasheh int ocfs2_reserve_new_metadata(struct ocfs2_super *osb,
62811f933dSTao Ma 			       struct ocfs2_extent_list *root_el,
63ccd979bdSMark Fasheh 			       struct ocfs2_alloc_context **ac);
64cf1d6c76STiger Yang int ocfs2_reserve_new_metadata_blocks(struct ocfs2_super *osb,
65cf1d6c76STiger Yang 				      int blocks,
66cf1d6c76STiger Yang 				      struct ocfs2_alloc_context **ac);
67ccd979bdSMark Fasheh int ocfs2_reserve_new_inode(struct ocfs2_super *osb,
68ccd979bdSMark Fasheh 			    struct ocfs2_alloc_context **ac);
69ccd979bdSMark Fasheh int ocfs2_reserve_clusters(struct ocfs2_super *osb,
70ccd979bdSMark Fasheh 			   u32 bits_wanted,
71ccd979bdSMark Fasheh 			   struct ocfs2_alloc_context **ac);
72ccd979bdSMark Fasheh 
730a2fcd89SYounger Liu int ocfs2_alloc_dinode_update_counts(struct inode *inode,
740a2fcd89SYounger Liu 			 handle_t *handle,
750a2fcd89SYounger Liu 			 struct buffer_head *di_bh,
760a2fcd89SYounger Liu 			 u32 num_bits,
770a2fcd89SYounger Liu 			 u16 chain);
78db66c715SYounger Liu void ocfs2_rollback_alloc_dinode_counts(struct inode *inode,
79db66c715SYounger Liu 			 struct buffer_head *di_bh,
80db66c715SYounger Liu 			 u32 num_bits,
81db66c715SYounger Liu 			 u16 chain);
820a2fcd89SYounger Liu int ocfs2_block_group_set_bits(handle_t *handle,
830a2fcd89SYounger Liu 			 struct inode *alloc_inode,
840a2fcd89SYounger Liu 			 struct ocfs2_group_desc *bg,
850a2fcd89SYounger Liu 			 struct buffer_head *group_bh,
860a2fcd89SYounger Liu 			 unsigned int bit_off,
870a2fcd89SYounger Liu 			 unsigned int num_bits);
880a2fcd89SYounger Liu 
891ed9b777SJoel Becker int ocfs2_claim_metadata(handle_t *handle,
90ccd979bdSMark Fasheh 			 struct ocfs2_alloc_context *ac,
91ccd979bdSMark Fasheh 			 u32 bits_wanted,
922b6cb576SJoel Becker 			 u64 *suballoc_loc,
93ccd979bdSMark Fasheh 			 u16 *suballoc_bit_start,
94ccd979bdSMark Fasheh 			 u32 *num_bits,
95ccd979bdSMark Fasheh 			 u64 *blkno_start);
961ed9b777SJoel Becker int ocfs2_claim_new_inode(handle_t *handle,
9713821151STao Ma 			  struct inode *dir,
9813821151STao Ma 			  struct buffer_head *parent_fe_bh,
99ccd979bdSMark Fasheh 			  struct ocfs2_alloc_context *ac,
1002b6cb576SJoel Becker 			  u64 *suballoc_loc,
101ccd979bdSMark Fasheh 			  u16 *suballoc_bit,
102ccd979bdSMark Fasheh 			  u64 *fe_blkno);
1031ed9b777SJoel Becker int ocfs2_claim_clusters(handle_t *handle,
104ccd979bdSMark Fasheh 			 struct ocfs2_alloc_context *ac,
105ccd979bdSMark Fasheh 			 u32 min_clusters,
106ccd979bdSMark Fasheh 			 u32 *cluster_start,
107ccd979bdSMark Fasheh 			 u32 *num_clusters);
108415cb800SMark Fasheh /*
109*1c320cfaSJiangshan Yi  * Use this variant of ocfs2_claim_clusters to specify a maximum
110415cb800SMark Fasheh  * number of clusters smaller than the allocation reserved.
111415cb800SMark Fasheh  */
1121ed9b777SJoel Becker int __ocfs2_claim_clusters(handle_t *handle,
113415cb800SMark Fasheh 			   struct ocfs2_alloc_context *ac,
114415cb800SMark Fasheh 			   u32 min_clusters,
115415cb800SMark Fasheh 			   u32 max_clusters,
116415cb800SMark Fasheh 			   u32 *cluster_start,
117415cb800SMark Fasheh 			   u32 *num_clusters);
118ccd979bdSMark Fasheh 
1192b604351SMark Fasheh int ocfs2_free_suballoc_bits(handle_t *handle,
1202b604351SMark Fasheh 			     struct inode *alloc_inode,
1212b604351SMark Fasheh 			     struct buffer_head *alloc_bh,
1222b604351SMark Fasheh 			     unsigned int start_bit,
1232b604351SMark Fasheh 			     u64 bg_blkno,
1242b604351SMark Fasheh 			     unsigned int count);
1251fabe148SMark Fasheh int ocfs2_free_dinode(handle_t *handle,
126ccd979bdSMark Fasheh 		      struct inode *inode_alloc_inode,
127ccd979bdSMark Fasheh 		      struct buffer_head *inode_alloc_bh,
128ccd979bdSMark Fasheh 		      struct ocfs2_dinode *di);
1291fabe148SMark Fasheh int ocfs2_free_clusters(handle_t *handle,
130ccd979bdSMark Fasheh 			struct inode *bitmap_inode,
131ccd979bdSMark Fasheh 			struct buffer_head *bitmap_bh,
132ccd979bdSMark Fasheh 			u64 start_blk,
133ccd979bdSMark Fasheh 			unsigned int num_clusters);
134b4414eeaSMark Fasheh int ocfs2_release_clusters(handle_t *handle,
135b4414eeaSMark Fasheh 			   struct inode *bitmap_inode,
136b4414eeaSMark Fasheh 			   struct buffer_head *bitmap_bh,
137b4414eeaSMark Fasheh 			   u64 start_blk,
138b4414eeaSMark Fasheh 			   unsigned int num_clusters);
139ccd979bdSMark Fasheh 
ocfs2_which_suballoc_group(u64 block,unsigned int bit)1402b604351SMark Fasheh static inline u64 ocfs2_which_suballoc_group(u64 block, unsigned int bit)
1412b604351SMark Fasheh {
1422b604351SMark Fasheh 	u64 group = block - (u64) bit;
1432b604351SMark Fasheh 
1442b604351SMark Fasheh 	return group;
1452b604351SMark Fasheh }
1462b604351SMark Fasheh 
ocfs2_cluster_from_desc(struct ocfs2_super * osb,u64 bg_blkno)147ccd979bdSMark Fasheh static inline u32 ocfs2_cluster_from_desc(struct ocfs2_super *osb,
148ccd979bdSMark Fasheh 					  u64 bg_blkno)
149ccd979bdSMark Fasheh {
150ccd979bdSMark Fasheh 	/* This should work for all block group descriptors as only
151ccd979bdSMark Fasheh 	 * the 1st group descriptor of the cluster bitmap is
152ccd979bdSMark Fasheh 	 * different. */
153ccd979bdSMark Fasheh 
154ccd979bdSMark Fasheh 	if (bg_blkno == osb->first_cluster_group_blkno)
155ccd979bdSMark Fasheh 		return 0;
156ccd979bdSMark Fasheh 
157ccd979bdSMark Fasheh 	/* the rest of the block groups are located at the beginning
158ccd979bdSMark Fasheh 	 * of their 1st cluster, so a direct translation just
159ccd979bdSMark Fasheh 	 * works. */
160ccd979bdSMark Fasheh 	return ocfs2_blocks_to_clusters(osb->sb, bg_blkno);
161ccd979bdSMark Fasheh }
162ccd979bdSMark Fasheh 
ocfs2_is_cluster_bitmap(struct inode * inode)163ccd979bdSMark Fasheh static inline int ocfs2_is_cluster_bitmap(struct inode *inode)
164ccd979bdSMark Fasheh {
165ccd979bdSMark Fasheh 	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
166ccd979bdSMark Fasheh 	return osb->bitmap_blkno == OCFS2_I(inode)->ip_blkno;
167ccd979bdSMark Fasheh }
168ccd979bdSMark Fasheh 
169ccd979bdSMark Fasheh /* This is for local alloc ONLY. Others should use the task-specific
170ccd979bdSMark Fasheh  * apis above. */
171ccd979bdSMark Fasheh int ocfs2_reserve_cluster_bitmap_bits(struct ocfs2_super *osb,
172ccd979bdSMark Fasheh 				      struct ocfs2_alloc_context *ac);
1739c7af40bSMark Fasheh void ocfs2_free_ac_resource(struct ocfs2_alloc_context *ac);
174ccd979bdSMark Fasheh 
175d659072fSTao Ma /* given a cluster offset, calculate which block group it belongs to
176d659072fSTao Ma  * and return that block offset. */
177d659072fSTao Ma u64 ocfs2_which_cluster_group(struct inode *inode, u32 cluster);
178d659072fSTao Ma 
17957e3e797SJoel Becker /*
180970e4936SJoel Becker  * By default, ocfs2_read_group_descriptor() calls ocfs2_error() when it
18157e3e797SJoel Becker  * finds a problem.  A caller that wants to check a group descriptor
182970e4936SJoel Becker  * without going readonly should read the block with ocfs2_read_block[s]()
183970e4936SJoel Becker  * and then checking it with this function.  This is only resize, really.
184970e4936SJoel Becker  * Everyone else should be using ocfs2_read_group_descriptor().
18557e3e797SJoel Becker  */
186970e4936SJoel Becker int ocfs2_check_group_descriptor(struct super_block *sb,
187d659072fSTao Ma 				 struct ocfs2_dinode *di,
188970e4936SJoel Becker 				 struct buffer_head *bh);
18968f64d47SJoel Becker /*
19068f64d47SJoel Becker  * Read a group descriptor block into *bh.  If *bh is NULL, a bh will be
19168f64d47SJoel Becker  * allocated.  This is a cached read.  The descriptor will be validated with
19268f64d47SJoel Becker  * ocfs2_validate_group_descriptor().
19368f64d47SJoel Becker  */
19468f64d47SJoel Becker int ocfs2_read_group_descriptor(struct inode *inode, struct ocfs2_dinode *di,
19568f64d47SJoel Becker 				u64 gd_blkno, struct buffer_head **bh);
19657e3e797SJoel Becker 
197f99b9b7cSJoel Becker int ocfs2_lock_allocators(struct inode *inode, struct ocfs2_extent_tree *et,
198e7d4cb6bSTao Ma 			  u32 clusters_to_add, u32 extents_to_split,
199e7d4cb6bSTao Ma 			  struct ocfs2_alloc_context **data_ac,
200f99b9b7cSJoel Becker 			  struct ocfs2_alloc_context **meta_ac);
2016ca497a8Swengang wang 
2026ca497a8Swengang wang int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res);
203e49e2767SMark Fasheh 
204e49e2767SMark Fasheh 
205e49e2767SMark Fasheh 
206e49e2767SMark Fasheh /*
207e49e2767SMark Fasheh  * The following two interfaces are for ocfs2_create_inode_in_orphan().
208e49e2767SMark Fasheh  */
209e49e2767SMark Fasheh int ocfs2_find_new_inode_loc(struct inode *dir,
210e49e2767SMark Fasheh 			     struct buffer_head *parent_fe_bh,
211e49e2767SMark Fasheh 			     struct ocfs2_alloc_context *ac,
212e49e2767SMark Fasheh 			     u64 *fe_blkno);
213e49e2767SMark Fasheh 
214e49e2767SMark Fasheh int ocfs2_claim_new_inode_at_loc(handle_t *handle,
215e49e2767SMark Fasheh 				 struct inode *dir,
216e49e2767SMark Fasheh 				 struct ocfs2_alloc_context *ac,
217e49e2767SMark Fasheh 				 u64 *suballoc_loc,
218e49e2767SMark Fasheh 				 u16 *suballoc_bit,
219e49e2767SMark Fasheh 				 u64 di_blkno);
220e49e2767SMark Fasheh 
221ccd979bdSMark Fasheh #endif /* _CHAINALLOC_H_ */
222