1  /* SPDX-License-Identifier: GPL-2.0 */
2  /*
3   * Copyright (c) 2000,2002-2005 Silicon Graphics, Inc.
4   * All Rights Reserved.
5   */
6  #ifndef __XFS_BMAP_BTREE_H__
7  #define __XFS_BMAP_BTREE_H__
8  
9  struct xfs_btree_cur;
10  struct xfs_btree_block;
11  struct xfs_mount;
12  struct xfs_inode;
13  struct xfs_trans;
14  struct xbtree_ifakeroot;
15  
16  /*
17   * Maximum number of bmap btree levels.
18   */
19  #define XFS_BM_MAXLEVELS(mp,w)		((mp)->m_bm_maxlevels[(w)])
20  
21  /*
22   * Prototypes for xfs_bmap.c to call.
23   */
24  extern void xfs_bmdr_to_bmbt(struct xfs_inode *, xfs_bmdr_block_t *, int,
25  			struct xfs_btree_block *, int);
26  
27  void xfs_bmbt_disk_set_all(struct xfs_bmbt_rec *r, struct xfs_bmbt_irec *s);
28  extern xfs_filblks_t xfs_bmbt_disk_get_blockcount(const struct xfs_bmbt_rec *r);
29  extern xfs_fileoff_t xfs_bmbt_disk_get_startoff(const struct xfs_bmbt_rec *r);
30  void xfs_bmbt_disk_get_all(const struct xfs_bmbt_rec *r,
31  		struct xfs_bmbt_irec *s);
32  
33  extern void xfs_bmbt_to_bmdr(struct xfs_mount *, struct xfs_btree_block *, int,
34  			xfs_bmdr_block_t *, int);
35  
36  extern int xfs_bmbt_get_maxrecs(struct xfs_btree_cur *, int level);
37  extern int xfs_bmdr_maxrecs(int blocklen, int leaf);
38  unsigned int xfs_bmbt_maxrecs(struct xfs_mount *mp, unsigned int blocklen,
39  		bool leaf);
40  
41  extern int xfs_bmbt_change_owner(struct xfs_trans *tp, struct xfs_inode *ip,
42  				 int whichfork, xfs_ino_t new_owner,
43  				 struct list_head *buffer_list);
44  
45  extern struct xfs_btree_cur *xfs_bmbt_init_cursor(struct xfs_mount *,
46  		struct xfs_trans *, struct xfs_inode *, int);
47  void xfs_bmbt_commit_staged_btree(struct xfs_btree_cur *cur,
48  		struct xfs_trans *tp, int whichfork);
49  
50  extern unsigned long long xfs_bmbt_calc_size(struct xfs_mount *mp,
51  		unsigned long long len);
52  
53  unsigned int xfs_bmbt_maxlevels_ondisk(void);
54  
55  int __init xfs_bmbt_init_cur_cache(void);
56  void xfs_bmbt_destroy_cur_cache(void);
57  
58  void xfs_bmbt_init_block(struct xfs_inode *ip, struct xfs_btree_block *buf,
59  		struct xfs_buf *bp, __u16 level, __u16 numrecs);
60  
61  /*
62   * Btree block header size depends on a superblock flag.
63   */
64  static inline size_t
xfs_bmbt_block_len(struct xfs_mount * mp)65  xfs_bmbt_block_len(struct xfs_mount *mp)
66  {
67  	return xfs_has_crc(mp) ?
68  			XFS_BTREE_LBLOCK_CRC_LEN : XFS_BTREE_LBLOCK_LEN;
69  }
70  
71  /* Addresses of key, pointers, and records within an incore bmbt block. */
72  
73  static inline struct xfs_bmbt_rec *
xfs_bmbt_rec_addr(struct xfs_mount * mp,struct xfs_btree_block * block,unsigned int index)74  xfs_bmbt_rec_addr(
75  	struct xfs_mount	*mp,
76  	struct xfs_btree_block	*block,
77  	unsigned int		index)
78  {
79  	return (struct xfs_bmbt_rec *)
80  		((char *)block + xfs_bmbt_block_len(mp) +
81  		 (index - 1) * sizeof(struct xfs_bmbt_rec));
82  }
83  
84  static inline struct xfs_bmbt_key *
xfs_bmbt_key_addr(struct xfs_mount * mp,struct xfs_btree_block * block,unsigned int index)85  xfs_bmbt_key_addr(
86  	struct xfs_mount	*mp,
87  	struct xfs_btree_block	*block,
88  	unsigned int		index)
89  {
90  	return (struct xfs_bmbt_key *)
91  		((char *)block + xfs_bmbt_block_len(mp) +
92  		 (index - 1) * sizeof(struct xfs_bmbt_key *));
93  }
94  
95  static inline xfs_bmbt_ptr_t *
xfs_bmbt_ptr_addr(struct xfs_mount * mp,struct xfs_btree_block * block,unsigned int index,unsigned int maxrecs)96  xfs_bmbt_ptr_addr(
97  	struct xfs_mount	*mp,
98  	struct xfs_btree_block	*block,
99  	unsigned int		index,
100  	unsigned int		maxrecs)
101  {
102  	return (xfs_bmbt_ptr_t *)
103  		((char *)block + xfs_bmbt_block_len(mp) +
104  		 maxrecs * sizeof(struct xfs_bmbt_key) +
105  		 (index - 1) * sizeof(xfs_bmbt_ptr_t));
106  }
107  
108  /* Addresses of key, pointers, and records within an ondisk bmbt block. */
109  
110  static inline struct xfs_bmbt_rec *
xfs_bmdr_rec_addr(struct xfs_bmdr_block * block,unsigned int index)111  xfs_bmdr_rec_addr(
112  	struct xfs_bmdr_block	*block,
113  	unsigned int		index)
114  {
115  	return (struct xfs_bmbt_rec *)
116  		((char *)(block + 1) +
117  		 (index - 1) * sizeof(struct xfs_bmbt_rec));
118  }
119  
120  static inline struct xfs_bmbt_key *
xfs_bmdr_key_addr(struct xfs_bmdr_block * block,unsigned int index)121  xfs_bmdr_key_addr(
122  	struct xfs_bmdr_block	*block,
123  	unsigned int		index)
124  {
125  	return (struct xfs_bmbt_key *)
126  		((char *)(block + 1) +
127  		 (index - 1) * sizeof(struct xfs_bmbt_key));
128  }
129  
130  static inline xfs_bmbt_ptr_t *
xfs_bmdr_ptr_addr(struct xfs_bmdr_block * block,unsigned int index,unsigned int maxrecs)131  xfs_bmdr_ptr_addr(
132  	struct xfs_bmdr_block	*block,
133  	unsigned int		index,
134  	unsigned int		maxrecs)
135  {
136  	return (xfs_bmbt_ptr_t *)
137  		((char *)(block + 1) +
138  		 maxrecs * sizeof(struct xfs_bmbt_key) +
139  		 (index - 1) * sizeof(xfs_bmbt_ptr_t));
140  }
141  
142  /*
143   * Address of pointers within the incore btree root.
144   *
145   * These are to be used when we know the size of the block and
146   * we don't have a cursor.
147   */
148  static inline xfs_bmbt_ptr_t *
xfs_bmap_broot_ptr_addr(struct xfs_mount * mp,struct xfs_btree_block * bb,unsigned int i,unsigned int sz)149  xfs_bmap_broot_ptr_addr(
150  	struct xfs_mount	*mp,
151  	struct xfs_btree_block	*bb,
152  	unsigned int		i,
153  	unsigned int		sz)
154  {
155  	return xfs_bmbt_ptr_addr(mp, bb, i, xfs_bmbt_maxrecs(mp, sz, false));
156  }
157  
158  /*
159   * Compute the space required for the incore btree root containing the given
160   * number of records.
161   */
162  static inline size_t
xfs_bmap_broot_space_calc(struct xfs_mount * mp,unsigned int nrecs)163  xfs_bmap_broot_space_calc(
164  	struct xfs_mount	*mp,
165  	unsigned int		nrecs)
166  {
167  	return xfs_bmbt_block_len(mp) +
168  	       (nrecs * (sizeof(struct xfs_bmbt_key) + sizeof(xfs_bmbt_ptr_t)));
169  }
170  
171  /*
172   * Compute the space required for the incore btree root given the ondisk
173   * btree root block.
174   */
175  static inline size_t
xfs_bmap_broot_space(struct xfs_mount * mp,struct xfs_bmdr_block * bb)176  xfs_bmap_broot_space(
177  	struct xfs_mount	*mp,
178  	struct xfs_bmdr_block	*bb)
179  {
180  	return xfs_bmap_broot_space_calc(mp, be16_to_cpu(bb->bb_numrecs));
181  }
182  
183  /* Compute the space required for the ondisk root block. */
184  static inline size_t
xfs_bmdr_space_calc(unsigned int nrecs)185  xfs_bmdr_space_calc(unsigned int nrecs)
186  {
187  	return sizeof(struct xfs_bmdr_block) +
188  	       (nrecs * (sizeof(struct xfs_bmbt_key) + sizeof(xfs_bmbt_ptr_t)));
189  }
190  
191  /*
192   * Compute the space required for the ondisk root block given an incore root
193   * block.
194   */
195  static inline size_t
xfs_bmap_bmdr_space(struct xfs_btree_block * bb)196  xfs_bmap_bmdr_space(struct xfs_btree_block *bb)
197  {
198  	return xfs_bmdr_space_calc(be16_to_cpu(bb->bb_numrecs));
199  }
200  
201  #endif	/* __XFS_BMAP_BTREE_H__ */
202