forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/fs/btrfs/file-item.c
....@@ -7,6 +7,8 @@
77 #include <linux/slab.h>
88 #include <linux/pagemap.h>
99 #include <linux/highmem.h>
10
+#include <linux/sched/mm.h>
11
+#include <crypto/hash.h>
1012 #include "ctree.h"
1113 #include "disk-io.h"
1214 #include "transaction.h"
....@@ -21,9 +23,104 @@
2123 #define MAX_CSUM_ITEMS(r, size) (min_t(u32, __MAX_CSUM_ITEMS(r, size), \
2224 PAGE_SIZE))
2325
24
-#define MAX_ORDERED_SUM_BYTES(fs_info) ((PAGE_SIZE - \
25
- sizeof(struct btrfs_ordered_sum)) / \
26
- sizeof(u32) * (fs_info)->sectorsize)
26
+/**
27
+ * @inode - the inode we want to update the disk_i_size for
28
+ * @new_i_size - the i_size we want to set to, 0 if we use i_size
29
+ *
30
+ * With NO_HOLES set this simply sets the disk_is_size to whatever i_size_read()
31
+ * returns as it is perfectly fine with a file that has holes without hole file
32
+ * extent items.
33
+ *
34
+ * However without NO_HOLES we need to only return the area that is contiguous
35
+ * from the 0 offset of the file. Otherwise we could end up adjust i_size up
36
+ * to an extent that has a gap in between.
37
+ *
38
+ * Finally new_i_size should only be set in the case of truncate where we're not
39
+ * ready to use i_size_read() as the limiter yet.
40
+ */
41
+void btrfs_inode_safe_disk_i_size_write(struct inode *inode, u64 new_i_size)
42
+{
43
+ struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info;
44
+ u64 start, end, i_size;
45
+ int ret;
46
+
47
+ i_size = new_i_size ?: i_size_read(inode);
48
+ if (btrfs_fs_incompat(fs_info, NO_HOLES)) {
49
+ BTRFS_I(inode)->disk_i_size = i_size;
50
+ return;
51
+ }
52
+
53
+ spin_lock(&BTRFS_I(inode)->lock);
54
+ ret = find_contiguous_extent_bit(&BTRFS_I(inode)->file_extent_tree, 0,
55
+ &start, &end, EXTENT_DIRTY);
56
+ if (!ret && start == 0)
57
+ i_size = min(i_size, end + 1);
58
+ else
59
+ i_size = 0;
60
+ BTRFS_I(inode)->disk_i_size = i_size;
61
+ spin_unlock(&BTRFS_I(inode)->lock);
62
+}
63
+
64
+/**
65
+ * @inode - the inode we're modifying
66
+ * @start - the start file offset of the file extent we've inserted
67
+ * @len - the logical length of the file extent item
68
+ *
69
+ * Call when we are inserting a new file extent where there was none before.
70
+ * Does not need to call this in the case where we're replacing an existing file
71
+ * extent, however if not sure it's fine to call this multiple times.
72
+ *
73
+ * The start and len must match the file extent item, so thus must be sectorsize
74
+ * aligned.
75
+ */
76
+int btrfs_inode_set_file_extent_range(struct btrfs_inode *inode, u64 start,
77
+ u64 len)
78
+{
79
+ if (len == 0)
80
+ return 0;
81
+
82
+ ASSERT(IS_ALIGNED(start + len, inode->root->fs_info->sectorsize));
83
+
84
+ if (btrfs_fs_incompat(inode->root->fs_info, NO_HOLES))
85
+ return 0;
86
+ return set_extent_bits(&inode->file_extent_tree, start, start + len - 1,
87
+ EXTENT_DIRTY);
88
+}
89
+
90
+/**
91
+ * @inode - the inode we're modifying
92
+ * @start - the start file offset of the file extent we've inserted
93
+ * @len - the logical length of the file extent item
94
+ *
95
+ * Called when we drop a file extent, for example when we truncate. Doesn't
96
+ * need to be called for cases where we're replacing a file extent, like when
97
+ * we've COWed a file extent.
98
+ *
99
+ * The start and len must match the file extent item, so thus must be sectorsize
100
+ * aligned.
101
+ */
102
+int btrfs_inode_clear_file_extent_range(struct btrfs_inode *inode, u64 start,
103
+ u64 len)
104
+{
105
+ if (len == 0)
106
+ return 0;
107
+
108
+ ASSERT(IS_ALIGNED(start + len, inode->root->fs_info->sectorsize) ||
109
+ len == (u64)-1);
110
+
111
+ if (btrfs_fs_incompat(inode->root->fs_info, NO_HOLES))
112
+ return 0;
113
+ return clear_extent_bit(&inode->file_extent_tree, start,
114
+ start + len - 1, EXTENT_DIRTY, 0, 0, NULL);
115
+}
116
+
117
+static inline u32 max_ordered_sum_bytes(struct btrfs_fs_info *fs_info,
118
+ u16 csum_size)
119
+{
120
+ u32 ncsums = (PAGE_SIZE - sizeof(struct btrfs_ordered_sum)) / csum_size;
121
+
122
+ return ncsums * fs_info->sectorsize;
123
+}
27124
28125 int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
29126 struct btrfs_root *root,
....@@ -142,23 +239,30 @@
142239 return ret;
143240 }
144241
145
-static void btrfs_io_bio_endio_readpage(struct btrfs_io_bio *bio, int err)
146
-{
147
- kfree(bio->csum_allocated);
148
-}
149
-
150
-static blk_status_t __btrfs_lookup_bio_sums(struct inode *inode, struct bio *bio,
151
- u64 logical_offset, u32 *dst, int dio)
242
+/**
243
+ * btrfs_lookup_bio_sums - Look up checksums for a bio.
244
+ * @inode: inode that the bio is for.
245
+ * @bio: bio to look up.
246
+ * @offset: Unless (u64)-1, look up checksums for this offset in the file.
247
+ * If (u64)-1, use the page offsets from the bio instead.
248
+ * @dst: Buffer of size nblocks * btrfs_super_csum_size() used to return
249
+ * checksum (nblocks = bio->bi_iter.bi_size / fs_info->sectorsize). If
250
+ * NULL, the checksum buffer is allocated and returned in
251
+ * btrfs_io_bio(bio)->csum instead.
252
+ *
253
+ * Return: BLK_STS_RESOURCE if allocating memory fails, BLK_STS_OK otherwise.
254
+ */
255
+blk_status_t btrfs_lookup_bio_sums(struct inode *inode, struct bio *bio,
256
+ u64 offset, u8 *dst)
152257 {
153258 struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
154259 struct bio_vec bvec;
155260 struct bvec_iter iter;
156
- struct btrfs_io_bio *btrfs_bio = btrfs_io_bio(bio);
157261 struct btrfs_csum_item *item = NULL;
158262 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
159263 struct btrfs_path *path;
264
+ const bool page_offsets = (offset == (u64)-1);
160265 u8 *csum;
161
- u64 offset = 0;
162266 u64 item_start_offset = 0;
163267 u64 item_last_offset = 0;
164268 u64 disk_bytenr;
....@@ -174,21 +278,21 @@
174278
175279 nblocks = bio->bi_iter.bi_size >> inode->i_sb->s_blocksize_bits;
176280 if (!dst) {
281
+ struct btrfs_io_bio *btrfs_bio = btrfs_io_bio(bio);
282
+
177283 if (nblocks * csum_size > BTRFS_BIO_INLINE_CSUM_SIZE) {
178
- btrfs_bio->csum_allocated = kmalloc_array(nblocks,
179
- csum_size, GFP_NOFS);
180
- if (!btrfs_bio->csum_allocated) {
284
+ btrfs_bio->csum = kmalloc_array(nblocks, csum_size,
285
+ GFP_NOFS);
286
+ if (!btrfs_bio->csum) {
181287 btrfs_free_path(path);
182288 return BLK_STS_RESOURCE;
183289 }
184
- btrfs_bio->csum = btrfs_bio->csum_allocated;
185
- btrfs_bio->end_io = btrfs_io_bio_endio_readpage;
186290 } else {
187291 btrfs_bio->csum = btrfs_bio->csum_inline;
188292 }
189293 csum = btrfs_bio->csum;
190294 } else {
191
- csum = (u8 *)dst;
295
+ csum = dst;
192296 }
193297
194298 if (bio->bi_iter.bi_size > PAGE_SIZE * 8)
....@@ -206,18 +310,16 @@
206310 }
207311
208312 disk_bytenr = (u64)bio->bi_iter.bi_sector << 9;
209
- if (dio)
210
- offset = logical_offset;
211313
212314 bio_for_each_segment(bvec, bio, iter) {
213315 page_bytes_left = bvec.bv_len;
214316 if (count)
215317 goto next;
216318
217
- if (!dio)
319
+ if (page_offsets)
218320 offset = page_offset(bvec.bv_page) + bvec.bv_offset;
219
- count = btrfs_find_ordered_sum(inode, offset, disk_bytenr,
220
- (u32 *)csum, nblocks);
321
+ count = btrfs_find_ordered_sum(BTRFS_I(inode), offset,
322
+ disk_bytenr, csum, nblocks);
221323 if (count)
222324 goto found;
223325
....@@ -287,17 +389,7 @@
287389
288390 WARN_ON_ONCE(count);
289391 btrfs_free_path(path);
290
- return 0;
291
-}
292
-
293
-blk_status_t btrfs_lookup_bio_sums(struct inode *inode, struct bio *bio, u32 *dst)
294
-{
295
- return __btrfs_lookup_bio_sums(inode, bio, 0, dst, 0);
296
-}
297
-
298
-blk_status_t btrfs_lookup_bio_sums_dio(struct inode *inode, struct bio *bio, u64 offset)
299
-{
300
- return __btrfs_lookup_bio_sums(inode, bio, offset, NULL, 1);
392
+ return BLK_STS_OK;
301393 }
302394
303395 int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
....@@ -381,7 +473,7 @@
381473 struct btrfs_csum_item);
382474 while (start < csum_end) {
383475 size = min_t(size_t, csum_end - start,
384
- MAX_ORDERED_SUM_BYTES(fs_info));
476
+ max_ordered_sum_bytes(fs_info, csum_size));
385477 sums = kzalloc(btrfs_ordered_sum_size(fs_info, size),
386478 GFP_NOFS);
387479 if (!sums) {
....@@ -420,10 +512,21 @@
420512 return ret;
421513 }
422514
423
-blk_status_t btrfs_csum_one_bio(struct inode *inode, struct bio *bio,
515
+/*
516
+ * btrfs_csum_one_bio - Calculates checksums of the data contained inside a bio
517
+ * @inode: Owner of the data inside the bio
518
+ * @bio: Contains the data to be checksummed
519
+ * @file_start: offset in file this bio begins to describe
520
+ * @contig: Boolean. If true/1 means all bio vecs in this bio are
521
+ * contiguous and they begin at @file_start in the file. False/0
522
+ * means this bio can contains potentially discontigous bio vecs
523
+ * so the logical offset of each should be calculated separately.
524
+ */
525
+blk_status_t btrfs_csum_one_bio(struct btrfs_inode *inode, struct bio *bio,
424526 u64 file_start, int contig)
425527 {
426
- struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
528
+ struct btrfs_fs_info *fs_info = inode->root->fs_info;
529
+ SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
427530 struct btrfs_ordered_sum *sums;
428531 struct btrfs_ordered_extent *ordered = NULL;
429532 char *data;
....@@ -435,9 +538,14 @@
435538 unsigned long this_sum_bytes = 0;
436539 int i;
437540 u64 offset;
541
+ unsigned nofs_flag;
542
+ const u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);
438543
439
- sums = kzalloc(btrfs_ordered_sum_size(fs_info, bio->bi_iter.bi_size),
440
- GFP_NOFS);
544
+ nofs_flag = memalloc_nofs_save();
545
+ sums = kvzalloc(btrfs_ordered_sum_size(fs_info, bio->bi_iter.bi_size),
546
+ GFP_KERNEL);
547
+ memalloc_nofs_restore(nofs_flag);
548
+
441549 if (!sums)
442550 return BLK_STS_RESOURCE;
443551
....@@ -452,36 +560,48 @@
452560 sums->bytenr = (u64)bio->bi_iter.bi_sector << 9;
453561 index = 0;
454562
563
+ shash->tfm = fs_info->csum_shash;
564
+
455565 bio_for_each_segment(bvec, bio, iter) {
456566 if (!contig)
457567 offset = page_offset(bvec.bv_page) + bvec.bv_offset;
458568
459569 if (!ordered) {
460570 ordered = btrfs_lookup_ordered_extent(inode, offset);
461
- BUG_ON(!ordered); /* Logic error */
571
+ /*
572
+ * The bio range is not covered by any ordered extent,
573
+ * must be a code logic error.
574
+ */
575
+ if (unlikely(!ordered)) {
576
+ WARN(1, KERN_WARNING
577
+ "no ordered extent for root %llu ino %llu offset %llu\n",
578
+ inode->root->root_key.objectid,
579
+ btrfs_ino(inode), offset);
580
+ kvfree(sums);
581
+ return BLK_STS_IOERR;
582
+ }
462583 }
463
-
464
- data = kmap_atomic(bvec.bv_page);
465584
466585 nr_sectors = BTRFS_BYTES_TO_BLKS(fs_info,
467586 bvec.bv_len + fs_info->sectorsize
468587 - 1);
469588
470589 for (i = 0; i < nr_sectors; i++) {
471
- if (offset >= ordered->file_offset + ordered->len ||
472
- offset < ordered->file_offset) {
590
+ if (offset >= ordered->file_offset + ordered->num_bytes ||
591
+ offset < ordered->file_offset) {
473592 unsigned long bytes_left;
474593
475
- kunmap_atomic(data);
476594 sums->len = this_sum_bytes;
477595 this_sum_bytes = 0;
478
- btrfs_add_ordered_sum(inode, ordered, sums);
596
+ btrfs_add_ordered_sum(ordered, sums);
479597 btrfs_put_ordered_extent(ordered);
480598
481599 bytes_left = bio->bi_iter.bi_size - total_bytes;
482600
483
- sums = kzalloc(btrfs_ordered_sum_size(fs_info, bytes_left),
484
- GFP_NOFS);
601
+ nofs_flag = memalloc_nofs_save();
602
+ sums = kvzalloc(btrfs_ordered_sum_size(fs_info,
603
+ bytes_left), GFP_KERNEL);
604
+ memalloc_nofs_restore(nofs_flag);
485605 BUG_ON(!sums); /* -ENOMEM */
486606 sums->len = bytes_left;
487607 ordered = btrfs_lookup_ordered_extent(inode,
....@@ -490,28 +610,23 @@
490610 sums->bytenr = ((u64)bio->bi_iter.bi_sector << 9)
491611 + total_bytes;
492612 index = 0;
493
-
494
- data = kmap_atomic(bvec.bv_page);
495613 }
496614
497
- sums->sums[index] = ~(u32)0;
498
- sums->sums[index]
499
- = btrfs_csum_data(data + bvec.bv_offset
500
- + (i * fs_info->sectorsize),
501
- sums->sums[index],
502
- fs_info->sectorsize);
503
- btrfs_csum_final(sums->sums[index],
504
- (char *)(sums->sums + index));
505
- index++;
615
+ data = kmap_atomic(bvec.bv_page);
616
+ crypto_shash_digest(shash, data + bvec.bv_offset
617
+ + (i * fs_info->sectorsize),
618
+ fs_info->sectorsize,
619
+ sums->sums + index);
620
+ kunmap_atomic(data);
621
+ index += csum_size;
506622 offset += fs_info->sectorsize;
507623 this_sum_bytes += fs_info->sectorsize;
508624 total_bytes += fs_info->sectorsize;
509625 }
510626
511
- kunmap_atomic(data);
512627 }
513628 this_sum_bytes = 0;
514
- btrfs_add_ordered_sum(inode, ordered, sums);
629
+ btrfs_add_ordered_sum(ordered, sums);
515630 btrfs_put_ordered_extent(ordered);
516631 return 0;
517632 }
....@@ -552,7 +667,7 @@
552667 */
553668 u32 new_size = (bytenr - key->offset) >> blocksize_bits;
554669 new_size *= csum_size;
555
- btrfs_truncate_item(fs_info, path, new_size, 1);
670
+ btrfs_truncate_item(path, new_size, 1);
556671 } else if (key->offset >= bytenr && csum_end > end_byte &&
557672 end_byte > key->offset) {
558673 /*
....@@ -564,7 +679,7 @@
564679 u32 new_size = (csum_end - end_byte) >> blocksize_bits;
565680 new_size *= csum_size;
566681
567
- btrfs_truncate_item(fs_info, path, new_size, 0);
682
+ btrfs_truncate_item(path, new_size, 0);
568683
569684 key->offset = end_byte;
570685 btrfs_set_item_key_safe(fs_info, path, key);
....@@ -767,7 +882,7 @@
767882 }
768883 ret = PTR_ERR(item);
769884 if (ret != -EFBIG && ret != -ENOENT)
770
- goto fail_unlock;
885
+ goto out;
771886
772887 if (ret == -EFBIG) {
773888 u32 item_size;
....@@ -805,14 +920,27 @@
805920 }
806921
807922 /*
808
- * at this point, we know the tree has an item, but it isn't big
809
- * enough yet to put our csum in. Grow it
923
+ * At this point, we know the tree has a checksum item that ends at an
924
+ * offset matching the start of the checksum range we want to insert.
925
+ * We try to extend that item as much as possible and then add as many
926
+ * checksums to it as they fit.
927
+ *
928
+ * First check if the leaf has enough free space for at least one
929
+ * checksum. If it has go directly to the item extension code, otherwise
930
+ * release the path and do a search for insertion before the extension.
810931 */
932
+ if (btrfs_leaf_free_space(leaf) >= csum_size) {
933
+ btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
934
+ csum_offset = (bytenr - found_key.offset) >>
935
+ fs_info->sb->s_blocksize_bits;
936
+ goto extend_csum;
937
+ }
938
+
811939 btrfs_release_path(path);
812940 ret = btrfs_search_slot(trans, root, &file_key, path,
813941 csum_size, 1);
814942 if (ret < 0)
815
- goto fail_unlock;
943
+ goto out;
816944
817945 if (ret > 0) {
818946 if (path->slots[0] == 0)
....@@ -831,19 +959,13 @@
831959 goto insert;
832960 }
833961
962
+extend_csum:
834963 if (csum_offset == btrfs_item_size_nr(leaf, path->slots[0]) /
835964 csum_size) {
836965 int extend_nr;
837966 u64 tmp;
838967 u32 diff;
839
- u32 free_space;
840968
841
- if (btrfs_leaf_free_space(fs_info, leaf) <
842
- sizeof(struct btrfs_item) + csum_size * 2)
843
- goto insert;
844
-
845
- free_space = btrfs_leaf_free_space(fs_info, leaf) -
846
- sizeof(struct btrfs_item) - csum_size;
847969 tmp = sums->len - total_bytes;
848970 tmp >>= fs_info->sb->s_blocksize_bits;
849971 WARN_ON(tmp < 1);
....@@ -854,11 +976,11 @@
854976 MAX_CSUM_ITEMS(fs_info, csum_size) * csum_size);
855977
856978 diff = diff - btrfs_item_size_nr(leaf, path->slots[0]);
857
- diff = min(free_space, diff);
979
+ diff = min_t(u32, btrfs_leaf_free_space(leaf), diff);
858980 diff /= csum_size;
859981 diff *= csum_size;
860982
861
- btrfs_extend_item(fs_info, path, diff);
983
+ btrfs_extend_item(path, diff);
862984 ret = 0;
863985 goto csum;
864986 }
....@@ -885,9 +1007,9 @@
8851007 ins_size);
8861008 path->leave_spinning = 0;
8871009 if (ret < 0)
888
- goto fail_unlock;
1010
+ goto out;
8891011 if (WARN_ON(ret != 0))
890
- goto fail_unlock;
1012
+ goto out;
8911013 leaf = path->nodes[0];
8921014 csum:
8931015 item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
....@@ -904,9 +1026,9 @@
9041026 write_extent_buffer(leaf, sums->sums + index, (unsigned long)item,
9051027 ins_size);
9061028
1029
+ index += ins_size;
9071030 ins_size /= csum_size;
9081031 total_bytes += ins_size * fs_info->sectorsize;
909
- index += ins_size;
9101032
9111033 btrfs_mark_buffer_dirty(path->nodes[0]);
9121034 if (total_bytes < sums->len) {
....@@ -917,9 +1039,6 @@
9171039 out:
9181040 btrfs_free_path(path);
9191041 return ret;
920
-
921
-fail_unlock:
922
- goto out;
9231042 }
9241043
9251044 void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
....@@ -938,21 +1057,9 @@
9381057 u8 type = btrfs_file_extent_type(leaf, fi);
9391058 int compress_type = btrfs_file_extent_compression(leaf, fi);
9401059
941
- em->bdev = fs_info->fs_devices->latest_bdev;
9421060 btrfs_item_key_to_cpu(leaf, &key, slot);
9431061 extent_start = key.offset;
944
-
945
- if (type == BTRFS_FILE_EXTENT_REG ||
946
- type == BTRFS_FILE_EXTENT_PREALLOC) {
947
- extent_end = extent_start +
948
- btrfs_file_extent_num_bytes(leaf, fi);
949
- } else if (type == BTRFS_FILE_EXTENT_INLINE) {
950
- size_t size;
951
- size = btrfs_file_extent_ram_bytes(leaf, fi);
952
- extent_end = ALIGN(extent_start + size,
953
- fs_info->sectorsize);
954
- }
955
-
1062
+ extent_end = btrfs_file_extent_end(path);
9561063 em->ram_bytes = btrfs_file_extent_ram_bytes(leaf, fi);
9571064 if (type == BTRFS_FILE_EXTENT_REG ||
9581065 type == BTRFS_FILE_EXTENT_PREALLOC) {
....@@ -999,3 +1106,30 @@
9991106 root->root_key.objectid);
10001107 }
10011108 }
1109
+
1110
+/*
1111
+ * Returns the end offset (non inclusive) of the file extent item the given path
1112
+ * points to. If it points to an inline extent, the returned offset is rounded
1113
+ * up to the sector size.
1114
+ */
1115
+u64 btrfs_file_extent_end(const struct btrfs_path *path)
1116
+{
1117
+ const struct extent_buffer *leaf = path->nodes[0];
1118
+ const int slot = path->slots[0];
1119
+ struct btrfs_file_extent_item *fi;
1120
+ struct btrfs_key key;
1121
+ u64 end;
1122
+
1123
+ btrfs_item_key_to_cpu(leaf, &key, slot);
1124
+ ASSERT(key.type == BTRFS_EXTENT_DATA_KEY);
1125
+ fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
1126
+
1127
+ if (btrfs_file_extent_type(leaf, fi) == BTRFS_FILE_EXTENT_INLINE) {
1128
+ end = btrfs_file_extent_ram_bytes(leaf, fi);
1129
+ end = ALIGN(key.offset + end, leaf->fs_info->sectorsize);
1130
+ } else {
1131
+ end = key.offset + btrfs_file_extent_num_bytes(leaf, fi);
1132
+ }
1133
+
1134
+ return end;
1135
+}