1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * Copyright (c) 2000-2006 Silicon Graphics, Inc. |
4 | * All Rights Reserved. |
5 | */ |
6 | #ifndef __XFS_BMAP_H__ |
7 | #define __XFS_BMAP_H__ |
8 | |
9 | struct getbmap; |
10 | struct xfs_bmbt_irec; |
11 | struct xfs_ifork; |
12 | struct xfs_inode; |
13 | struct xfs_mount; |
14 | struct xfs_trans; |
15 | struct xfs_alloc_arg; |
16 | |
17 | /* |
18 | * Argument structure for xfs_bmap_alloc. |
19 | */ |
20 | struct xfs_bmalloca { |
21 | struct xfs_trans *tp; /* transaction pointer */ |
22 | struct xfs_inode *ip; /* incore inode pointer */ |
23 | struct xfs_bmbt_irec prev; /* extent before the new one */ |
24 | struct xfs_bmbt_irec got; /* extent after, or delayed */ |
25 | |
26 | xfs_fileoff_t offset; /* offset in file filling in */ |
27 | xfs_extlen_t length; /* i/o length asked/allocated */ |
28 | xfs_fsblock_t blkno; /* starting block of new extent */ |
29 | |
30 | struct xfs_btree_cur *cur; /* btree cursor */ |
31 | struct xfs_iext_cursor icur; /* incore extent cursor */ |
32 | int nallocs;/* number of extents alloc'd */ |
33 | int logflags;/* flags for transaction logging */ |
34 | |
35 | xfs_extlen_t total; /* total blocks needed for xaction */ |
36 | xfs_extlen_t minlen; /* minimum allocation size (blocks) */ |
37 | xfs_extlen_t minleft; /* amount must be left after alloc */ |
38 | bool eof; /* set if allocating past last extent */ |
39 | bool wasdel; /* replacing a delayed allocation */ |
40 | bool aeof; /* allocated space at eof */ |
41 | bool conv; /* overwriting unwritten extents */ |
42 | int datatype;/* data type being allocated */ |
43 | uint32_t flags; |
44 | }; |
45 | |
46 | #define XFS_BMAP_MAX_NMAP 4 |
47 | |
48 | /* |
49 | * Flags for xfs_bmapi_* |
50 | */ |
51 | #define XFS_BMAPI_ENTIRE (1u << 0) /* return entire extent untrimmed */ |
52 | #define XFS_BMAPI_METADATA (1u << 1) /* mapping metadata not user data */ |
53 | #define XFS_BMAPI_ATTRFORK (1u << 2) /* use attribute fork not data */ |
54 | #define XFS_BMAPI_PREALLOC (1u << 3) /* preallocating unwritten space */ |
55 | #define XFS_BMAPI_CONTIG (1u << 4) /* must allocate only one extent */ |
56 | /* |
57 | * unwritten extent conversion - this needs write cache flushing and no additional |
58 | * allocation alignments. When specified with XFS_BMAPI_PREALLOC it converts |
59 | * from written to unwritten, otherwise convert from unwritten to written. |
60 | */ |
61 | #define XFS_BMAPI_CONVERT (1u << 5) |
62 | |
63 | /* |
64 | * allocate zeroed extents - this requires all newly allocated user data extents |
65 | * to be initialised to zero. It will be ignored if XFS_BMAPI_METADATA is set. |
66 | * Use in conjunction with XFS_BMAPI_CONVERT to convert unwritten extents found |
67 | * during the allocation range to zeroed written extents. |
68 | */ |
69 | #define XFS_BMAPI_ZERO (1u << 6) |
70 | |
71 | /* |
72 | * Map the inode offset to the block given in ap->firstblock. Primarily |
73 | * used for reflink. The range must be in a hole, and this flag cannot be |
74 | * turned on with PREALLOC or CONVERT, and cannot be used on the attr fork. |
75 | * |
76 | * For bunmapi, this flag unmaps the range without adjusting quota, reducing |
77 | * refcount, or freeing the blocks. |
78 | */ |
79 | #define XFS_BMAPI_REMAP (1u << 7) |
80 | |
81 | /* Map something in the CoW fork. */ |
82 | #define XFS_BMAPI_COWFORK (1u << 8) |
83 | |
84 | /* Skip online discard of freed extents */ |
85 | #define XFS_BMAPI_NODISCARD (1u << 9) |
86 | |
87 | /* Do not update the rmap btree. Used for reconstructing bmbt from rmapbt. */ |
88 | #define XFS_BMAPI_NORMAP (1u << 10) |
89 | |
90 | #define XFS_BMAPI_FLAGS \ |
91 | { XFS_BMAPI_ENTIRE, "ENTIRE" }, \ |
92 | { XFS_BMAPI_METADATA, "METADATA" }, \ |
93 | { XFS_BMAPI_ATTRFORK, "ATTRFORK" }, \ |
94 | { XFS_BMAPI_PREALLOC, "PREALLOC" }, \ |
95 | { XFS_BMAPI_CONTIG, "CONTIG" }, \ |
96 | { XFS_BMAPI_CONVERT, "CONVERT" }, \ |
97 | { XFS_BMAPI_ZERO, "ZERO" }, \ |
98 | { XFS_BMAPI_REMAP, "REMAP" }, \ |
99 | { XFS_BMAPI_COWFORK, "COWFORK" }, \ |
100 | { XFS_BMAPI_NODISCARD, "NODISCARD" }, \ |
101 | { XFS_BMAPI_NORMAP, "NORMAP" } |
102 | |
103 | |
104 | static inline int xfs_bmapi_aflag(int w) |
105 | { |
106 | return (w == XFS_ATTR_FORK ? XFS_BMAPI_ATTRFORK : |
107 | (w == XFS_COW_FORK ? XFS_BMAPI_COWFORK : 0)); |
108 | } |
109 | |
110 | static inline int xfs_bmapi_whichfork(uint32_t bmapi_flags) |
111 | { |
112 | if (bmapi_flags & XFS_BMAPI_COWFORK) |
113 | return XFS_COW_FORK; |
114 | else if (bmapi_flags & XFS_BMAPI_ATTRFORK) |
115 | return XFS_ATTR_FORK; |
116 | return XFS_DATA_FORK; |
117 | } |
118 | |
119 | void xfs_bmap_alloc_account(struct xfs_bmalloca *ap); |
120 | |
121 | /* |
122 | * Special values for xfs_bmbt_irec_t br_startblock field. |
123 | */ |
124 | #define DELAYSTARTBLOCK ((xfs_fsblock_t)-1LL) |
125 | #define HOLESTARTBLOCK ((xfs_fsblock_t)-2LL) |
126 | |
127 | /* |
128 | * Flags for xfs_bmap_add_extent*. |
129 | */ |
130 | #define BMAP_LEFT_CONTIG (1u << 0) |
131 | #define BMAP_RIGHT_CONTIG (1u << 1) |
132 | #define BMAP_LEFT_FILLING (1u << 2) |
133 | #define BMAP_RIGHT_FILLING (1u << 3) |
134 | #define BMAP_LEFT_DELAY (1u << 4) |
135 | #define BMAP_RIGHT_DELAY (1u << 5) |
136 | #define BMAP_LEFT_VALID (1u << 6) |
137 | #define BMAP_RIGHT_VALID (1u << 7) |
138 | #define BMAP_ATTRFORK (1u << 8) |
139 | #define BMAP_COWFORK (1u << 9) |
140 | |
141 | #define XFS_BMAP_EXT_FLAGS \ |
142 | { BMAP_LEFT_CONTIG, "LC" }, \ |
143 | { BMAP_RIGHT_CONTIG, "RC" }, \ |
144 | { BMAP_LEFT_FILLING, "LF" }, \ |
145 | { BMAP_RIGHT_FILLING, "RF" }, \ |
146 | { BMAP_ATTRFORK, "ATTR" }, \ |
147 | { BMAP_COWFORK, "COW" } |
148 | |
149 | /* Return true if the extent is an allocated extent, written or not. */ |
150 | static inline bool xfs_bmap_is_real_extent(const struct xfs_bmbt_irec *irec) |
151 | { |
152 | return irec->br_startblock != HOLESTARTBLOCK && |
153 | irec->br_startblock != DELAYSTARTBLOCK && |
154 | !isnullstartblock(irec->br_startblock); |
155 | } |
156 | |
157 | /* |
158 | * Return true if the extent is a real, allocated extent, or false if it is a |
159 | * delayed allocation, and unwritten extent or a hole. |
160 | */ |
161 | static inline bool xfs_bmap_is_written_extent(struct xfs_bmbt_irec *irec) |
162 | { |
163 | return xfs_bmap_is_real_extent(irec) && |
164 | irec->br_state != XFS_EXT_UNWRITTEN; |
165 | } |
166 | |
167 | /* |
168 | * Check the mapping for obviously garbage allocations that could trash the |
169 | * filesystem immediately. |
170 | */ |
171 | #define xfs_valid_startblock(ip, startblock) \ |
172 | ((startblock) != 0 || XFS_IS_REALTIME_INODE(ip)) |
173 | |
174 | int xfs_bmap_longest_free_extent(struct xfs_perag *pag, |
175 | struct xfs_trans *tp, xfs_extlen_t *blen); |
176 | void xfs_trim_extent(struct xfs_bmbt_irec *irec, xfs_fileoff_t bno, |
177 | xfs_filblks_t len); |
178 | unsigned int xfs_bmap_compute_attr_offset(struct xfs_mount *mp); |
179 | int xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd); |
180 | void xfs_bmap_local_to_extents_empty(struct xfs_trans *tp, |
181 | struct xfs_inode *ip, int whichfork); |
182 | void xfs_bmap_compute_maxlevels(struct xfs_mount *mp, int whichfork); |
183 | int xfs_bmap_first_unused(struct xfs_trans *tp, struct xfs_inode *ip, |
184 | xfs_extlen_t len, xfs_fileoff_t *unused, int whichfork); |
185 | int xfs_bmap_last_before(struct xfs_trans *tp, struct xfs_inode *ip, |
186 | xfs_fileoff_t *last_block, int whichfork); |
187 | int xfs_bmap_last_offset(struct xfs_inode *ip, xfs_fileoff_t *unused, |
188 | int whichfork); |
189 | int xfs_bmapi_read(struct xfs_inode *ip, xfs_fileoff_t bno, |
190 | xfs_filblks_t len, struct xfs_bmbt_irec *mval, |
191 | int *nmap, uint32_t flags); |
192 | int xfs_bmapi_write(struct xfs_trans *tp, struct xfs_inode *ip, |
193 | xfs_fileoff_t bno, xfs_filblks_t len, uint32_t flags, |
194 | xfs_extlen_t total, struct xfs_bmbt_irec *mval, int *nmap); |
195 | int xfs_bunmapi(struct xfs_trans *tp, struct xfs_inode *ip, |
196 | xfs_fileoff_t bno, xfs_filblks_t len, uint32_t flags, |
197 | xfs_extnum_t nexts, int *done); |
198 | int xfs_bmap_del_extent_delay(struct xfs_inode *ip, int whichfork, |
199 | struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *got, |
200 | struct xfs_bmbt_irec *del); |
201 | void xfs_bmap_del_extent_cow(struct xfs_inode *ip, |
202 | struct xfs_iext_cursor *cur, struct xfs_bmbt_irec *got, |
203 | struct xfs_bmbt_irec *del); |
204 | uint xfs_default_attroffset(struct xfs_inode *ip); |
205 | int xfs_bmap_collapse_extents(struct xfs_trans *tp, struct xfs_inode *ip, |
206 | xfs_fileoff_t *next_fsb, xfs_fileoff_t offset_shift_fsb, |
207 | bool *done); |
208 | int xfs_bmap_can_insert_extents(struct xfs_inode *ip, xfs_fileoff_t off, |
209 | xfs_fileoff_t shift); |
210 | int xfs_bmap_insert_extents(struct xfs_trans *tp, struct xfs_inode *ip, |
211 | xfs_fileoff_t *next_fsb, xfs_fileoff_t offset_shift_fsb, |
212 | bool *done, xfs_fileoff_t stop_fsb); |
213 | int xfs_bmap_split_extent(struct xfs_trans *tp, struct xfs_inode *ip, |
214 | xfs_fileoff_t split_offset); |
215 | int xfs_bmapi_reserve_delalloc(struct xfs_inode *ip, int whichfork, |
216 | xfs_fileoff_t off, xfs_filblks_t len, xfs_filblks_t prealloc, |
217 | struct xfs_bmbt_irec *got, struct xfs_iext_cursor *cur, |
218 | int eof); |
219 | int xfs_bmapi_convert_delalloc(struct xfs_inode *ip, int whichfork, |
220 | xfs_off_t offset, struct iomap *iomap, unsigned int *seq); |
221 | int xfs_bmap_add_extent_unwritten_real(struct xfs_trans *tp, |
222 | struct xfs_inode *ip, int whichfork, |
223 | struct xfs_iext_cursor *icur, struct xfs_btree_cur **curp, |
224 | struct xfs_bmbt_irec *new, int *logflagsp); |
225 | xfs_extlen_t xfs_bmapi_minleft(struct xfs_trans *tp, struct xfs_inode *ip, |
226 | int fork); |
227 | int xfs_bmap_btalloc_low_space(struct xfs_bmalloca *ap, |
228 | struct xfs_alloc_arg *args); |
229 | |
230 | enum xfs_bmap_intent_type { |
231 | XFS_BMAP_MAP = 1, |
232 | XFS_BMAP_UNMAP, |
233 | }; |
234 | |
235 | #define XFS_BMAP_INTENT_STRINGS \ |
236 | { XFS_BMAP_MAP, "map" }, \ |
237 | { XFS_BMAP_UNMAP, "unmap" } |
238 | |
239 | struct xfs_bmap_intent { |
240 | struct list_head bi_list; |
241 | enum xfs_bmap_intent_type bi_type; |
242 | int bi_whichfork; |
243 | struct xfs_inode *bi_owner; |
244 | struct xfs_perag *bi_pag; |
245 | struct xfs_bmbt_irec bi_bmap; |
246 | }; |
247 | |
248 | int xfs_bmap_finish_one(struct xfs_trans *tp, struct xfs_bmap_intent *bi); |
249 | void xfs_bmap_map_extent(struct xfs_trans *tp, struct xfs_inode *ip, |
250 | int whichfork, struct xfs_bmbt_irec *imap); |
251 | void xfs_bmap_unmap_extent(struct xfs_trans *tp, struct xfs_inode *ip, |
252 | int whichfork, struct xfs_bmbt_irec *imap); |
253 | |
254 | static inline uint32_t xfs_bmap_fork_to_state(int whichfork) |
255 | { |
256 | switch (whichfork) { |
257 | case XFS_ATTR_FORK: |
258 | return BMAP_ATTRFORK; |
259 | case XFS_COW_FORK: |
260 | return BMAP_COWFORK; |
261 | default: |
262 | return 0; |
263 | } |
264 | } |
265 | |
266 | xfs_failaddr_t xfs_bmap_validate_extent_raw(struct xfs_mount *mp, bool rtfile, |
267 | int whichfork, struct xfs_bmbt_irec *irec); |
268 | xfs_failaddr_t xfs_bmap_validate_extent(struct xfs_inode *ip, int whichfork, |
269 | struct xfs_bmbt_irec *irec); |
270 | int xfs_bmap_complain_bad_rec(struct xfs_inode *ip, int whichfork, |
271 | xfs_failaddr_t fa, const struct xfs_bmbt_irec *irec); |
272 | |
273 | int xfs_bmapi_remap(struct xfs_trans *tp, struct xfs_inode *ip, |
274 | xfs_fileoff_t bno, xfs_filblks_t len, xfs_fsblock_t startblock, |
275 | uint32_t flags); |
276 | int xfs_bunmapi_range(struct xfs_trans **tpp, struct xfs_inode *ip, |
277 | uint32_t flags, xfs_fileoff_t startoff, xfs_fileoff_t endoff); |
278 | |
279 | extern struct kmem_cache *xfs_bmap_intent_cache; |
280 | |
281 | int __init xfs_bmap_intent_init_cache(void); |
282 | void xfs_bmap_intent_destroy_cache(void); |
283 | |
284 | typedef int (*xfs_bmap_query_range_fn)( |
285 | struct xfs_btree_cur *cur, |
286 | struct xfs_bmbt_irec *rec, |
287 | void *priv); |
288 | |
289 | int xfs_bmap_query_all(struct xfs_btree_cur *cur, xfs_bmap_query_range_fn fn, |
290 | void *priv); |
291 | |
292 | #endif /* __XFS_BMAP_H__ */ |
293 | |