1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | |
3 | #ifndef BTRFS_EXTENT_IO_H |
4 | #define BTRFS_EXTENT_IO_H |
5 | |
6 | #include <linux/rbtree.h> |
7 | #include <linux/refcount.h> |
8 | #include <linux/fiemap.h> |
9 | #include <linux/btrfs_tree.h> |
10 | #include "compression.h" |
11 | #include "ulist.h" |
12 | #include "misc.h" |
13 | |
14 | struct btrfs_trans_handle; |
15 | |
16 | enum { |
17 | EXTENT_BUFFER_UPTODATE, |
18 | EXTENT_BUFFER_DIRTY, |
19 | EXTENT_BUFFER_CORRUPT, |
20 | /* this got triggered by readahead */ |
21 | EXTENT_BUFFER_READAHEAD, |
22 | EXTENT_BUFFER_TREE_REF, |
23 | EXTENT_BUFFER_STALE, |
24 | EXTENT_BUFFER_WRITEBACK, |
25 | /* read IO error */ |
26 | EXTENT_BUFFER_READ_ERR, |
27 | EXTENT_BUFFER_UNMAPPED, |
28 | EXTENT_BUFFER_IN_TREE, |
29 | /* write IO error */ |
30 | EXTENT_BUFFER_WRITE_ERR, |
31 | EXTENT_BUFFER_NO_CHECK, |
32 | /* Indicate that extent buffer pages a being read */ |
33 | EXTENT_BUFFER_READING, |
34 | }; |
35 | |
36 | /* these are flags for __process_pages_contig */ |
37 | enum { |
38 | ENUM_BIT(PAGE_UNLOCK), |
39 | /* Page starts writeback, clear dirty bit and set writeback bit */ |
40 | ENUM_BIT(PAGE_START_WRITEBACK), |
41 | ENUM_BIT(PAGE_END_WRITEBACK), |
42 | ENUM_BIT(PAGE_SET_ORDERED), |
43 | }; |
44 | |
45 | /* |
46 | * page->private values. Every page that is controlled by the extent |
47 | * map has page->private set to one. |
48 | */ |
49 | #define EXTENT_PAGE_PRIVATE 1 |
50 | |
51 | /* |
52 | * The extent buffer bitmap operations are done with byte granularity instead of |
53 | * word granularity for two reasons: |
54 | * 1. The bitmaps must be little-endian on disk. |
55 | * 2. Bitmap items are not guaranteed to be aligned to a word and therefore a |
56 | * single word in a bitmap may straddle two pages in the extent buffer. |
57 | */ |
58 | #define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE) |
59 | #define BYTE_MASK ((1 << BITS_PER_BYTE) - 1) |
60 | #define BITMAP_FIRST_BYTE_MASK(start) \ |
61 | ((BYTE_MASK << ((start) & (BITS_PER_BYTE - 1))) & BYTE_MASK) |
62 | #define BITMAP_LAST_BYTE_MASK(nbits) \ |
63 | (BYTE_MASK >> (-(nbits) & (BITS_PER_BYTE - 1))) |
64 | |
65 | struct btrfs_root; |
66 | struct btrfs_inode; |
67 | struct btrfs_fs_info; |
68 | struct extent_io_tree; |
69 | struct btrfs_tree_parent_check; |
70 | |
71 | int __init extent_buffer_init_cachep(void); |
72 | void __cold extent_buffer_free_cachep(void); |
73 | |
74 | #define INLINE_EXTENT_BUFFER_PAGES (BTRFS_MAX_METADATA_BLOCKSIZE / PAGE_SIZE) |
75 | struct extent_buffer { |
76 | u64 start; |
77 | unsigned long len; |
78 | unsigned long bflags; |
79 | struct btrfs_fs_info *fs_info; |
80 | spinlock_t refs_lock; |
81 | atomic_t refs; |
82 | int read_mirror; |
83 | /* >= 0 if eb belongs to a log tree, -1 otherwise */ |
84 | s8 log_index; |
85 | struct rcu_head rcu_head; |
86 | |
87 | struct rw_semaphore lock; |
88 | |
89 | struct page *pages[INLINE_EXTENT_BUFFER_PAGES]; |
90 | #ifdef CONFIG_BTRFS_DEBUG |
91 | struct list_head leak_list; |
92 | pid_t lock_owner; |
93 | #endif |
94 | }; |
95 | |
96 | struct btrfs_eb_write_context { |
97 | struct writeback_control *wbc; |
98 | struct extent_buffer *eb; |
99 | /* Block group @eb resides in. Only used for zoned mode. */ |
100 | struct btrfs_block_group *zoned_bg; |
101 | }; |
102 | |
103 | /* |
104 | * Get the correct offset inside the page of extent buffer. |
105 | * |
106 | * @eb: target extent buffer |
107 | * @start: offset inside the extent buffer |
108 | * |
109 | * Will handle both sectorsize == PAGE_SIZE and sectorsize < PAGE_SIZE cases. |
110 | */ |
111 | static inline size_t get_eb_offset_in_page(const struct extent_buffer *eb, |
112 | unsigned long offset) |
113 | { |
114 | /* |
115 | * For sectorsize == PAGE_SIZE case, eb->start will always be aligned |
116 | * to PAGE_SIZE, thus adding it won't cause any difference. |
117 | * |
118 | * For sectorsize < PAGE_SIZE, we must only read the data that belongs |
119 | * to the eb, thus we have to take the eb->start into consideration. |
120 | */ |
121 | return offset_in_page(offset + eb->start); |
122 | } |
123 | |
124 | static inline unsigned long get_eb_page_index(unsigned long offset) |
125 | { |
126 | /* |
127 | * For sectorsize == PAGE_SIZE case, plain >> PAGE_SHIFT is enough. |
128 | * |
129 | * For sectorsize < PAGE_SIZE case, we only support 64K PAGE_SIZE, |
130 | * and have ensured that all tree blocks are contained in one page, |
131 | * thus we always get index == 0. |
132 | */ |
133 | return offset >> PAGE_SHIFT; |
134 | } |
135 | |
136 | /* |
137 | * Structure to record how many bytes and which ranges are set/cleared |
138 | */ |
139 | struct extent_changeset { |
140 | /* How many bytes are set/cleared in this operation */ |
141 | u64 bytes_changed; |
142 | |
143 | /* Changed ranges */ |
144 | struct ulist range_changed; |
145 | }; |
146 | |
147 | static inline void extent_changeset_init(struct extent_changeset *changeset) |
148 | { |
149 | changeset->bytes_changed = 0; |
150 | ulist_init(ulist: &changeset->range_changed); |
151 | } |
152 | |
153 | static inline struct extent_changeset *extent_changeset_alloc(void) |
154 | { |
155 | struct extent_changeset *ret; |
156 | |
157 | ret = kmalloc(size: sizeof(*ret), GFP_KERNEL); |
158 | if (!ret) |
159 | return NULL; |
160 | |
161 | extent_changeset_init(changeset: ret); |
162 | return ret; |
163 | } |
164 | |
165 | static inline void extent_changeset_release(struct extent_changeset *changeset) |
166 | { |
167 | if (!changeset) |
168 | return; |
169 | changeset->bytes_changed = 0; |
170 | ulist_release(ulist: &changeset->range_changed); |
171 | } |
172 | |
173 | static inline void extent_changeset_free(struct extent_changeset *changeset) |
174 | { |
175 | if (!changeset) |
176 | return; |
177 | extent_changeset_release(changeset); |
178 | kfree(objp: changeset); |
179 | } |
180 | |
181 | struct extent_map_tree; |
182 | |
183 | int try_release_extent_mapping(struct page *page, gfp_t mask); |
184 | int try_release_extent_buffer(struct page *page); |
185 | |
186 | int btrfs_read_folio(struct file *file, struct folio *folio); |
187 | void extent_write_locked_range(struct inode *inode, struct page *locked_page, |
188 | u64 start, u64 end, struct writeback_control *wbc, |
189 | bool pages_dirty); |
190 | int extent_writepages(struct address_space *mapping, |
191 | struct writeback_control *wbc); |
192 | int btree_write_cache_pages(struct address_space *mapping, |
193 | struct writeback_control *wbc); |
194 | void extent_readahead(struct readahead_control *rac); |
195 | int extent_fiemap(struct btrfs_inode *inode, struct fiemap_extent_info *fieinfo, |
196 | u64 start, u64 len); |
197 | int set_page_extent_mapped(struct page *page); |
198 | void clear_page_extent_mapped(struct page *page); |
199 | |
200 | struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info, |
201 | u64 start, u64 owner_root, int level); |
202 | struct extent_buffer *__alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info, |
203 | u64 start, unsigned long len); |
204 | struct extent_buffer *alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info, |
205 | u64 start); |
206 | struct extent_buffer *btrfs_clone_extent_buffer(const struct extent_buffer *src); |
207 | struct extent_buffer *find_extent_buffer(struct btrfs_fs_info *fs_info, |
208 | u64 start); |
209 | void free_extent_buffer(struct extent_buffer *eb); |
210 | void free_extent_buffer_stale(struct extent_buffer *eb); |
211 | #define WAIT_NONE 0 |
212 | #define WAIT_COMPLETE 1 |
213 | #define WAIT_PAGE_LOCK 2 |
214 | int read_extent_buffer_pages(struct extent_buffer *eb, int wait, int mirror_num, |
215 | struct btrfs_tree_parent_check *parent_check); |
216 | void wait_on_extent_buffer_writeback(struct extent_buffer *eb); |
217 | void btrfs_readahead_tree_block(struct btrfs_fs_info *fs_info, |
218 | u64 bytenr, u64 owner_root, u64 gen, int level); |
219 | void btrfs_readahead_node_child(struct extent_buffer *node, int slot); |
220 | |
221 | static inline int num_extent_pages(const struct extent_buffer *eb) |
222 | { |
223 | /* |
224 | * For sectorsize == PAGE_SIZE case, since nodesize is always aligned to |
225 | * sectorsize, it's just eb->len >> PAGE_SHIFT. |
226 | * |
227 | * For sectorsize < PAGE_SIZE case, we could have nodesize < PAGE_SIZE, |
228 | * thus have to ensure we get at least one page. |
229 | */ |
230 | return (eb->len >> PAGE_SHIFT) ?: 1; |
231 | } |
232 | |
233 | static inline int extent_buffer_uptodate(const struct extent_buffer *eb) |
234 | { |
235 | return test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); |
236 | } |
237 | |
238 | int memcmp_extent_buffer(const struct extent_buffer *eb, const void *ptrv, |
239 | unsigned long start, unsigned long len); |
240 | void read_extent_buffer(const struct extent_buffer *eb, void *dst, |
241 | unsigned long start, |
242 | unsigned long len); |
243 | int read_extent_buffer_to_user_nofault(const struct extent_buffer *eb, |
244 | void __user *dst, unsigned long start, |
245 | unsigned long len); |
246 | void write_extent_buffer(const struct extent_buffer *eb, const void *src, |
247 | unsigned long start, unsigned long len); |
248 | |
249 | static inline void write_extent_buffer_chunk_tree_uuid( |
250 | const struct extent_buffer *eb, const void *chunk_tree_uuid) |
251 | { |
252 | write_extent_buffer(eb, src: chunk_tree_uuid, |
253 | offsetof(struct btrfs_header, chunk_tree_uuid), |
254 | BTRFS_FSID_SIZE); |
255 | } |
256 | |
257 | static inline void write_extent_buffer_fsid(const struct extent_buffer *eb, |
258 | const void *fsid) |
259 | { |
260 | write_extent_buffer(eb, src: fsid, offsetof(struct btrfs_header, fsid), |
261 | BTRFS_FSID_SIZE); |
262 | } |
263 | |
264 | void copy_extent_buffer_full(const struct extent_buffer *dst, |
265 | const struct extent_buffer *src); |
266 | void copy_extent_buffer(const struct extent_buffer *dst, |
267 | const struct extent_buffer *src, |
268 | unsigned long dst_offset, unsigned long src_offset, |
269 | unsigned long len); |
270 | void memcpy_extent_buffer(const struct extent_buffer *dst, |
271 | unsigned long dst_offset, unsigned long src_offset, |
272 | unsigned long len); |
273 | void memmove_extent_buffer(const struct extent_buffer *dst, |
274 | unsigned long dst_offset, unsigned long src_offset, |
275 | unsigned long len); |
276 | void memzero_extent_buffer(const struct extent_buffer *eb, unsigned long start, |
277 | unsigned long len); |
278 | int extent_buffer_test_bit(const struct extent_buffer *eb, unsigned long start, |
279 | unsigned long pos); |
280 | void extent_buffer_bitmap_set(const struct extent_buffer *eb, unsigned long start, |
281 | unsigned long pos, unsigned long len); |
282 | void extent_buffer_bitmap_clear(const struct extent_buffer *eb, |
283 | unsigned long start, unsigned long pos, |
284 | unsigned long len); |
285 | void set_extent_buffer_dirty(struct extent_buffer *eb); |
286 | void set_extent_buffer_uptodate(struct extent_buffer *eb); |
287 | void clear_extent_buffer_uptodate(struct extent_buffer *eb); |
288 | void extent_range_clear_dirty_for_io(struct inode *inode, u64 start, u64 end); |
289 | void extent_clear_unlock_delalloc(struct btrfs_inode *inode, u64 start, u64 end, |
290 | struct page *locked_page, |
291 | u32 bits_to_clear, unsigned long page_ops); |
292 | int extent_invalidate_folio(struct extent_io_tree *tree, |
293 | struct folio *folio, size_t offset); |
294 | void btrfs_clear_buffer_dirty(struct btrfs_trans_handle *trans, |
295 | struct extent_buffer *buf); |
296 | |
297 | int btrfs_alloc_page_array(unsigned int nr_pages, struct page **page_array); |
298 | |
299 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS |
300 | bool find_lock_delalloc_range(struct inode *inode, |
301 | struct page *locked_page, u64 *start, |
302 | u64 *end); |
303 | #endif |
304 | struct extent_buffer *alloc_test_extent_buffer(struct btrfs_fs_info *fs_info, |
305 | u64 start); |
306 | |
307 | #ifdef CONFIG_BTRFS_DEBUG |
308 | void btrfs_extent_buffer_leak_debug_check(struct btrfs_fs_info *fs_info); |
309 | #else |
310 | #define btrfs_extent_buffer_leak_debug_check(fs_info) do {} while (0) |
311 | #endif |
312 | |
313 | #endif |
314 | |