162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * suballoc.h
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Defines sub allocator api
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Copyright (C) 2003, 2004 Oracle.  All rights reserved.
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#ifndef _CHAINALLOC_H_
1162306a36Sopenharmony_ci#define _CHAINALLOC_H_
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_cistruct ocfs2_suballoc_result;
1462306a36Sopenharmony_citypedef int (group_search_t)(struct inode *,
1562306a36Sopenharmony_ci			     struct buffer_head *,
1662306a36Sopenharmony_ci			     u32,			/* bits_wanted */
1762306a36Sopenharmony_ci			     u32,			/* min_bits */
1862306a36Sopenharmony_ci			     u64,			/* max_block */
1962306a36Sopenharmony_ci			     struct ocfs2_suballoc_result *);
2062306a36Sopenharmony_ci							/* found bits */
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cistruct ocfs2_alloc_context {
2362306a36Sopenharmony_ci	struct inode *ac_inode;    /* which bitmap are we allocating from? */
2462306a36Sopenharmony_ci	struct buffer_head *ac_bh; /* file entry bh */
2562306a36Sopenharmony_ci	u32    ac_alloc_slot;   /* which slot are we allocating from? */
2662306a36Sopenharmony_ci	u32    ac_bits_wanted;
2762306a36Sopenharmony_ci	u32    ac_bits_given;
2862306a36Sopenharmony_ci#define OCFS2_AC_USE_LOCAL 1
2962306a36Sopenharmony_ci#define OCFS2_AC_USE_MAIN  2
3062306a36Sopenharmony_ci#define OCFS2_AC_USE_INODE 3
3162306a36Sopenharmony_ci#define OCFS2_AC_USE_META  4
3262306a36Sopenharmony_ci	u32    ac_which;
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci	/* these are used by the chain search */
3562306a36Sopenharmony_ci	u16    ac_chain;
3662306a36Sopenharmony_ci	int    ac_disable_chain_relink;
3762306a36Sopenharmony_ci	group_search_t *ac_group_search;
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci	u64    ac_last_group;
4062306a36Sopenharmony_ci	u64    ac_max_block;  /* Highest block number to allocate. 0 is
4162306a36Sopenharmony_ci				 the same as ~0 - unlimited */
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	int    ac_find_loc_only;  /* hack for reflink operation ordering */
4462306a36Sopenharmony_ci	struct ocfs2_suballoc_result *ac_find_loc_priv; /* */
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	struct ocfs2_alloc_reservation	*ac_resv;
4762306a36Sopenharmony_ci};
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_civoid ocfs2_init_steal_slots(struct ocfs2_super *osb);
5062306a36Sopenharmony_civoid ocfs2_free_alloc_context(struct ocfs2_alloc_context *ac);
5162306a36Sopenharmony_cistatic inline int ocfs2_alloc_context_bits_left(struct ocfs2_alloc_context *ac)
5262306a36Sopenharmony_ci{
5362306a36Sopenharmony_ci	return ac->ac_bits_wanted - ac->ac_bits_given;
5462306a36Sopenharmony_ci}
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci/*
5762306a36Sopenharmony_ci * Please note that the caller must make sure that root_el is the root
5862306a36Sopenharmony_ci * of extent tree. So for an inode, it should be &fe->id2.i_list. Otherwise
5962306a36Sopenharmony_ci * the result may be wrong.
6062306a36Sopenharmony_ci */
6162306a36Sopenharmony_ciint ocfs2_reserve_new_metadata(struct ocfs2_super *osb,
6262306a36Sopenharmony_ci			       struct ocfs2_extent_list *root_el,
6362306a36Sopenharmony_ci			       struct ocfs2_alloc_context **ac);
6462306a36Sopenharmony_ciint ocfs2_reserve_new_metadata_blocks(struct ocfs2_super *osb,
6562306a36Sopenharmony_ci				      int blocks,
6662306a36Sopenharmony_ci				      struct ocfs2_alloc_context **ac);
6762306a36Sopenharmony_ciint ocfs2_reserve_new_inode(struct ocfs2_super *osb,
6862306a36Sopenharmony_ci			    struct ocfs2_alloc_context **ac);
6962306a36Sopenharmony_ciint ocfs2_reserve_clusters(struct ocfs2_super *osb,
7062306a36Sopenharmony_ci			   u32 bits_wanted,
7162306a36Sopenharmony_ci			   struct ocfs2_alloc_context **ac);
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ciint ocfs2_alloc_dinode_update_counts(struct inode *inode,
7462306a36Sopenharmony_ci			 handle_t *handle,
7562306a36Sopenharmony_ci			 struct buffer_head *di_bh,
7662306a36Sopenharmony_ci			 u32 num_bits,
7762306a36Sopenharmony_ci			 u16 chain);
7862306a36Sopenharmony_civoid ocfs2_rollback_alloc_dinode_counts(struct inode *inode,
7962306a36Sopenharmony_ci			 struct buffer_head *di_bh,
8062306a36Sopenharmony_ci			 u32 num_bits,
8162306a36Sopenharmony_ci			 u16 chain);
8262306a36Sopenharmony_ciint ocfs2_block_group_set_bits(handle_t *handle,
8362306a36Sopenharmony_ci			 struct inode *alloc_inode,
8462306a36Sopenharmony_ci			 struct ocfs2_group_desc *bg,
8562306a36Sopenharmony_ci			 struct buffer_head *group_bh,
8662306a36Sopenharmony_ci			 unsigned int bit_off,
8762306a36Sopenharmony_ci			 unsigned int num_bits);
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ciint ocfs2_claim_metadata(handle_t *handle,
9062306a36Sopenharmony_ci			 struct ocfs2_alloc_context *ac,
9162306a36Sopenharmony_ci			 u32 bits_wanted,
9262306a36Sopenharmony_ci			 u64 *suballoc_loc,
9362306a36Sopenharmony_ci			 u16 *suballoc_bit_start,
9462306a36Sopenharmony_ci			 u32 *num_bits,
9562306a36Sopenharmony_ci			 u64 *blkno_start);
9662306a36Sopenharmony_ciint ocfs2_claim_new_inode(handle_t *handle,
9762306a36Sopenharmony_ci			  struct inode *dir,
9862306a36Sopenharmony_ci			  struct buffer_head *parent_fe_bh,
9962306a36Sopenharmony_ci			  struct ocfs2_alloc_context *ac,
10062306a36Sopenharmony_ci			  u64 *suballoc_loc,
10162306a36Sopenharmony_ci			  u16 *suballoc_bit,
10262306a36Sopenharmony_ci			  u64 *fe_blkno);
10362306a36Sopenharmony_ciint ocfs2_claim_clusters(handle_t *handle,
10462306a36Sopenharmony_ci			 struct ocfs2_alloc_context *ac,
10562306a36Sopenharmony_ci			 u32 min_clusters,
10662306a36Sopenharmony_ci			 u32 *cluster_start,
10762306a36Sopenharmony_ci			 u32 *num_clusters);
10862306a36Sopenharmony_ci/*
10962306a36Sopenharmony_ci * Use this variant of ocfs2_claim_clusters to specify a maximum
11062306a36Sopenharmony_ci * number of clusters smaller than the allocation reserved.
11162306a36Sopenharmony_ci */
11262306a36Sopenharmony_ciint __ocfs2_claim_clusters(handle_t *handle,
11362306a36Sopenharmony_ci			   struct ocfs2_alloc_context *ac,
11462306a36Sopenharmony_ci			   u32 min_clusters,
11562306a36Sopenharmony_ci			   u32 max_clusters,
11662306a36Sopenharmony_ci			   u32 *cluster_start,
11762306a36Sopenharmony_ci			   u32 *num_clusters);
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ciint ocfs2_free_suballoc_bits(handle_t *handle,
12062306a36Sopenharmony_ci			     struct inode *alloc_inode,
12162306a36Sopenharmony_ci			     struct buffer_head *alloc_bh,
12262306a36Sopenharmony_ci			     unsigned int start_bit,
12362306a36Sopenharmony_ci			     u64 bg_blkno,
12462306a36Sopenharmony_ci			     unsigned int count);
12562306a36Sopenharmony_ciint ocfs2_free_dinode(handle_t *handle,
12662306a36Sopenharmony_ci		      struct inode *inode_alloc_inode,
12762306a36Sopenharmony_ci		      struct buffer_head *inode_alloc_bh,
12862306a36Sopenharmony_ci		      struct ocfs2_dinode *di);
12962306a36Sopenharmony_ciint ocfs2_free_clusters(handle_t *handle,
13062306a36Sopenharmony_ci			struct inode *bitmap_inode,
13162306a36Sopenharmony_ci			struct buffer_head *bitmap_bh,
13262306a36Sopenharmony_ci			u64 start_blk,
13362306a36Sopenharmony_ci			unsigned int num_clusters);
13462306a36Sopenharmony_ciint ocfs2_release_clusters(handle_t *handle,
13562306a36Sopenharmony_ci			   struct inode *bitmap_inode,
13662306a36Sopenharmony_ci			   struct buffer_head *bitmap_bh,
13762306a36Sopenharmony_ci			   u64 start_blk,
13862306a36Sopenharmony_ci			   unsigned int num_clusters);
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_cistatic inline u64 ocfs2_which_suballoc_group(u64 block, unsigned int bit)
14162306a36Sopenharmony_ci{
14262306a36Sopenharmony_ci	u64 group = block - (u64) bit;
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	return group;
14562306a36Sopenharmony_ci}
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_cistatic inline u32 ocfs2_cluster_from_desc(struct ocfs2_super *osb,
14862306a36Sopenharmony_ci					  u64 bg_blkno)
14962306a36Sopenharmony_ci{
15062306a36Sopenharmony_ci	/* This should work for all block group descriptors as only
15162306a36Sopenharmony_ci	 * the 1st group descriptor of the cluster bitmap is
15262306a36Sopenharmony_ci	 * different. */
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci	if (bg_blkno == osb->first_cluster_group_blkno)
15562306a36Sopenharmony_ci		return 0;
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci	/* the rest of the block groups are located at the beginning
15862306a36Sopenharmony_ci	 * of their 1st cluster, so a direct translation just
15962306a36Sopenharmony_ci	 * works. */
16062306a36Sopenharmony_ci	return ocfs2_blocks_to_clusters(osb->sb, bg_blkno);
16162306a36Sopenharmony_ci}
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_cistatic inline int ocfs2_is_cluster_bitmap(struct inode *inode)
16462306a36Sopenharmony_ci{
16562306a36Sopenharmony_ci	struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
16662306a36Sopenharmony_ci	return osb->bitmap_blkno == OCFS2_I(inode)->ip_blkno;
16762306a36Sopenharmony_ci}
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci/* This is for local alloc ONLY. Others should use the task-specific
17062306a36Sopenharmony_ci * apis above. */
17162306a36Sopenharmony_ciint ocfs2_reserve_cluster_bitmap_bits(struct ocfs2_super *osb,
17262306a36Sopenharmony_ci				      struct ocfs2_alloc_context *ac);
17362306a36Sopenharmony_civoid ocfs2_free_ac_resource(struct ocfs2_alloc_context *ac);
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci/* given a cluster offset, calculate which block group it belongs to
17662306a36Sopenharmony_ci * and return that block offset. */
17762306a36Sopenharmony_ciu64 ocfs2_which_cluster_group(struct inode *inode, u32 cluster);
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci/*
18062306a36Sopenharmony_ci * By default, ocfs2_read_group_descriptor() calls ocfs2_error() when it
18162306a36Sopenharmony_ci * finds a problem.  A caller that wants to check a group descriptor
18262306a36Sopenharmony_ci * without going readonly should read the block with ocfs2_read_block[s]()
18362306a36Sopenharmony_ci * and then checking it with this function.  This is only resize, really.
18462306a36Sopenharmony_ci * Everyone else should be using ocfs2_read_group_descriptor().
18562306a36Sopenharmony_ci */
18662306a36Sopenharmony_ciint ocfs2_check_group_descriptor(struct super_block *sb,
18762306a36Sopenharmony_ci				 struct ocfs2_dinode *di,
18862306a36Sopenharmony_ci				 struct buffer_head *bh);
18962306a36Sopenharmony_ci/*
19062306a36Sopenharmony_ci * Read a group descriptor block into *bh.  If *bh is NULL, a bh will be
19162306a36Sopenharmony_ci * allocated.  This is a cached read.  The descriptor will be validated with
19262306a36Sopenharmony_ci * ocfs2_validate_group_descriptor().
19362306a36Sopenharmony_ci */
19462306a36Sopenharmony_ciint ocfs2_read_group_descriptor(struct inode *inode, struct ocfs2_dinode *di,
19562306a36Sopenharmony_ci				u64 gd_blkno, struct buffer_head **bh);
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ciint ocfs2_lock_allocators(struct inode *inode, struct ocfs2_extent_tree *et,
19862306a36Sopenharmony_ci			  u32 clusters_to_add, u32 extents_to_split,
19962306a36Sopenharmony_ci			  struct ocfs2_alloc_context **data_ac,
20062306a36Sopenharmony_ci			  struct ocfs2_alloc_context **meta_ac);
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ciint ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res);
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ci/*
20762306a36Sopenharmony_ci * The following two interfaces are for ocfs2_create_inode_in_orphan().
20862306a36Sopenharmony_ci */
20962306a36Sopenharmony_ciint ocfs2_find_new_inode_loc(struct inode *dir,
21062306a36Sopenharmony_ci			     struct buffer_head *parent_fe_bh,
21162306a36Sopenharmony_ci			     struct ocfs2_alloc_context *ac,
21262306a36Sopenharmony_ci			     u64 *fe_blkno);
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ciint ocfs2_claim_new_inode_at_loc(handle_t *handle,
21562306a36Sopenharmony_ci				 struct inode *dir,
21662306a36Sopenharmony_ci				 struct ocfs2_alloc_context *ac,
21762306a36Sopenharmony_ci				 u64 *suballoc_loc,
21862306a36Sopenharmony_ci				 u16 *suballoc_bit,
21962306a36Sopenharmony_ci				 u64 di_blkno);
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci#endif /* _CHAINALLOC_H_ */
222