1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2007 Oracle. All rights reserved.
4 */
5
6 #include <linux/bio.h>
7 #include <linux/slab.h>
8 #include <linux/pagemap.h>
9 #include <linux/highmem.h>
10 #include <linux/sched/mm.h>
11 #include <crypto/hash.h>
12 #include "messages.h"
13 #include "ctree.h"
14 #include "disk-io.h"
15 #include "transaction.h"
16 #include "bio.h"
17 #include "compression.h"
18 #include "fs.h"
19 #include "accessors.h"
20 #include "file-item.h"
21
22 #define __MAX_CSUM_ITEMS(r, size) ((unsigned long)(((BTRFS_LEAF_DATA_SIZE(r) - \
23 sizeof(struct btrfs_item) * 2) / \
24 size) - 1))
25
26 #define MAX_CSUM_ITEMS(r, size) (min_t(u32, __MAX_CSUM_ITEMS(r, size), \
27 PAGE_SIZE))
28
29 /*
30 * Set inode's size according to filesystem options.
31 *
32 * @inode: inode we want to update the disk_i_size for
33 * @new_i_size: i_size we want to set to, 0 if we use i_size
34 *
35 * With NO_HOLES set this simply sets the disk_is_size to whatever i_size_read()
36 * returns as it is perfectly fine with a file that has holes without hole file
37 * extent items.
38 *
39 * However without NO_HOLES we need to only return the area that is contiguous
40 * from the 0 offset of the file. Otherwise we could end up adjust i_size up
41 * to an extent that has a gap in between.
42 *
43 * Finally new_i_size should only be set in the case of truncate where we're not
44 * ready to use i_size_read() as the limiter yet.
45 */
btrfs_inode_safe_disk_i_size_write(struct btrfs_inode * inode,u64 new_i_size)46 void btrfs_inode_safe_disk_i_size_write(struct btrfs_inode *inode, u64 new_i_size)
47 {
48 u64 start, end, i_size;
49 int ret;
50
51 spin_lock(&inode->lock);
52 i_size = new_i_size ?: i_size_read(&inode->vfs_inode);
53 if (!inode->file_extent_tree) {
54 inode->disk_i_size = i_size;
55 goto out_unlock;
56 }
57
58 ret = find_contiguous_extent_bit(inode->file_extent_tree, 0, &start,
59 &end, EXTENT_DIRTY);
60 if (!ret && start == 0)
61 i_size = min(i_size, end + 1);
62 else
63 i_size = 0;
64 inode->disk_i_size = i_size;
65 out_unlock:
66 spin_unlock(&inode->lock);
67 }
68
69 /*
70 * Mark range within a file as having a new extent inserted.
71 *
72 * @inode: inode being modified
73 * @start: start file offset of the file extent we've inserted
74 * @len: logical length of the file extent item
75 *
76 * Call when we are inserting a new file extent where there was none before.
77 * Does not need to call this in the case where we're replacing an existing file
78 * extent, however if not sure it's fine to call this multiple times.
79 *
80 * The start and len must match the file extent item, so thus must be sectorsize
81 * aligned.
82 */
btrfs_inode_set_file_extent_range(struct btrfs_inode * inode,u64 start,u64 len)83 int btrfs_inode_set_file_extent_range(struct btrfs_inode *inode, u64 start,
84 u64 len)
85 {
86 if (!inode->file_extent_tree)
87 return 0;
88
89 if (len == 0)
90 return 0;
91
92 ASSERT(IS_ALIGNED(start + len, inode->root->fs_info->sectorsize));
93
94 return set_extent_bit(inode->file_extent_tree, start, start + len - 1,
95 EXTENT_DIRTY, NULL);
96 }
97
98 /*
99 * Mark an inode range as not having a backing extent.
100 *
101 * @inode: inode being modified
102 * @start: start file offset of the file extent we've inserted
103 * @len: logical length of the file extent item
104 *
105 * Called when we drop a file extent, for example when we truncate. Doesn't
106 * need to be called for cases where we're replacing a file extent, like when
107 * we've COWed a file extent.
108 *
109 * The start and len must match the file extent item, so thus must be sectorsize
110 * aligned.
111 */
btrfs_inode_clear_file_extent_range(struct btrfs_inode * inode,u64 start,u64 len)112 int btrfs_inode_clear_file_extent_range(struct btrfs_inode *inode, u64 start,
113 u64 len)
114 {
115 if (!inode->file_extent_tree)
116 return 0;
117
118 if (len == 0)
119 return 0;
120
121 ASSERT(IS_ALIGNED(start + len, inode->root->fs_info->sectorsize) ||
122 len == (u64)-1);
123
124 return clear_extent_bit(inode->file_extent_tree, start,
125 start + len - 1, EXTENT_DIRTY, NULL);
126 }
127
bytes_to_csum_size(const struct btrfs_fs_info * fs_info,u32 bytes)128 static size_t bytes_to_csum_size(const struct btrfs_fs_info *fs_info, u32 bytes)
129 {
130 ASSERT(IS_ALIGNED(bytes, fs_info->sectorsize));
131
132 return (bytes >> fs_info->sectorsize_bits) * fs_info->csum_size;
133 }
134
csum_size_to_bytes(const struct btrfs_fs_info * fs_info,u32 csum_size)135 static size_t csum_size_to_bytes(const struct btrfs_fs_info *fs_info, u32 csum_size)
136 {
137 ASSERT(IS_ALIGNED(csum_size, fs_info->csum_size));
138
139 return (csum_size / fs_info->csum_size) << fs_info->sectorsize_bits;
140 }
141
max_ordered_sum_bytes(const struct btrfs_fs_info * fs_info)142 static inline u32 max_ordered_sum_bytes(const struct btrfs_fs_info *fs_info)
143 {
144 u32 max_csum_size = round_down(PAGE_SIZE - sizeof(struct btrfs_ordered_sum),
145 fs_info->csum_size);
146
147 return csum_size_to_bytes(fs_info, max_csum_size);
148 }
149
150 /*
151 * Calculate the total size needed to allocate for an ordered sum structure
152 * spanning @bytes in the file.
153 */
btrfs_ordered_sum_size(const struct btrfs_fs_info * fs_info,unsigned long bytes)154 static int btrfs_ordered_sum_size(const struct btrfs_fs_info *fs_info, unsigned long bytes)
155 {
156 return sizeof(struct btrfs_ordered_sum) + bytes_to_csum_size(fs_info, bytes);
157 }
158
btrfs_insert_hole_extent(struct btrfs_trans_handle * trans,struct btrfs_root * root,u64 objectid,u64 pos,u64 num_bytes)159 int btrfs_insert_hole_extent(struct btrfs_trans_handle *trans,
160 struct btrfs_root *root,
161 u64 objectid, u64 pos, u64 num_bytes)
162 {
163 int ret = 0;
164 struct btrfs_file_extent_item *item;
165 struct btrfs_key file_key;
166 BTRFS_PATH_AUTO_FREE(path);
167 struct extent_buffer *leaf;
168
169 path = btrfs_alloc_path();
170 if (!path)
171 return -ENOMEM;
172
173 file_key.objectid = objectid;
174 file_key.type = BTRFS_EXTENT_DATA_KEY;
175 file_key.offset = pos;
176
177 ret = btrfs_insert_empty_item(trans, root, path, &file_key,
178 sizeof(*item));
179 if (ret < 0)
180 return ret;
181 leaf = path->nodes[0];
182 item = btrfs_item_ptr(leaf, path->slots[0],
183 struct btrfs_file_extent_item);
184 btrfs_set_file_extent_disk_bytenr(leaf, item, 0);
185 btrfs_set_file_extent_disk_num_bytes(leaf, item, 0);
186 btrfs_set_file_extent_offset(leaf, item, 0);
187 btrfs_set_file_extent_num_bytes(leaf, item, num_bytes);
188 btrfs_set_file_extent_ram_bytes(leaf, item, num_bytes);
189 btrfs_set_file_extent_generation(leaf, item, trans->transid);
190 btrfs_set_file_extent_type(leaf, item, BTRFS_FILE_EXTENT_REG);
191 btrfs_set_file_extent_compression(leaf, item, 0);
192 btrfs_set_file_extent_encryption(leaf, item, 0);
193 btrfs_set_file_extent_other_encoding(leaf, item, 0);
194
195 return ret;
196 }
197
198 static struct btrfs_csum_item *
btrfs_lookup_csum(struct btrfs_trans_handle * trans,struct btrfs_root * root,struct btrfs_path * path,u64 bytenr,int cow)199 btrfs_lookup_csum(struct btrfs_trans_handle *trans,
200 struct btrfs_root *root,
201 struct btrfs_path *path,
202 u64 bytenr, int cow)
203 {
204 struct btrfs_fs_info *fs_info = root->fs_info;
205 int ret;
206 struct btrfs_key file_key;
207 struct btrfs_key found_key;
208 struct btrfs_csum_item *item;
209 struct extent_buffer *leaf;
210 u64 csum_offset = 0;
211 const u32 csum_size = fs_info->csum_size;
212 int csums_in_item;
213
214 file_key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
215 file_key.type = BTRFS_EXTENT_CSUM_KEY;
216 file_key.offset = bytenr;
217 ret = btrfs_search_slot(trans, root, &file_key, path, 0, cow);
218 if (ret < 0)
219 goto fail;
220 leaf = path->nodes[0];
221 if (ret > 0) {
222 ret = 1;
223 if (path->slots[0] == 0)
224 goto fail;
225 path->slots[0]--;
226 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
227 if (found_key.type != BTRFS_EXTENT_CSUM_KEY)
228 goto fail;
229
230 csum_offset = (bytenr - found_key.offset) >>
231 fs_info->sectorsize_bits;
232 csums_in_item = btrfs_item_size(leaf, path->slots[0]);
233 csums_in_item /= csum_size;
234
235 if (csum_offset == csums_in_item) {
236 ret = -EFBIG;
237 goto fail;
238 } else if (csum_offset > csums_in_item) {
239 goto fail;
240 }
241 }
242 item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
243 item = (struct btrfs_csum_item *)((unsigned char *)item +
244 csum_offset * csum_size);
245 return item;
246 fail:
247 if (ret > 0)
248 ret = -ENOENT;
249 return ERR_PTR(ret);
250 }
251
btrfs_lookup_file_extent(struct btrfs_trans_handle * trans,struct btrfs_root * root,struct btrfs_path * path,u64 objectid,u64 offset,int mod)252 int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans,
253 struct btrfs_root *root,
254 struct btrfs_path *path, u64 objectid,
255 u64 offset, int mod)
256 {
257 struct btrfs_key file_key;
258 int ins_len = mod < 0 ? -1 : 0;
259 int cow = mod != 0;
260
261 file_key.objectid = objectid;
262 file_key.type = BTRFS_EXTENT_DATA_KEY;
263 file_key.offset = offset;
264
265 return btrfs_search_slot(trans, root, &file_key, path, ins_len, cow);
266 }
267
268 /*
269 * Find checksums for logical bytenr range [disk_bytenr, disk_bytenr + len) and
270 * store the result to @dst.
271 *
272 * Return >0 for the number of sectors we found.
273 * Return 0 for the range [disk_bytenr, disk_bytenr + sectorsize) has no csum
274 * for it. Caller may want to try next sector until one range is hit.
275 * Return <0 for fatal error.
276 */
search_csum_tree(struct btrfs_fs_info * fs_info,struct btrfs_path * path,u64 disk_bytenr,u64 len,u8 * dst)277 static int search_csum_tree(struct btrfs_fs_info *fs_info,
278 struct btrfs_path *path, u64 disk_bytenr,
279 u64 len, u8 *dst)
280 {
281 struct btrfs_root *csum_root;
282 struct btrfs_csum_item *item = NULL;
283 struct btrfs_key key;
284 const u32 sectorsize = fs_info->sectorsize;
285 const u32 csum_size = fs_info->csum_size;
286 u32 itemsize;
287 int ret;
288 u64 csum_start;
289 u64 csum_len;
290
291 ASSERT(IS_ALIGNED(disk_bytenr, sectorsize) &&
292 IS_ALIGNED(len, sectorsize));
293
294 /* Check if the current csum item covers disk_bytenr */
295 if (path->nodes[0]) {
296 item = btrfs_item_ptr(path->nodes[0], path->slots[0],
297 struct btrfs_csum_item);
298 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
299 itemsize = btrfs_item_size(path->nodes[0], path->slots[0]);
300
301 csum_start = key.offset;
302 csum_len = (itemsize / csum_size) * sectorsize;
303
304 if (in_range(disk_bytenr, csum_start, csum_len))
305 goto found;
306 }
307
308 /* Current item doesn't contain the desired range, search again */
309 btrfs_release_path(path);
310 csum_root = btrfs_csum_root(fs_info, disk_bytenr);
311 item = btrfs_lookup_csum(NULL, csum_root, path, disk_bytenr, 0);
312 if (IS_ERR(item)) {
313 ret = PTR_ERR(item);
314 goto out;
315 }
316 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
317 itemsize = btrfs_item_size(path->nodes[0], path->slots[0]);
318
319 csum_start = key.offset;
320 csum_len = (itemsize / csum_size) * sectorsize;
321 ASSERT(in_range(disk_bytenr, csum_start, csum_len));
322
323 found:
324 ret = (min(csum_start + csum_len, disk_bytenr + len) -
325 disk_bytenr) >> fs_info->sectorsize_bits;
326 read_extent_buffer(path->nodes[0], dst, (unsigned long)item,
327 ret * csum_size);
328 out:
329 if (ret == -ENOENT || ret == -EFBIG)
330 ret = 0;
331 return ret;
332 }
333
334 /*
335 * Lookup the checksum for the read bio in csum tree.
336 *
337 * Return: BLK_STS_RESOURCE if allocating memory fails, BLK_STS_OK otherwise.
338 */
btrfs_lookup_bio_sums(struct btrfs_bio * bbio)339 blk_status_t btrfs_lookup_bio_sums(struct btrfs_bio *bbio)
340 {
341 struct btrfs_inode *inode = bbio->inode;
342 struct btrfs_fs_info *fs_info = inode->root->fs_info;
343 struct bio *bio = &bbio->bio;
344 BTRFS_PATH_AUTO_FREE(path);
345 const u32 sectorsize = fs_info->sectorsize;
346 const u32 csum_size = fs_info->csum_size;
347 u32 orig_len = bio->bi_iter.bi_size;
348 u64 orig_disk_bytenr = bio->bi_iter.bi_sector << SECTOR_SHIFT;
349 const unsigned int nblocks = orig_len >> fs_info->sectorsize_bits;
350 blk_status_t ret = BLK_STS_OK;
351 u32 bio_offset = 0;
352
353 if ((inode->flags & BTRFS_INODE_NODATASUM) ||
354 test_bit(BTRFS_FS_STATE_NO_DATA_CSUMS, &fs_info->fs_state))
355 return BLK_STS_OK;
356
357 /*
358 * This function is only called for read bio.
359 *
360 * This means two things:
361 * - All our csums should only be in csum tree
362 * No ordered extents csums, as ordered extents are only for write
363 * path.
364 * - No need to bother any other info from bvec
365 * Since we're looking up csums, the only important info is the
366 * disk_bytenr and the length, which can be extracted from bi_iter
367 * directly.
368 */
369 ASSERT(bio_op(bio) == REQ_OP_READ);
370 path = btrfs_alloc_path();
371 if (!path)
372 return BLK_STS_RESOURCE;
373
374 if (nblocks * csum_size > BTRFS_BIO_INLINE_CSUM_SIZE) {
375 bbio->csum = kmalloc_array(nblocks, csum_size, GFP_NOFS);
376 if (!bbio->csum)
377 return BLK_STS_RESOURCE;
378 } else {
379 bbio->csum = bbio->csum_inline;
380 }
381
382 /*
383 * If requested number of sectors is larger than one leaf can contain,
384 * kick the readahead for csum tree.
385 */
386 if (nblocks > fs_info->csums_per_leaf)
387 path->reada = READA_FORWARD;
388
389 /*
390 * the free space stuff is only read when it hasn't been
391 * updated in the current transaction. So, we can safely
392 * read from the commit root and sidestep a nasty deadlock
393 * between reading the free space cache and updating the csum tree.
394 */
395 if (btrfs_is_free_space_inode(inode)) {
396 path->search_commit_root = 1;
397 path->skip_locking = 1;
398 }
399
400 while (bio_offset < orig_len) {
401 int count;
402 u64 cur_disk_bytenr = orig_disk_bytenr + bio_offset;
403 u8 *csum_dst = bbio->csum +
404 (bio_offset >> fs_info->sectorsize_bits) * csum_size;
405
406 count = search_csum_tree(fs_info, path, cur_disk_bytenr,
407 orig_len - bio_offset, csum_dst);
408 if (count < 0) {
409 ret = errno_to_blk_status(count);
410 if (bbio->csum != bbio->csum_inline)
411 kfree(bbio->csum);
412 bbio->csum = NULL;
413 break;
414 }
415
416 /*
417 * We didn't find a csum for this range. We need to make sure
418 * we complain loudly about this, because we are not NODATASUM.
419 *
420 * However for the DATA_RELOC inode we could potentially be
421 * relocating data extents for a NODATASUM inode, so the inode
422 * itself won't be marked with NODATASUM, but the extent we're
423 * copying is in fact NODATASUM. If we don't find a csum we
424 * assume this is the case.
425 */
426 if (count == 0) {
427 memset(csum_dst, 0, csum_size);
428 count = 1;
429
430 if (btrfs_root_id(inode->root) == BTRFS_DATA_RELOC_TREE_OBJECTID) {
431 u64 file_offset = bbio->file_offset + bio_offset;
432
433 set_extent_bit(&inode->io_tree, file_offset,
434 file_offset + sectorsize - 1,
435 EXTENT_NODATASUM, NULL);
436 } else {
437 btrfs_warn_rl(fs_info,
438 "csum hole found for disk bytenr range [%llu, %llu)",
439 cur_disk_bytenr, cur_disk_bytenr + sectorsize);
440 }
441 }
442 bio_offset += count * sectorsize;
443 }
444
445 return ret;
446 }
447
448 /*
449 * Search for checksums for a given logical range.
450 *
451 * @root: The root where to look for checksums.
452 * @start: Logical address of target checksum range.
453 * @end: End offset (inclusive) of the target checksum range.
454 * @list: List for adding each checksum that was found.
455 * Can be NULL in case the caller only wants to check if
456 * there any checksums for the range.
457 * @nowait: Indicate if the search must be non-blocking or not.
458 *
459 * Return < 0 on error, 0 if no checksums were found, or 1 if checksums were
460 * found.
461 */
btrfs_lookup_csums_list(struct btrfs_root * root,u64 start,u64 end,struct list_head * list,bool nowait)462 int btrfs_lookup_csums_list(struct btrfs_root *root, u64 start, u64 end,
463 struct list_head *list, bool nowait)
464 {
465 struct btrfs_fs_info *fs_info = root->fs_info;
466 struct btrfs_key key;
467 struct btrfs_path *path;
468 struct extent_buffer *leaf;
469 struct btrfs_ordered_sum *sums;
470 struct btrfs_csum_item *item;
471 int ret;
472 bool found_csums = false;
473
474 ASSERT(IS_ALIGNED(start, fs_info->sectorsize) &&
475 IS_ALIGNED(end + 1, fs_info->sectorsize));
476
477 path = btrfs_alloc_path();
478 if (!path)
479 return -ENOMEM;
480
481 path->nowait = nowait;
482
483 key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
484 key.type = BTRFS_EXTENT_CSUM_KEY;
485 key.offset = start;
486
487 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
488 if (ret < 0)
489 goto out;
490 if (ret > 0 && path->slots[0] > 0) {
491 leaf = path->nodes[0];
492 btrfs_item_key_to_cpu(leaf, &key, path->slots[0] - 1);
493
494 /*
495 * There are two cases we can hit here for the previous csum
496 * item:
497 *
498 * |<- search range ->|
499 * |<- csum item ->|
500 *
501 * Or
502 * |<- search range ->|
503 * |<- csum item ->|
504 *
505 * Check if the previous csum item covers the leading part of
506 * the search range. If so we have to start from previous csum
507 * item.
508 */
509 if (key.objectid == BTRFS_EXTENT_CSUM_OBJECTID &&
510 key.type == BTRFS_EXTENT_CSUM_KEY) {
511 if (bytes_to_csum_size(fs_info, start - key.offset) <
512 btrfs_item_size(leaf, path->slots[0] - 1))
513 path->slots[0]--;
514 }
515 }
516
517 while (start <= end) {
518 u64 csum_end;
519
520 leaf = path->nodes[0];
521 if (path->slots[0] >= btrfs_header_nritems(leaf)) {
522 ret = btrfs_next_leaf(root, path);
523 if (ret < 0)
524 goto out;
525 if (ret > 0)
526 break;
527 leaf = path->nodes[0];
528 }
529
530 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
531 if (key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
532 key.type != BTRFS_EXTENT_CSUM_KEY ||
533 key.offset > end)
534 break;
535
536 if (key.offset > start)
537 start = key.offset;
538
539 csum_end = key.offset + csum_size_to_bytes(fs_info,
540 btrfs_item_size(leaf, path->slots[0]));
541 if (csum_end <= start) {
542 path->slots[0]++;
543 continue;
544 }
545
546 found_csums = true;
547 if (!list)
548 goto out;
549
550 csum_end = min(csum_end, end + 1);
551 item = btrfs_item_ptr(path->nodes[0], path->slots[0],
552 struct btrfs_csum_item);
553 while (start < csum_end) {
554 unsigned long offset;
555 size_t size;
556
557 size = min_t(size_t, csum_end - start,
558 max_ordered_sum_bytes(fs_info));
559 sums = kzalloc(btrfs_ordered_sum_size(fs_info, size),
560 GFP_NOFS);
561 if (!sums) {
562 ret = -ENOMEM;
563 goto out;
564 }
565
566 sums->logical = start;
567 sums->len = size;
568
569 offset = bytes_to_csum_size(fs_info, start - key.offset);
570
571 read_extent_buffer(path->nodes[0],
572 sums->sums,
573 ((unsigned long)item) + offset,
574 bytes_to_csum_size(fs_info, size));
575
576 start += size;
577 list_add_tail(&sums->list, list);
578 }
579 path->slots[0]++;
580 }
581 out:
582 btrfs_free_path(path);
583 if (ret < 0) {
584 if (list) {
585 struct btrfs_ordered_sum *tmp_sums;
586
587 list_for_each_entry_safe(sums, tmp_sums, list, list)
588 kfree(sums);
589 }
590
591 return ret;
592 }
593
594 return found_csums ? 1 : 0;
595 }
596
597 /*
598 * Do the same work as btrfs_lookup_csums_list(), the difference is in how
599 * we return the result.
600 *
601 * This version will set the corresponding bits in @csum_bitmap to represent
602 * that there is a csum found.
603 * Each bit represents a sector. Thus caller should ensure @csum_buf passed
604 * in is large enough to contain all csums.
605 */
btrfs_lookup_csums_bitmap(struct btrfs_root * root,struct btrfs_path * path,u64 start,u64 end,u8 * csum_buf,unsigned long * csum_bitmap)606 int btrfs_lookup_csums_bitmap(struct btrfs_root *root, struct btrfs_path *path,
607 u64 start, u64 end, u8 *csum_buf,
608 unsigned long *csum_bitmap)
609 {
610 struct btrfs_fs_info *fs_info = root->fs_info;
611 struct btrfs_key key;
612 struct extent_buffer *leaf;
613 struct btrfs_csum_item *item;
614 const u64 orig_start = start;
615 bool free_path = false;
616 int ret;
617
618 ASSERT(IS_ALIGNED(start, fs_info->sectorsize) &&
619 IS_ALIGNED(end + 1, fs_info->sectorsize));
620
621 if (!path) {
622 path = btrfs_alloc_path();
623 if (!path)
624 return -ENOMEM;
625 free_path = true;
626 }
627
628 /* Check if we can reuse the previous path. */
629 if (path->nodes[0]) {
630 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
631
632 if (key.objectid == BTRFS_EXTENT_CSUM_OBJECTID &&
633 key.type == BTRFS_EXTENT_CSUM_KEY &&
634 key.offset <= start)
635 goto search_forward;
636 btrfs_release_path(path);
637 }
638
639 key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
640 key.type = BTRFS_EXTENT_CSUM_KEY;
641 key.offset = start;
642
643 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
644 if (ret < 0)
645 goto fail;
646 if (ret > 0 && path->slots[0] > 0) {
647 leaf = path->nodes[0];
648 btrfs_item_key_to_cpu(leaf, &key, path->slots[0] - 1);
649
650 /*
651 * There are two cases we can hit here for the previous csum
652 * item:
653 *
654 * |<- search range ->|
655 * |<- csum item ->|
656 *
657 * Or
658 * |<- search range ->|
659 * |<- csum item ->|
660 *
661 * Check if the previous csum item covers the leading part of
662 * the search range. If so we have to start from previous csum
663 * item.
664 */
665 if (key.objectid == BTRFS_EXTENT_CSUM_OBJECTID &&
666 key.type == BTRFS_EXTENT_CSUM_KEY) {
667 if (bytes_to_csum_size(fs_info, start - key.offset) <
668 btrfs_item_size(leaf, path->slots[0] - 1))
669 path->slots[0]--;
670 }
671 }
672
673 search_forward:
674 while (start <= end) {
675 u64 csum_end;
676
677 leaf = path->nodes[0];
678 if (path->slots[0] >= btrfs_header_nritems(leaf)) {
679 ret = btrfs_next_leaf(root, path);
680 if (ret < 0)
681 goto fail;
682 if (ret > 0)
683 break;
684 leaf = path->nodes[0];
685 }
686
687 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
688 if (key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
689 key.type != BTRFS_EXTENT_CSUM_KEY ||
690 key.offset > end)
691 break;
692
693 if (key.offset > start)
694 start = key.offset;
695
696 csum_end = key.offset + csum_size_to_bytes(fs_info,
697 btrfs_item_size(leaf, path->slots[0]));
698 if (csum_end <= start) {
699 path->slots[0]++;
700 continue;
701 }
702
703 csum_end = min(csum_end, end + 1);
704 item = btrfs_item_ptr(path->nodes[0], path->slots[0],
705 struct btrfs_csum_item);
706 while (start < csum_end) {
707 unsigned long offset;
708 size_t size;
709 u8 *csum_dest = csum_buf + bytes_to_csum_size(fs_info,
710 start - orig_start);
711
712 size = min_t(size_t, csum_end - start, end + 1 - start);
713
714 offset = bytes_to_csum_size(fs_info, start - key.offset);
715
716 read_extent_buffer(path->nodes[0], csum_dest,
717 ((unsigned long)item) + offset,
718 bytes_to_csum_size(fs_info, size));
719
720 bitmap_set(csum_bitmap,
721 (start - orig_start) >> fs_info->sectorsize_bits,
722 size >> fs_info->sectorsize_bits);
723
724 start += size;
725 }
726 path->slots[0]++;
727 }
728 ret = 0;
729 fail:
730 if (free_path)
731 btrfs_free_path(path);
732 return ret;
733 }
734
735 /*
736 * Calculate checksums of the data contained inside a bio.
737 */
btrfs_csum_one_bio(struct btrfs_bio * bbio)738 blk_status_t btrfs_csum_one_bio(struct btrfs_bio *bbio)
739 {
740 struct btrfs_ordered_extent *ordered = bbio->ordered;
741 struct btrfs_inode *inode = bbio->inode;
742 struct btrfs_fs_info *fs_info = inode->root->fs_info;
743 SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
744 struct bio *bio = &bbio->bio;
745 struct btrfs_ordered_sum *sums;
746 char *data;
747 struct bvec_iter iter;
748 struct bio_vec bvec;
749 int index;
750 unsigned int blockcount;
751 int i;
752 unsigned nofs_flag;
753
754 nofs_flag = memalloc_nofs_save();
755 sums = kvzalloc(btrfs_ordered_sum_size(fs_info, bio->bi_iter.bi_size),
756 GFP_KERNEL);
757 memalloc_nofs_restore(nofs_flag);
758
759 if (!sums)
760 return BLK_STS_RESOURCE;
761
762 sums->len = bio->bi_iter.bi_size;
763 INIT_LIST_HEAD(&sums->list);
764
765 sums->logical = bio->bi_iter.bi_sector << SECTOR_SHIFT;
766 index = 0;
767
768 shash->tfm = fs_info->csum_shash;
769
770 bio_for_each_segment(bvec, bio, iter) {
771 blockcount = BTRFS_BYTES_TO_BLKS(fs_info,
772 bvec.bv_len + fs_info->sectorsize
773 - 1);
774
775 for (i = 0; i < blockcount; i++) {
776 data = bvec_kmap_local(&bvec);
777 crypto_shash_digest(shash,
778 data + (i * fs_info->sectorsize),
779 fs_info->sectorsize,
780 sums->sums + index);
781 kunmap_local(data);
782 index += fs_info->csum_size;
783 }
784
785 }
786
787 bbio->sums = sums;
788 btrfs_add_ordered_sum(ordered, sums);
789 return 0;
790 }
791
792 /*
793 * Nodatasum I/O on zoned file systems still requires an btrfs_ordered_sum to
794 * record the updated logical address on Zone Append completion.
795 * Allocate just the structure with an empty sums array here for that case.
796 */
btrfs_alloc_dummy_sum(struct btrfs_bio * bbio)797 blk_status_t btrfs_alloc_dummy_sum(struct btrfs_bio *bbio)
798 {
799 bbio->sums = kmalloc(sizeof(*bbio->sums), GFP_NOFS);
800 if (!bbio->sums)
801 return BLK_STS_RESOURCE;
802 bbio->sums->len = bbio->bio.bi_iter.bi_size;
803 bbio->sums->logical = bbio->bio.bi_iter.bi_sector << SECTOR_SHIFT;
804 btrfs_add_ordered_sum(bbio->ordered, bbio->sums);
805 return 0;
806 }
807
808 /*
809 * Remove one checksum overlapping a range.
810 *
811 * This expects the key to describe the csum pointed to by the path, and it
812 * expects the csum to overlap the range [bytenr, len]
813 *
814 * The csum should not be entirely contained in the range and the range should
815 * not be entirely contained in the csum.
816 *
817 * This calls btrfs_truncate_item with the correct args based on the overlap,
818 * and fixes up the key as required.
819 */
truncate_one_csum(struct btrfs_trans_handle * trans,struct btrfs_path * path,struct btrfs_key * key,u64 bytenr,u64 len)820 static noinline void truncate_one_csum(struct btrfs_trans_handle *trans,
821 struct btrfs_path *path,
822 struct btrfs_key *key,
823 u64 bytenr, u64 len)
824 {
825 struct btrfs_fs_info *fs_info = trans->fs_info;
826 struct extent_buffer *leaf;
827 const u32 csum_size = fs_info->csum_size;
828 u64 csum_end;
829 u64 end_byte = bytenr + len;
830 u32 blocksize_bits = fs_info->sectorsize_bits;
831
832 leaf = path->nodes[0];
833 csum_end = btrfs_item_size(leaf, path->slots[0]) / csum_size;
834 csum_end <<= blocksize_bits;
835 csum_end += key->offset;
836
837 if (key->offset < bytenr && csum_end <= end_byte) {
838 /*
839 * [ bytenr - len ]
840 * [ ]
841 * [csum ]
842 * A simple truncate off the end of the item
843 */
844 u32 new_size = (bytenr - key->offset) >> blocksize_bits;
845 new_size *= csum_size;
846 btrfs_truncate_item(trans, path, new_size, 1);
847 } else if (key->offset >= bytenr && csum_end > end_byte &&
848 end_byte > key->offset) {
849 /*
850 * [ bytenr - len ]
851 * [ ]
852 * [csum ]
853 * we need to truncate from the beginning of the csum
854 */
855 u32 new_size = (csum_end - end_byte) >> blocksize_bits;
856 new_size *= csum_size;
857
858 btrfs_truncate_item(trans, path, new_size, 0);
859
860 key->offset = end_byte;
861 btrfs_set_item_key_safe(trans, path, key);
862 } else {
863 BUG();
864 }
865 }
866
867 /*
868 * Delete the csum items from the csum tree for a given range of bytes.
869 */
btrfs_del_csums(struct btrfs_trans_handle * trans,struct btrfs_root * root,u64 bytenr,u64 len)870 int btrfs_del_csums(struct btrfs_trans_handle *trans,
871 struct btrfs_root *root, u64 bytenr, u64 len)
872 {
873 struct btrfs_fs_info *fs_info = trans->fs_info;
874 BTRFS_PATH_AUTO_FREE(path);
875 struct btrfs_key key;
876 u64 end_byte = bytenr + len;
877 u64 csum_end;
878 struct extent_buffer *leaf;
879 int ret = 0;
880 const u32 csum_size = fs_info->csum_size;
881 u32 blocksize_bits = fs_info->sectorsize_bits;
882
883 ASSERT(btrfs_root_id(root) == BTRFS_CSUM_TREE_OBJECTID ||
884 btrfs_root_id(root) == BTRFS_TREE_LOG_OBJECTID);
885
886 path = btrfs_alloc_path();
887 if (!path)
888 return -ENOMEM;
889
890 while (1) {
891 key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
892 key.type = BTRFS_EXTENT_CSUM_KEY;
893 key.offset = end_byte - 1;
894
895 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
896 if (ret > 0) {
897 ret = 0;
898 if (path->slots[0] == 0)
899 break;
900 path->slots[0]--;
901 } else if (ret < 0) {
902 break;
903 }
904
905 leaf = path->nodes[0];
906 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
907
908 if (key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
909 key.type != BTRFS_EXTENT_CSUM_KEY) {
910 break;
911 }
912
913 if (key.offset >= end_byte)
914 break;
915
916 csum_end = btrfs_item_size(leaf, path->slots[0]) / csum_size;
917 csum_end <<= blocksize_bits;
918 csum_end += key.offset;
919
920 /* this csum ends before we start, we're done */
921 if (csum_end <= bytenr)
922 break;
923
924 /* delete the entire item, it is inside our range */
925 if (key.offset >= bytenr && csum_end <= end_byte) {
926 int del_nr = 1;
927
928 /*
929 * Check how many csum items preceding this one in this
930 * leaf correspond to our range and then delete them all
931 * at once.
932 */
933 if (key.offset > bytenr && path->slots[0] > 0) {
934 int slot = path->slots[0] - 1;
935
936 while (slot >= 0) {
937 struct btrfs_key pk;
938
939 btrfs_item_key_to_cpu(leaf, &pk, slot);
940 if (pk.offset < bytenr ||
941 pk.type != BTRFS_EXTENT_CSUM_KEY ||
942 pk.objectid !=
943 BTRFS_EXTENT_CSUM_OBJECTID)
944 break;
945 path->slots[0] = slot;
946 del_nr++;
947 key.offset = pk.offset;
948 slot--;
949 }
950 }
951 ret = btrfs_del_items(trans, root, path,
952 path->slots[0], del_nr);
953 if (ret)
954 break;
955 if (key.offset == bytenr)
956 break;
957 } else if (key.offset < bytenr && csum_end > end_byte) {
958 unsigned long offset;
959 unsigned long shift_len;
960 unsigned long item_offset;
961 /*
962 * [ bytenr - len ]
963 * [csum ]
964 *
965 * Our bytes are in the middle of the csum,
966 * we need to split this item and insert a new one.
967 *
968 * But we can't drop the path because the
969 * csum could change, get removed, extended etc.
970 *
971 * The trick here is the max size of a csum item leaves
972 * enough room in the tree block for a single
973 * item header. So, we split the item in place,
974 * adding a new header pointing to the existing
975 * bytes. Then we loop around again and we have
976 * a nicely formed csum item that we can neatly
977 * truncate.
978 */
979 offset = (bytenr - key.offset) >> blocksize_bits;
980 offset *= csum_size;
981
982 shift_len = (len >> blocksize_bits) * csum_size;
983
984 item_offset = btrfs_item_ptr_offset(leaf,
985 path->slots[0]);
986
987 memzero_extent_buffer(leaf, item_offset + offset,
988 shift_len);
989 key.offset = bytenr;
990
991 /*
992 * btrfs_split_item returns -EAGAIN when the
993 * item changed size or key
994 */
995 ret = btrfs_split_item(trans, root, path, &key, offset);
996 if (ret && ret != -EAGAIN) {
997 btrfs_abort_transaction(trans, ret);
998 break;
999 }
1000 ret = 0;
1001
1002 key.offset = end_byte - 1;
1003 } else {
1004 truncate_one_csum(trans, path, &key, bytenr, len);
1005 if (key.offset < bytenr)
1006 break;
1007 }
1008 btrfs_release_path(path);
1009 }
1010 return ret;
1011 }
1012
find_next_csum_offset(struct btrfs_root * root,struct btrfs_path * path,u64 * next_offset)1013 static int find_next_csum_offset(struct btrfs_root *root,
1014 struct btrfs_path *path,
1015 u64 *next_offset)
1016 {
1017 const u32 nritems = btrfs_header_nritems(path->nodes[0]);
1018 struct btrfs_key found_key;
1019 int slot = path->slots[0] + 1;
1020 int ret;
1021
1022 if (nritems == 0 || slot >= nritems) {
1023 ret = btrfs_next_leaf(root, path);
1024 if (ret < 0) {
1025 return ret;
1026 } else if (ret > 0) {
1027 *next_offset = (u64)-1;
1028 return 0;
1029 }
1030 slot = path->slots[0];
1031 }
1032
1033 btrfs_item_key_to_cpu(path->nodes[0], &found_key, slot);
1034
1035 if (found_key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
1036 found_key.type != BTRFS_EXTENT_CSUM_KEY)
1037 *next_offset = (u64)-1;
1038 else
1039 *next_offset = found_key.offset;
1040
1041 return 0;
1042 }
1043
btrfs_csum_file_blocks(struct btrfs_trans_handle * trans,struct btrfs_root * root,struct btrfs_ordered_sum * sums)1044 int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
1045 struct btrfs_root *root,
1046 struct btrfs_ordered_sum *sums)
1047 {
1048 struct btrfs_fs_info *fs_info = root->fs_info;
1049 struct btrfs_key file_key;
1050 struct btrfs_key found_key;
1051 struct btrfs_path *path;
1052 struct btrfs_csum_item *item;
1053 struct btrfs_csum_item *item_end;
1054 struct extent_buffer *leaf = NULL;
1055 u64 next_offset;
1056 u64 total_bytes = 0;
1057 u64 csum_offset;
1058 u64 bytenr;
1059 u32 ins_size;
1060 int index = 0;
1061 int found_next;
1062 int ret;
1063 const u32 csum_size = fs_info->csum_size;
1064
1065 path = btrfs_alloc_path();
1066 if (!path)
1067 return -ENOMEM;
1068 again:
1069 next_offset = (u64)-1;
1070 found_next = 0;
1071 bytenr = sums->logical + total_bytes;
1072 file_key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
1073 file_key.type = BTRFS_EXTENT_CSUM_KEY;
1074 file_key.offset = bytenr;
1075
1076 item = btrfs_lookup_csum(trans, root, path, bytenr, 1);
1077 if (!IS_ERR(item)) {
1078 ret = 0;
1079 leaf = path->nodes[0];
1080 item_end = btrfs_item_ptr(leaf, path->slots[0],
1081 struct btrfs_csum_item);
1082 item_end = (struct btrfs_csum_item *)((char *)item_end +
1083 btrfs_item_size(leaf, path->slots[0]));
1084 goto found;
1085 }
1086 ret = PTR_ERR(item);
1087 if (ret != -EFBIG && ret != -ENOENT)
1088 goto out;
1089
1090 if (ret == -EFBIG) {
1091 u32 item_size;
1092 /* we found one, but it isn't big enough yet */
1093 leaf = path->nodes[0];
1094 item_size = btrfs_item_size(leaf, path->slots[0]);
1095 if ((item_size / csum_size) >=
1096 MAX_CSUM_ITEMS(fs_info, csum_size)) {
1097 /* already at max size, make a new one */
1098 goto insert;
1099 }
1100 } else {
1101 /* We didn't find a csum item, insert one. */
1102 ret = find_next_csum_offset(root, path, &next_offset);
1103 if (ret < 0)
1104 goto out;
1105 found_next = 1;
1106 goto insert;
1107 }
1108
1109 /*
1110 * At this point, we know the tree has a checksum item that ends at an
1111 * offset matching the start of the checksum range we want to insert.
1112 * We try to extend that item as much as possible and then add as many
1113 * checksums to it as they fit.
1114 *
1115 * First check if the leaf has enough free space for at least one
1116 * checksum. If it has go directly to the item extension code, otherwise
1117 * release the path and do a search for insertion before the extension.
1118 */
1119 if (btrfs_leaf_free_space(leaf) >= csum_size) {
1120 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
1121 csum_offset = (bytenr - found_key.offset) >>
1122 fs_info->sectorsize_bits;
1123 goto extend_csum;
1124 }
1125
1126 btrfs_release_path(path);
1127 path->search_for_extension = 1;
1128 ret = btrfs_search_slot(trans, root, &file_key, path,
1129 csum_size, 1);
1130 path->search_for_extension = 0;
1131 if (ret < 0)
1132 goto out;
1133
1134 if (ret > 0) {
1135 if (path->slots[0] == 0)
1136 goto insert;
1137 path->slots[0]--;
1138 }
1139
1140 leaf = path->nodes[0];
1141 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
1142 csum_offset = (bytenr - found_key.offset) >> fs_info->sectorsize_bits;
1143
1144 if (found_key.type != BTRFS_EXTENT_CSUM_KEY ||
1145 found_key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
1146 csum_offset >= MAX_CSUM_ITEMS(fs_info, csum_size)) {
1147 goto insert;
1148 }
1149
1150 extend_csum:
1151 if (csum_offset == btrfs_item_size(leaf, path->slots[0]) /
1152 csum_size) {
1153 int extend_nr;
1154 u64 tmp;
1155 u32 diff;
1156
1157 tmp = sums->len - total_bytes;
1158 tmp >>= fs_info->sectorsize_bits;
1159 WARN_ON(tmp < 1);
1160 extend_nr = max_t(int, 1, tmp);
1161
1162 /*
1163 * A log tree can already have checksum items with a subset of
1164 * the checksums we are trying to log. This can happen after
1165 * doing a sequence of partial writes into prealloc extents and
1166 * fsyncs in between, with a full fsync logging a larger subrange
1167 * of an extent for which a previous fast fsync logged a smaller
1168 * subrange. And this happens in particular due to merging file
1169 * extent items when we complete an ordered extent for a range
1170 * covered by a prealloc extent - this is done at
1171 * btrfs_mark_extent_written().
1172 *
1173 * So if we try to extend the previous checksum item, which has
1174 * a range that ends at the start of the range we want to insert,
1175 * make sure we don't extend beyond the start offset of the next
1176 * checksum item. If we are at the last item in the leaf, then
1177 * forget the optimization of extending and add a new checksum
1178 * item - it is not worth the complexity of releasing the path,
1179 * getting the first key for the next leaf, repeat the btree
1180 * search, etc, because log trees are temporary anyway and it
1181 * would only save a few bytes of leaf space.
1182 */
1183 if (btrfs_root_id(root) == BTRFS_TREE_LOG_OBJECTID) {
1184 if (path->slots[0] + 1 >=
1185 btrfs_header_nritems(path->nodes[0])) {
1186 ret = find_next_csum_offset(root, path, &next_offset);
1187 if (ret < 0)
1188 goto out;
1189 found_next = 1;
1190 goto insert;
1191 }
1192
1193 ret = find_next_csum_offset(root, path, &next_offset);
1194 if (ret < 0)
1195 goto out;
1196
1197 tmp = (next_offset - bytenr) >> fs_info->sectorsize_bits;
1198 if (tmp <= INT_MAX)
1199 extend_nr = min_t(int, extend_nr, tmp);
1200 }
1201
1202 diff = (csum_offset + extend_nr) * csum_size;
1203 diff = min(diff,
1204 MAX_CSUM_ITEMS(fs_info, csum_size) * csum_size);
1205
1206 diff = diff - btrfs_item_size(leaf, path->slots[0]);
1207 diff = min_t(u32, btrfs_leaf_free_space(leaf), diff);
1208 diff /= csum_size;
1209 diff *= csum_size;
1210
1211 btrfs_extend_item(trans, path, diff);
1212 ret = 0;
1213 goto csum;
1214 }
1215
1216 insert:
1217 btrfs_release_path(path);
1218 csum_offset = 0;
1219 if (found_next) {
1220 u64 tmp;
1221
1222 tmp = sums->len - total_bytes;
1223 tmp >>= fs_info->sectorsize_bits;
1224 tmp = min(tmp, (next_offset - file_key.offset) >>
1225 fs_info->sectorsize_bits);
1226
1227 tmp = max_t(u64, 1, tmp);
1228 tmp = min_t(u64, tmp, MAX_CSUM_ITEMS(fs_info, csum_size));
1229 ins_size = csum_size * tmp;
1230 } else {
1231 ins_size = csum_size;
1232 }
1233 ret = btrfs_insert_empty_item(trans, root, path, &file_key,
1234 ins_size);
1235 if (ret < 0)
1236 goto out;
1237 leaf = path->nodes[0];
1238 csum:
1239 item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
1240 item_end = (struct btrfs_csum_item *)((unsigned char *)item +
1241 btrfs_item_size(leaf, path->slots[0]));
1242 item = (struct btrfs_csum_item *)((unsigned char *)item +
1243 csum_offset * csum_size);
1244 found:
1245 ins_size = (u32)(sums->len - total_bytes) >> fs_info->sectorsize_bits;
1246 ins_size *= csum_size;
1247 ins_size = min_t(u32, (unsigned long)item_end - (unsigned long)item,
1248 ins_size);
1249 write_extent_buffer(leaf, sums->sums + index, (unsigned long)item,
1250 ins_size);
1251
1252 index += ins_size;
1253 ins_size /= csum_size;
1254 total_bytes += ins_size * fs_info->sectorsize;
1255
1256 if (total_bytes < sums->len) {
1257 btrfs_release_path(path);
1258 cond_resched();
1259 goto again;
1260 }
1261 out:
1262 btrfs_free_path(path);
1263 return ret;
1264 }
1265
btrfs_extent_item_to_extent_map(struct btrfs_inode * inode,const struct btrfs_path * path,const struct btrfs_file_extent_item * fi,struct extent_map * em)1266 void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
1267 const struct btrfs_path *path,
1268 const struct btrfs_file_extent_item *fi,
1269 struct extent_map *em)
1270 {
1271 struct btrfs_fs_info *fs_info = inode->root->fs_info;
1272 struct btrfs_root *root = inode->root;
1273 struct extent_buffer *leaf = path->nodes[0];
1274 const int slot = path->slots[0];
1275 struct btrfs_key key;
1276 u64 extent_start;
1277 u8 type = btrfs_file_extent_type(leaf, fi);
1278 int compress_type = btrfs_file_extent_compression(leaf, fi);
1279
1280 btrfs_item_key_to_cpu(leaf, &key, slot);
1281 extent_start = key.offset;
1282 em->ram_bytes = btrfs_file_extent_ram_bytes(leaf, fi);
1283 em->generation = btrfs_file_extent_generation(leaf, fi);
1284 if (type == BTRFS_FILE_EXTENT_REG ||
1285 type == BTRFS_FILE_EXTENT_PREALLOC) {
1286 const u64 disk_bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
1287
1288 em->start = extent_start;
1289 em->len = btrfs_file_extent_end(path) - extent_start;
1290 if (disk_bytenr == 0) {
1291 em->disk_bytenr = EXTENT_MAP_HOLE;
1292 em->disk_num_bytes = 0;
1293 em->offset = 0;
1294 return;
1295 }
1296 em->disk_bytenr = disk_bytenr;
1297 em->disk_num_bytes = btrfs_file_extent_disk_num_bytes(leaf, fi);
1298 em->offset = btrfs_file_extent_offset(leaf, fi);
1299 if (compress_type != BTRFS_COMPRESS_NONE) {
1300 extent_map_set_compression(em, compress_type);
1301 } else {
1302 /*
1303 * Older kernels can create regular non-hole data
1304 * extents with ram_bytes smaller than disk_num_bytes.
1305 * Not a big deal, just always use disk_num_bytes
1306 * for ram_bytes.
1307 */
1308 em->ram_bytes = em->disk_num_bytes;
1309 if (type == BTRFS_FILE_EXTENT_PREALLOC)
1310 em->flags |= EXTENT_FLAG_PREALLOC;
1311 }
1312 } else if (type == BTRFS_FILE_EXTENT_INLINE) {
1313 /* Tree-checker has ensured this. */
1314 ASSERT(extent_start == 0);
1315
1316 em->disk_bytenr = EXTENT_MAP_INLINE;
1317 em->start = 0;
1318 em->len = fs_info->sectorsize;
1319 em->offset = 0;
1320 extent_map_set_compression(em, compress_type);
1321 } else {
1322 btrfs_err(fs_info,
1323 "unknown file extent item type %d, inode %llu, offset %llu, "
1324 "root %llu", type, btrfs_ino(inode), extent_start,
1325 btrfs_root_id(root));
1326 }
1327 }
1328
1329 /*
1330 * Returns the end offset (non inclusive) of the file extent item the given path
1331 * points to. If it points to an inline extent, the returned offset is rounded
1332 * up to the sector size.
1333 */
btrfs_file_extent_end(const struct btrfs_path * path)1334 u64 btrfs_file_extent_end(const struct btrfs_path *path)
1335 {
1336 const struct extent_buffer *leaf = path->nodes[0];
1337 const int slot = path->slots[0];
1338 struct btrfs_file_extent_item *fi;
1339 struct btrfs_key key;
1340 u64 end;
1341
1342 btrfs_item_key_to_cpu(leaf, &key, slot);
1343 ASSERT(key.type == BTRFS_EXTENT_DATA_KEY);
1344 fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
1345
1346 if (btrfs_file_extent_type(leaf, fi) == BTRFS_FILE_EXTENT_INLINE)
1347 end = leaf->fs_info->sectorsize;
1348 else
1349 end = key.offset + btrfs_file_extent_num_bytes(leaf, fi);
1350
1351 return end;
1352 }
1353