1
2
3
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 "ctree.h"
13#include "disk-io.h"
14#include "transaction.h"
15#include "volumes.h"
16#include "print-tree.h"
17#include "compression.h"
18
19#define __MAX_CSUM_ITEMS(r, size) ((unsigned long)(((BTRFS_LEAF_DATA_SIZE(r) - \
20 sizeof(struct btrfs_item) * 2) / \
21 size) - 1))
22
23#define MAX_CSUM_ITEMS(r, size) (min_t(u32, __MAX_CSUM_ITEMS(r, size), \
24 PAGE_SIZE))
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43void btrfs_inode_safe_disk_i_size_write(struct btrfs_inode *inode, u64 new_i_size)
44{
45 struct btrfs_fs_info *fs_info = inode->root->fs_info;
46 u64 start, end, i_size;
47 int ret;
48
49 i_size = new_i_size ?: i_size_read(&inode->vfs_inode);
50 if (btrfs_fs_incompat(fs_info, NO_HOLES)) {
51 inode->disk_i_size = i_size;
52 return;
53 }
54
55 spin_lock(&inode->lock);
56 ret = find_contiguous_extent_bit(&inode->file_extent_tree, 0, &start,
57 &end, EXTENT_DIRTY);
58 if (!ret && start == 0)
59 i_size = min(i_size, end + 1);
60 else
61 i_size = 0;
62 inode->disk_i_size = i_size;
63 spin_unlock(&inode->lock);
64}
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80int btrfs_inode_set_file_extent_range(struct btrfs_inode *inode, u64 start,
81 u64 len)
82{
83 if (len == 0)
84 return 0;
85
86 ASSERT(IS_ALIGNED(start + len, inode->root->fs_info->sectorsize));
87
88 if (btrfs_fs_incompat(inode->root->fs_info, NO_HOLES))
89 return 0;
90 return set_extent_bits(&inode->file_extent_tree, start, start + len - 1,
91 EXTENT_DIRTY);
92}
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108int btrfs_inode_clear_file_extent_range(struct btrfs_inode *inode, u64 start,
109 u64 len)
110{
111 if (len == 0)
112 return 0;
113
114 ASSERT(IS_ALIGNED(start + len, inode->root->fs_info->sectorsize) ||
115 len == (u64)-1);
116
117 if (btrfs_fs_incompat(inode->root->fs_info, NO_HOLES))
118 return 0;
119 return clear_extent_bit(&inode->file_extent_tree, start,
120 start + len - 1, EXTENT_DIRTY, 0, 0, NULL);
121}
122
123static inline u32 max_ordered_sum_bytes(struct btrfs_fs_info *fs_info,
124 u16 csum_size)
125{
126 u32 ncsums = (PAGE_SIZE - sizeof(struct btrfs_ordered_sum)) / csum_size;
127
128 return ncsums * fs_info->sectorsize;
129}
130
131int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
132 struct btrfs_root *root,
133 u64 objectid, u64 pos,
134 u64 disk_offset, u64 disk_num_bytes,
135 u64 num_bytes, u64 offset, u64 ram_bytes,
136 u8 compression, u8 encryption, u16 other_encoding)
137{
138 int ret = 0;
139 struct btrfs_file_extent_item *item;
140 struct btrfs_key file_key;
141 struct btrfs_path *path;
142 struct extent_buffer *leaf;
143
144 path = btrfs_alloc_path();
145 if (!path)
146 return -ENOMEM;
147 file_key.objectid = objectid;
148 file_key.offset = pos;
149 file_key.type = BTRFS_EXTENT_DATA_KEY;
150
151 ret = btrfs_insert_empty_item(trans, root, path, &file_key,
152 sizeof(*item));
153 if (ret < 0)
154 goto out;
155 BUG_ON(ret);
156 leaf = path->nodes[0];
157 item = btrfs_item_ptr(leaf, path->slots[0],
158 struct btrfs_file_extent_item);
159 btrfs_set_file_extent_disk_bytenr(leaf, item, disk_offset);
160 btrfs_set_file_extent_disk_num_bytes(leaf, item, disk_num_bytes);
161 btrfs_set_file_extent_offset(leaf, item, offset);
162 btrfs_set_file_extent_num_bytes(leaf, item, num_bytes);
163 btrfs_set_file_extent_ram_bytes(leaf, item, ram_bytes);
164 btrfs_set_file_extent_generation(leaf, item, trans->transid);
165 btrfs_set_file_extent_type(leaf, item, BTRFS_FILE_EXTENT_REG);
166 btrfs_set_file_extent_compression(leaf, item, compression);
167 btrfs_set_file_extent_encryption(leaf, item, encryption);
168 btrfs_set_file_extent_other_encoding(leaf, item, other_encoding);
169
170 btrfs_mark_buffer_dirty(leaf);
171out:
172 btrfs_free_path(path);
173 return ret;
174}
175
176static struct btrfs_csum_item *
177btrfs_lookup_csum(struct btrfs_trans_handle *trans,
178 struct btrfs_root *root,
179 struct btrfs_path *path,
180 u64 bytenr, int cow)
181{
182 struct btrfs_fs_info *fs_info = root->fs_info;
183 int ret;
184 struct btrfs_key file_key;
185 struct btrfs_key found_key;
186 struct btrfs_csum_item *item;
187 struct extent_buffer *leaf;
188 u64 csum_offset = 0;
189 const u32 csum_size = fs_info->csum_size;
190 int csums_in_item;
191
192 file_key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
193 file_key.offset = bytenr;
194 file_key.type = BTRFS_EXTENT_CSUM_KEY;
195 ret = btrfs_search_slot(trans, root, &file_key, path, 0, cow);
196 if (ret < 0)
197 goto fail;
198 leaf = path->nodes[0];
199 if (ret > 0) {
200 ret = 1;
201 if (path->slots[0] == 0)
202 goto fail;
203 path->slots[0]--;
204 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
205 if (found_key.type != BTRFS_EXTENT_CSUM_KEY)
206 goto fail;
207
208 csum_offset = (bytenr - found_key.offset) >>
209 fs_info->sectorsize_bits;
210 csums_in_item = btrfs_item_size_nr(leaf, path->slots[0]);
211 csums_in_item /= csum_size;
212
213 if (csum_offset == csums_in_item) {
214 ret = -EFBIG;
215 goto fail;
216 } else if (csum_offset > csums_in_item) {
217 goto fail;
218 }
219 }
220 item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
221 item = (struct btrfs_csum_item *)((unsigned char *)item +
222 csum_offset * csum_size);
223 return item;
224fail:
225 if (ret > 0)
226 ret = -ENOENT;
227 return ERR_PTR(ret);
228}
229
230int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans,
231 struct btrfs_root *root,
232 struct btrfs_path *path, u64 objectid,
233 u64 offset, int mod)
234{
235 int ret;
236 struct btrfs_key file_key;
237 int ins_len = mod < 0 ? -1 : 0;
238 int cow = mod != 0;
239
240 file_key.objectid = objectid;
241 file_key.offset = offset;
242 file_key.type = BTRFS_EXTENT_DATA_KEY;
243 ret = btrfs_search_slot(trans, root, &file_key, path, ins_len, cow);
244 return ret;
245}
246
247
248
249
250
251
252
253
254
255
256static int search_csum_tree(struct btrfs_fs_info *fs_info,
257 struct btrfs_path *path, u64 disk_bytenr,
258 u64 len, u8 *dst)
259{
260 struct btrfs_csum_item *item = NULL;
261 struct btrfs_key key;
262 const u32 sectorsize = fs_info->sectorsize;
263 const u32 csum_size = fs_info->csum_size;
264 u32 itemsize;
265 int ret;
266 u64 csum_start;
267 u64 csum_len;
268
269 ASSERT(IS_ALIGNED(disk_bytenr, sectorsize) &&
270 IS_ALIGNED(len, sectorsize));
271
272
273 if (path->nodes[0]) {
274 item = btrfs_item_ptr(path->nodes[0], path->slots[0],
275 struct btrfs_csum_item);
276 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
277 itemsize = btrfs_item_size_nr(path->nodes[0], path->slots[0]);
278
279 csum_start = key.offset;
280 csum_len = (itemsize / csum_size) * sectorsize;
281
282 if (in_range(disk_bytenr, csum_start, csum_len))
283 goto found;
284 }
285
286
287 btrfs_release_path(path);
288 item = btrfs_lookup_csum(NULL, fs_info->csum_root, path, disk_bytenr, 0);
289 if (IS_ERR(item)) {
290 ret = PTR_ERR(item);
291 goto out;
292 }
293 btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
294 itemsize = btrfs_item_size_nr(path->nodes[0], path->slots[0]);
295
296 csum_start = key.offset;
297 csum_len = (itemsize / csum_size) * sectorsize;
298 ASSERT(in_range(disk_bytenr, csum_start, csum_len));
299
300found:
301 ret = (min(csum_start + csum_len, disk_bytenr + len) -
302 disk_bytenr) >> fs_info->sectorsize_bits;
303 read_extent_buffer(path->nodes[0], dst, (unsigned long)item,
304 ret * csum_size);
305out:
306 if (ret == -ENOENT)
307 ret = 0;
308 return ret;
309}
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324static int search_file_offset_in_bio(struct bio *bio, struct inode *inode,
325 u64 disk_bytenr, u64 *file_offset_ret)
326{
327 struct bvec_iter iter;
328 struct bio_vec bvec;
329 u64 cur = bio->bi_iter.bi_sector << SECTOR_SHIFT;
330 int ret = 0;
331
332 bio_for_each_segment(bvec, bio, iter) {
333 struct page *page = bvec.bv_page;
334
335 if (cur > disk_bytenr)
336 break;
337 if (cur + bvec.bv_len <= disk_bytenr) {
338 cur += bvec.bv_len;
339 continue;
340 }
341 ASSERT(in_range(disk_bytenr, cur, bvec.bv_len));
342 if (page->mapping && page->mapping->host &&
343 page->mapping->host == inode) {
344 ret = 1;
345 *file_offset_ret = page_offset(page) + bvec.bv_offset +
346 disk_bytenr - cur;
347 break;
348 }
349 }
350 return ret;
351}
352
353
354
355
356
357
358
359
360
361
362
363
364
365blk_status_t btrfs_lookup_bio_sums(struct inode *inode, struct bio *bio, u8 *dst)
366{
367 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
368 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
369 struct btrfs_path *path;
370 const u32 sectorsize = fs_info->sectorsize;
371 const u32 csum_size = fs_info->csum_size;
372 u32 orig_len = bio->bi_iter.bi_size;
373 u64 orig_disk_bytenr = bio->bi_iter.bi_sector << SECTOR_SHIFT;
374 u64 cur_disk_bytenr;
375 u8 *csum;
376 const unsigned int nblocks = orig_len >> fs_info->sectorsize_bits;
377 int count = 0;
378
379 if (!fs_info->csum_root || (BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM))
380 return BLK_STS_OK;
381
382
383
384
385
386
387
388
389
390
391
392
393
394 ASSERT(bio_op(bio) == REQ_OP_READ);
395 path = btrfs_alloc_path();
396 if (!path)
397 return BLK_STS_RESOURCE;
398
399 if (!dst) {
400 struct btrfs_io_bio *btrfs_bio = btrfs_io_bio(bio);
401
402 if (nblocks * csum_size > BTRFS_BIO_INLINE_CSUM_SIZE) {
403 btrfs_bio->csum = kmalloc_array(nblocks, csum_size,
404 GFP_NOFS);
405 if (!btrfs_bio->csum) {
406 btrfs_free_path(path);
407 return BLK_STS_RESOURCE;
408 }
409 } else {
410 btrfs_bio->csum = btrfs_bio->csum_inline;
411 }
412 csum = btrfs_bio->csum;
413 } else {
414 csum = dst;
415 }
416
417
418
419
420
421 if (nblocks > fs_info->csums_per_leaf)
422 path->reada = READA_FORWARD;
423
424
425
426
427
428
429
430 if (btrfs_is_free_space_inode(BTRFS_I(inode))) {
431 path->search_commit_root = 1;
432 path->skip_locking = 1;
433 }
434
435 for (cur_disk_bytenr = orig_disk_bytenr;
436 cur_disk_bytenr < orig_disk_bytenr + orig_len;
437 cur_disk_bytenr += (count * sectorsize)) {
438 u64 search_len = orig_disk_bytenr + orig_len - cur_disk_bytenr;
439 unsigned int sector_offset;
440 u8 *csum_dst;
441
442
443
444
445
446
447
448
449
450 ASSERT(cur_disk_bytenr - orig_disk_bytenr < UINT_MAX);
451 sector_offset = (cur_disk_bytenr - orig_disk_bytenr) >>
452 fs_info->sectorsize_bits;
453 csum_dst = csum + sector_offset * csum_size;
454
455 count = search_csum_tree(fs_info, path, cur_disk_bytenr,
456 search_len, csum_dst);
457 if (count <= 0) {
458
459
460
461
462
463
464 memset(csum_dst, 0, csum_size);
465 count = 1;
466
467
468
469
470
471
472 if (BTRFS_I(inode)->root->root_key.objectid ==
473 BTRFS_DATA_RELOC_TREE_OBJECTID) {
474 u64 file_offset;
475 int ret;
476
477 ret = search_file_offset_in_bio(bio, inode,
478 cur_disk_bytenr, &file_offset);
479 if (ret)
480 set_extent_bits(io_tree, file_offset,
481 file_offset + sectorsize - 1,
482 EXTENT_NODATASUM);
483 } else {
484 btrfs_warn_rl(fs_info,
485 "csum hole found for disk bytenr range [%llu, %llu)",
486 cur_disk_bytenr, cur_disk_bytenr + sectorsize);
487 }
488 }
489 }
490
491 btrfs_free_path(path);
492 return BLK_STS_OK;
493}
494
495int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
496 struct list_head *list, int search_commit)
497{
498 struct btrfs_fs_info *fs_info = root->fs_info;
499 struct btrfs_key key;
500 struct btrfs_path *path;
501 struct extent_buffer *leaf;
502 struct btrfs_ordered_sum *sums;
503 struct btrfs_csum_item *item;
504 LIST_HEAD(tmplist);
505 unsigned long offset;
506 int ret;
507 size_t size;
508 u64 csum_end;
509 const u32 csum_size = fs_info->csum_size;
510
511 ASSERT(IS_ALIGNED(start, fs_info->sectorsize) &&
512 IS_ALIGNED(end + 1, fs_info->sectorsize));
513
514 path = btrfs_alloc_path();
515 if (!path)
516 return -ENOMEM;
517
518 if (search_commit) {
519 path->skip_locking = 1;
520 path->reada = READA_FORWARD;
521 path->search_commit_root = 1;
522 }
523
524 key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
525 key.offset = start;
526 key.type = BTRFS_EXTENT_CSUM_KEY;
527
528 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
529 if (ret < 0)
530 goto fail;
531 if (ret > 0 && path->slots[0] > 0) {
532 leaf = path->nodes[0];
533 btrfs_item_key_to_cpu(leaf, &key, path->slots[0] - 1);
534 if (key.objectid == BTRFS_EXTENT_CSUM_OBJECTID &&
535 key.type == BTRFS_EXTENT_CSUM_KEY) {
536 offset = (start - key.offset) >> fs_info->sectorsize_bits;
537 if (offset * csum_size <
538 btrfs_item_size_nr(leaf, path->slots[0] - 1))
539 path->slots[0]--;
540 }
541 }
542
543 while (start <= end) {
544 leaf = path->nodes[0];
545 if (path->slots[0] >= btrfs_header_nritems(leaf)) {
546 ret = btrfs_next_leaf(root, path);
547 if (ret < 0)
548 goto fail;
549 if (ret > 0)
550 break;
551 leaf = path->nodes[0];
552 }
553
554 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
555 if (key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
556 key.type != BTRFS_EXTENT_CSUM_KEY ||
557 key.offset > end)
558 break;
559
560 if (key.offset > start)
561 start = key.offset;
562
563 size = btrfs_item_size_nr(leaf, path->slots[0]);
564 csum_end = key.offset + (size / csum_size) * fs_info->sectorsize;
565 if (csum_end <= start) {
566 path->slots[0]++;
567 continue;
568 }
569
570 csum_end = min(csum_end, end + 1);
571 item = btrfs_item_ptr(path->nodes[0], path->slots[0],
572 struct btrfs_csum_item);
573 while (start < csum_end) {
574 size = min_t(size_t, csum_end - start,
575 max_ordered_sum_bytes(fs_info, csum_size));
576 sums = kzalloc(btrfs_ordered_sum_size(fs_info, size),
577 GFP_NOFS);
578 if (!sums) {
579 ret = -ENOMEM;
580 goto fail;
581 }
582
583 sums->bytenr = start;
584 sums->len = (int)size;
585
586 offset = (start - key.offset) >> fs_info->sectorsize_bits;
587 offset *= csum_size;
588 size >>= fs_info->sectorsize_bits;
589
590 read_extent_buffer(path->nodes[0],
591 sums->sums,
592 ((unsigned long)item) + offset,
593 csum_size * size);
594
595 start += fs_info->sectorsize * size;
596 list_add_tail(&sums->list, &tmplist);
597 }
598 path->slots[0]++;
599 }
600 ret = 0;
601fail:
602 while (ret < 0 && !list_empty(&tmplist)) {
603 sums = list_entry(tmplist.next, struct btrfs_ordered_sum, list);
604 list_del(&sums->list);
605 kfree(sums);
606 }
607 list_splice_tail(&tmplist, list);
608
609 btrfs_free_path(path);
610 return ret;
611}
612
613
614
615
616
617
618
619
620
621
622
623blk_status_t btrfs_csum_one_bio(struct btrfs_inode *inode, struct bio *bio,
624 u64 file_start, int contig)
625{
626 struct btrfs_fs_info *fs_info = inode->root->fs_info;
627 SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
628 struct btrfs_ordered_sum *sums;
629 struct btrfs_ordered_extent *ordered = NULL;
630 char *data;
631 struct bvec_iter iter;
632 struct bio_vec bvec;
633 int index;
634 int nr_sectors;
635 unsigned long total_bytes = 0;
636 unsigned long this_sum_bytes = 0;
637 int i;
638 u64 offset;
639 unsigned nofs_flag;
640
641 nofs_flag = memalloc_nofs_save();
642 sums = kvzalloc(btrfs_ordered_sum_size(fs_info, bio->bi_iter.bi_size),
643 GFP_KERNEL);
644 memalloc_nofs_restore(nofs_flag);
645
646 if (!sums)
647 return BLK_STS_RESOURCE;
648
649 sums->len = bio->bi_iter.bi_size;
650 INIT_LIST_HEAD(&sums->list);
651
652 if (contig)
653 offset = file_start;
654 else
655 offset = 0;
656
657 sums->bytenr = bio->bi_iter.bi_sector << 9;
658 index = 0;
659
660 shash->tfm = fs_info->csum_shash;
661
662 bio_for_each_segment(bvec, bio, iter) {
663 if (!contig)
664 offset = page_offset(bvec.bv_page) + bvec.bv_offset;
665
666 if (!ordered) {
667 ordered = btrfs_lookup_ordered_extent(inode, offset);
668 BUG_ON(!ordered);
669 }
670
671 nr_sectors = BTRFS_BYTES_TO_BLKS(fs_info,
672 bvec.bv_len + fs_info->sectorsize
673 - 1);
674
675 for (i = 0; i < nr_sectors; i++) {
676 if (offset >= ordered->file_offset + ordered->num_bytes ||
677 offset < ordered->file_offset) {
678 unsigned long bytes_left;
679
680 sums->len = this_sum_bytes;
681 this_sum_bytes = 0;
682 btrfs_add_ordered_sum(ordered, sums);
683 btrfs_put_ordered_extent(ordered);
684
685 bytes_left = bio->bi_iter.bi_size - total_bytes;
686
687 nofs_flag = memalloc_nofs_save();
688 sums = kvzalloc(btrfs_ordered_sum_size(fs_info,
689 bytes_left), GFP_KERNEL);
690 memalloc_nofs_restore(nofs_flag);
691 BUG_ON(!sums);
692 sums->len = bytes_left;
693 ordered = btrfs_lookup_ordered_extent(inode,
694 offset);
695 ASSERT(ordered);
696 sums->bytenr = (bio->bi_iter.bi_sector << 9)
697 + total_bytes;
698 index = 0;
699 }
700
701 data = kmap_atomic(bvec.bv_page);
702 crypto_shash_digest(shash, data + bvec.bv_offset
703 + (i * fs_info->sectorsize),
704 fs_info->sectorsize,
705 sums->sums + index);
706 kunmap_atomic(data);
707 index += fs_info->csum_size;
708 offset += fs_info->sectorsize;
709 this_sum_bytes += fs_info->sectorsize;
710 total_bytes += fs_info->sectorsize;
711 }
712
713 }
714 this_sum_bytes = 0;
715 btrfs_add_ordered_sum(ordered, sums);
716 btrfs_put_ordered_extent(ordered);
717 return 0;
718}
719
720
721
722
723
724
725
726
727
728
729
730
731static noinline void truncate_one_csum(struct btrfs_fs_info *fs_info,
732 struct btrfs_path *path,
733 struct btrfs_key *key,
734 u64 bytenr, u64 len)
735{
736 struct extent_buffer *leaf;
737 const u32 csum_size = fs_info->csum_size;
738 u64 csum_end;
739 u64 end_byte = bytenr + len;
740 u32 blocksize_bits = fs_info->sectorsize_bits;
741
742 leaf = path->nodes[0];
743 csum_end = btrfs_item_size_nr(leaf, path->slots[0]) / csum_size;
744 csum_end <<= blocksize_bits;
745 csum_end += key->offset;
746
747 if (key->offset < bytenr && csum_end <= end_byte) {
748
749
750
751
752
753
754 u32 new_size = (bytenr - key->offset) >> blocksize_bits;
755 new_size *= csum_size;
756 btrfs_truncate_item(path, new_size, 1);
757 } else if (key->offset >= bytenr && csum_end > end_byte &&
758 end_byte > key->offset) {
759
760
761
762
763
764
765 u32 new_size = (csum_end - end_byte) >> blocksize_bits;
766 new_size *= csum_size;
767
768 btrfs_truncate_item(path, new_size, 0);
769
770 key->offset = end_byte;
771 btrfs_set_item_key_safe(fs_info, path, key);
772 } else {
773 BUG();
774 }
775}
776
777
778
779
780
781int btrfs_del_csums(struct btrfs_trans_handle *trans,
782 struct btrfs_root *root, u64 bytenr, u64 len)
783{
784 struct btrfs_fs_info *fs_info = trans->fs_info;
785 struct btrfs_path *path;
786 struct btrfs_key key;
787 u64 end_byte = bytenr + len;
788 u64 csum_end;
789 struct extent_buffer *leaf;
790 int ret;
791 const u32 csum_size = fs_info->csum_size;
792 u32 blocksize_bits = fs_info->sectorsize_bits;
793
794 ASSERT(root == fs_info->csum_root ||
795 root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID);
796
797 path = btrfs_alloc_path();
798 if (!path)
799 return -ENOMEM;
800
801 while (1) {
802 key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
803 key.offset = end_byte - 1;
804 key.type = BTRFS_EXTENT_CSUM_KEY;
805
806 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
807 if (ret > 0) {
808 if (path->slots[0] == 0)
809 break;
810 path->slots[0]--;
811 } else if (ret < 0) {
812 break;
813 }
814
815 leaf = path->nodes[0];
816 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
817
818 if (key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
819 key.type != BTRFS_EXTENT_CSUM_KEY) {
820 break;
821 }
822
823 if (key.offset >= end_byte)
824 break;
825
826 csum_end = btrfs_item_size_nr(leaf, path->slots[0]) / csum_size;
827 csum_end <<= blocksize_bits;
828 csum_end += key.offset;
829
830
831 if (csum_end <= bytenr)
832 break;
833
834
835 if (key.offset >= bytenr && csum_end <= end_byte) {
836 int del_nr = 1;
837
838
839
840
841
842
843 if (key.offset > bytenr && path->slots[0] > 0) {
844 int slot = path->slots[0] - 1;
845
846 while (slot >= 0) {
847 struct btrfs_key pk;
848
849 btrfs_item_key_to_cpu(leaf, &pk, slot);
850 if (pk.offset < bytenr ||
851 pk.type != BTRFS_EXTENT_CSUM_KEY ||
852 pk.objectid !=
853 BTRFS_EXTENT_CSUM_OBJECTID)
854 break;
855 path->slots[0] = slot;
856 del_nr++;
857 key.offset = pk.offset;
858 slot--;
859 }
860 }
861 ret = btrfs_del_items(trans, root, path,
862 path->slots[0], del_nr);
863 if (ret)
864 goto out;
865 if (key.offset == bytenr)
866 break;
867 } else if (key.offset < bytenr && csum_end > end_byte) {
868 unsigned long offset;
869 unsigned long shift_len;
870 unsigned long item_offset;
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889 offset = (bytenr - key.offset) >> blocksize_bits;
890 offset *= csum_size;
891
892 shift_len = (len >> blocksize_bits) * csum_size;
893
894 item_offset = btrfs_item_ptr_offset(leaf,
895 path->slots[0]);
896
897 memzero_extent_buffer(leaf, item_offset + offset,
898 shift_len);
899 key.offset = bytenr;
900
901
902
903
904
905 ret = btrfs_split_item(trans, root, path, &key, offset);
906 if (ret && ret != -EAGAIN) {
907 btrfs_abort_transaction(trans, ret);
908 goto out;
909 }
910
911 key.offset = end_byte - 1;
912 } else {
913 truncate_one_csum(fs_info, path, &key, bytenr, len);
914 if (key.offset < bytenr)
915 break;
916 }
917 btrfs_release_path(path);
918 }
919 ret = 0;
920out:
921 btrfs_free_path(path);
922 return ret;
923}
924
925int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
926 struct btrfs_root *root,
927 struct btrfs_ordered_sum *sums)
928{
929 struct btrfs_fs_info *fs_info = root->fs_info;
930 struct btrfs_key file_key;
931 struct btrfs_key found_key;
932 struct btrfs_path *path;
933 struct btrfs_csum_item *item;
934 struct btrfs_csum_item *item_end;
935 struct extent_buffer *leaf = NULL;
936 u64 next_offset;
937 u64 total_bytes = 0;
938 u64 csum_offset;
939 u64 bytenr;
940 u32 nritems;
941 u32 ins_size;
942 int index = 0;
943 int found_next;
944 int ret;
945 const u32 csum_size = fs_info->csum_size;
946
947 path = btrfs_alloc_path();
948 if (!path)
949 return -ENOMEM;
950again:
951 next_offset = (u64)-1;
952 found_next = 0;
953 bytenr = sums->bytenr + total_bytes;
954 file_key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
955 file_key.offset = bytenr;
956 file_key.type = BTRFS_EXTENT_CSUM_KEY;
957
958 item = btrfs_lookup_csum(trans, root, path, bytenr, 1);
959 if (!IS_ERR(item)) {
960 ret = 0;
961 leaf = path->nodes[0];
962 item_end = btrfs_item_ptr(leaf, path->slots[0],
963 struct btrfs_csum_item);
964 item_end = (struct btrfs_csum_item *)((char *)item_end +
965 btrfs_item_size_nr(leaf, path->slots[0]));
966 goto found;
967 }
968 ret = PTR_ERR(item);
969 if (ret != -EFBIG && ret != -ENOENT)
970 goto out;
971
972 if (ret == -EFBIG) {
973 u32 item_size;
974
975 leaf = path->nodes[0];
976 item_size = btrfs_item_size_nr(leaf, path->slots[0]);
977 if ((item_size / csum_size) >=
978 MAX_CSUM_ITEMS(fs_info, csum_size)) {
979
980 goto insert;
981 }
982 } else {
983 int slot = path->slots[0] + 1;
984
985 nritems = btrfs_header_nritems(path->nodes[0]);
986 if (!nritems || (path->slots[0] >= nritems - 1)) {
987 ret = btrfs_next_leaf(root, path);
988 if (ret < 0) {
989 goto out;
990 } else if (ret > 0) {
991 found_next = 1;
992 goto insert;
993 }
994 slot = path->slots[0];
995 }
996 btrfs_item_key_to_cpu(path->nodes[0], &found_key, slot);
997 if (found_key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
998 found_key.type != BTRFS_EXTENT_CSUM_KEY) {
999 found_next = 1;
1000 goto insert;
1001 }
1002 next_offset = found_key.offset;
1003 found_next = 1;
1004 goto insert;
1005 }
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017 if (btrfs_leaf_free_space(leaf) >= csum_size) {
1018 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
1019 csum_offset = (bytenr - found_key.offset) >>
1020 fs_info->sectorsize_bits;
1021 goto extend_csum;
1022 }
1023
1024 btrfs_release_path(path);
1025 path->search_for_extension = 1;
1026 ret = btrfs_search_slot(trans, root, &file_key, path,
1027 csum_size, 1);
1028 path->search_for_extension = 0;
1029 if (ret < 0)
1030 goto out;
1031
1032 if (ret > 0) {
1033 if (path->slots[0] == 0)
1034 goto insert;
1035 path->slots[0]--;
1036 }
1037
1038 leaf = path->nodes[0];
1039 btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
1040 csum_offset = (bytenr - found_key.offset) >> fs_info->sectorsize_bits;
1041
1042 if (found_key.type != BTRFS_EXTENT_CSUM_KEY ||
1043 found_key.objectid != BTRFS_EXTENT_CSUM_OBJECTID ||
1044 csum_offset >= MAX_CSUM_ITEMS(fs_info, csum_size)) {
1045 goto insert;
1046 }
1047
1048extend_csum:
1049 if (csum_offset == btrfs_item_size_nr(leaf, path->slots[0]) /
1050 csum_size) {
1051 int extend_nr;
1052 u64 tmp;
1053 u32 diff;
1054
1055 tmp = sums->len - total_bytes;
1056 tmp >>= fs_info->sectorsize_bits;
1057 WARN_ON(tmp < 1);
1058
1059 extend_nr = max_t(int, 1, (int)tmp);
1060 diff = (csum_offset + extend_nr) * csum_size;
1061 diff = min(diff,
1062 MAX_CSUM_ITEMS(fs_info, csum_size) * csum_size);
1063
1064 diff = diff - btrfs_item_size_nr(leaf, path->slots[0]);
1065 diff = min_t(u32, btrfs_leaf_free_space(leaf), diff);
1066 diff /= csum_size;
1067 diff *= csum_size;
1068
1069 btrfs_extend_item(path, diff);
1070 ret = 0;
1071 goto csum;
1072 }
1073
1074insert:
1075 btrfs_release_path(path);
1076 csum_offset = 0;
1077 if (found_next) {
1078 u64 tmp;
1079
1080 tmp = sums->len - total_bytes;
1081 tmp >>= fs_info->sectorsize_bits;
1082 tmp = min(tmp, (next_offset - file_key.offset) >>
1083 fs_info->sectorsize_bits);
1084
1085 tmp = max_t(u64, 1, tmp);
1086 tmp = min_t(u64, tmp, MAX_CSUM_ITEMS(fs_info, csum_size));
1087 ins_size = csum_size * tmp;
1088 } else {
1089 ins_size = csum_size;
1090 }
1091 ret = btrfs_insert_empty_item(trans, root, path, &file_key,
1092 ins_size);
1093 if (ret < 0)
1094 goto out;
1095 if (WARN_ON(ret != 0))
1096 goto out;
1097 leaf = path->nodes[0];
1098csum:
1099 item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
1100 item_end = (struct btrfs_csum_item *)((unsigned char *)item +
1101 btrfs_item_size_nr(leaf, path->slots[0]));
1102 item = (struct btrfs_csum_item *)((unsigned char *)item +
1103 csum_offset * csum_size);
1104found:
1105 ins_size = (u32)(sums->len - total_bytes) >> fs_info->sectorsize_bits;
1106 ins_size *= csum_size;
1107 ins_size = min_t(u32, (unsigned long)item_end - (unsigned long)item,
1108 ins_size);
1109 write_extent_buffer(leaf, sums->sums + index, (unsigned long)item,
1110 ins_size);
1111
1112 index += ins_size;
1113 ins_size /= csum_size;
1114 total_bytes += ins_size * fs_info->sectorsize;
1115
1116 btrfs_mark_buffer_dirty(path->nodes[0]);
1117 if (total_bytes < sums->len) {
1118 btrfs_release_path(path);
1119 cond_resched();
1120 goto again;
1121 }
1122out:
1123 btrfs_free_path(path);
1124 return ret;
1125}
1126
1127void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
1128 const struct btrfs_path *path,
1129 struct btrfs_file_extent_item *fi,
1130 const bool new_inline,
1131 struct extent_map *em)
1132{
1133 struct btrfs_fs_info *fs_info = inode->root->fs_info;
1134 struct btrfs_root *root = inode->root;
1135 struct extent_buffer *leaf = path->nodes[0];
1136 const int slot = path->slots[0];
1137 struct btrfs_key key;
1138 u64 extent_start, extent_end;
1139 u64 bytenr;
1140 u8 type = btrfs_file_extent_type(leaf, fi);
1141 int compress_type = btrfs_file_extent_compression(leaf, fi);
1142
1143 btrfs_item_key_to_cpu(leaf, &key, slot);
1144 extent_start = key.offset;
1145 extent_end = btrfs_file_extent_end(path);
1146 em->ram_bytes = btrfs_file_extent_ram_bytes(leaf, fi);
1147 if (type == BTRFS_FILE_EXTENT_REG ||
1148 type == BTRFS_FILE_EXTENT_PREALLOC) {
1149 em->start = extent_start;
1150 em->len = extent_end - extent_start;
1151 em->orig_start = extent_start -
1152 btrfs_file_extent_offset(leaf, fi);
1153 em->orig_block_len = btrfs_file_extent_disk_num_bytes(leaf, fi);
1154 bytenr = btrfs_file_extent_disk_bytenr(leaf, fi);
1155 if (bytenr == 0) {
1156 em->block_start = EXTENT_MAP_HOLE;
1157 return;
1158 }
1159 if (compress_type != BTRFS_COMPRESS_NONE) {
1160 set_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
1161 em->compress_type = compress_type;
1162 em->block_start = bytenr;
1163 em->block_len = em->orig_block_len;
1164 } else {
1165 bytenr += btrfs_file_extent_offset(leaf, fi);
1166 em->block_start = bytenr;
1167 em->block_len = em->len;
1168 if (type == BTRFS_FILE_EXTENT_PREALLOC)
1169 set_bit(EXTENT_FLAG_PREALLOC, &em->flags);
1170 }
1171 } else if (type == BTRFS_FILE_EXTENT_INLINE) {
1172 em->block_start = EXTENT_MAP_INLINE;
1173 em->start = extent_start;
1174 em->len = extent_end - extent_start;
1175
1176
1177
1178
1179 em->orig_start = EXTENT_MAP_HOLE;
1180 em->block_len = (u64)-1;
1181 if (!new_inline && compress_type != BTRFS_COMPRESS_NONE) {
1182 set_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
1183 em->compress_type = compress_type;
1184 }
1185 } else {
1186 btrfs_err(fs_info,
1187 "unknown file extent item type %d, inode %llu, offset %llu, "
1188 "root %llu", type, btrfs_ino(inode), extent_start,
1189 root->root_key.objectid);
1190 }
1191}
1192
1193
1194
1195
1196
1197
1198u64 btrfs_file_extent_end(const struct btrfs_path *path)
1199{
1200 const struct extent_buffer *leaf = path->nodes[0];
1201 const int slot = path->slots[0];
1202 struct btrfs_file_extent_item *fi;
1203 struct btrfs_key key;
1204 u64 end;
1205
1206 btrfs_item_key_to_cpu(leaf, &key, slot);
1207 ASSERT(key.type == BTRFS_EXTENT_DATA_KEY);
1208 fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
1209
1210 if (btrfs_file_extent_type(leaf, fi) == BTRFS_FILE_EXTENT_INLINE) {
1211 end = btrfs_file_extent_ram_bytes(leaf, fi);
1212 end = ALIGN(key.offset + end, leaf->fs_info->sectorsize);
1213 } else {
1214 end = key.offset + btrfs_file_extent_num_bytes(leaf, fi);
1215 }
1216
1217 return end;
1218}
1219