hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
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,37 +560,51 @@
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);
485
- BUG_ON(!sums); /* -ENOMEM */
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);
605
+ if (!sums)
606
+ return BLK_STS_RESOURCE;
607
+
486608 sums->len = bytes_left;
487609 ordered = btrfs_lookup_ordered_extent(inode,
488610 offset);
....@@ -490,28 +612,23 @@
490612 sums->bytenr = ((u64)bio->bi_iter.bi_sector << 9)
491613 + total_bytes;
492614 index = 0;
493
-
494
- data = kmap_atomic(bvec.bv_page);
495615 }
496616
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++;
617
+ data = kmap_atomic(bvec.bv_page);
618
+ crypto_shash_digest(shash, data + bvec.bv_offset
619
+ + (i * fs_info->sectorsize),
620
+ fs_info->sectorsize,
621
+ sums->sums + index);
622
+ kunmap_atomic(data);
623
+ index += csum_size;
506624 offset += fs_info->sectorsize;
507625 this_sum_bytes += fs_info->sectorsize;
508626 total_bytes += fs_info->sectorsize;
509627 }
510628
511
- kunmap_atomic(data);
512629 }
513630 this_sum_bytes = 0;
514
- btrfs_add_ordered_sum(inode, ordered, sums);
631
+ btrfs_add_ordered_sum(ordered, sums);
515632 btrfs_put_ordered_extent(ordered);
516633 return 0;
517634 }
....@@ -552,7 +669,7 @@
552669 */
553670 u32 new_size = (bytenr - key->offset) >> blocksize_bits;
554671 new_size *= csum_size;
555
- btrfs_truncate_item(fs_info, path, new_size, 1);
672
+ btrfs_truncate_item(path, new_size, 1);
556673 } else if (key->offset >= bytenr && csum_end > end_byte &&
557674 end_byte > key->offset) {
558675 /*
....@@ -564,7 +681,7 @@
564681 u32 new_size = (csum_end - end_byte) >> blocksize_bits;
565682 new_size *= csum_size;
566683
567
- btrfs_truncate_item(fs_info, path, new_size, 0);
684
+ btrfs_truncate_item(path, new_size, 0);
568685
569686 key->offset = end_byte;
570687 btrfs_set_item_key_safe(fs_info, path, key);
....@@ -767,7 +884,7 @@
767884 }
768885 ret = PTR_ERR(item);
769886 if (ret != -EFBIG && ret != -ENOENT)
770
- goto fail_unlock;
887
+ goto out;
771888
772889 if (ret == -EFBIG) {
773890 u32 item_size;
....@@ -805,14 +922,27 @@
805922 }
806923
807924 /*
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
925
+ * At this point, we know the tree has a checksum item that ends at an
926
+ * offset matching the start of the checksum range we want to insert.
927
+ * We try to extend that item as much as possible and then add as many
928
+ * checksums to it as they fit.
929
+ *
930
+ * First check if the leaf has enough free space for at least one
931
+ * checksum. If it has go directly to the item extension code, otherwise
932
+ * release the path and do a search for insertion before the extension.
810933 */
934
+ if (btrfs_leaf_free_space(leaf) >= csum_size) {
935
+ btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
936
+ csum_offset = (bytenr - found_key.offset) >>
937
+ fs_info->sb->s_blocksize_bits;
938
+ goto extend_csum;
939
+ }
940
+
811941 btrfs_release_path(path);
812942 ret = btrfs_search_slot(trans, root, &file_key, path,
813943 csum_size, 1);
814944 if (ret < 0)
815
- goto fail_unlock;
945
+ goto out;
816946
817947 if (ret > 0) {
818948 if (path->slots[0] == 0)
....@@ -831,19 +961,13 @@
831961 goto insert;
832962 }
833963
964
+extend_csum:
834965 if (csum_offset == btrfs_item_size_nr(leaf, path->slots[0]) /
835966 csum_size) {
836967 int extend_nr;
837968 u64 tmp;
838969 u32 diff;
839
- u32 free_space;
840970
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;
847971 tmp = sums->len - total_bytes;
848972 tmp >>= fs_info->sb->s_blocksize_bits;
849973 WARN_ON(tmp < 1);
....@@ -854,11 +978,11 @@
854978 MAX_CSUM_ITEMS(fs_info, csum_size) * csum_size);
855979
856980 diff = diff - btrfs_item_size_nr(leaf, path->slots[0]);
857
- diff = min(free_space, diff);
981
+ diff = min_t(u32, btrfs_leaf_free_space(leaf), diff);
858982 diff /= csum_size;
859983 diff *= csum_size;
860984
861
- btrfs_extend_item(fs_info, path, diff);
985
+ btrfs_extend_item(path, diff);
862986 ret = 0;
863987 goto csum;
864988 }
....@@ -885,9 +1009,9 @@
8851009 ins_size);
8861010 path->leave_spinning = 0;
8871011 if (ret < 0)
888
- goto fail_unlock;
1012
+ goto out;
8891013 if (WARN_ON(ret != 0))
890
- goto fail_unlock;
1014
+ goto out;
8911015 leaf = path->nodes[0];
8921016 csum:
8931017 item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
....@@ -904,9 +1028,9 @@
9041028 write_extent_buffer(leaf, sums->sums + index, (unsigned long)item,
9051029 ins_size);
9061030
1031
+ index += ins_size;
9071032 ins_size /= csum_size;
9081033 total_bytes += ins_size * fs_info->sectorsize;
909
- index += ins_size;
9101034
9111035 btrfs_mark_buffer_dirty(path->nodes[0]);
9121036 if (total_bytes < sums->len) {
....@@ -917,9 +1041,6 @@
9171041 out:
9181042 btrfs_free_path(path);
9191043 return ret;
920
-
921
-fail_unlock:
922
- goto out;
9231044 }
9241045
9251046 void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode,
....@@ -938,21 +1059,9 @@
9381059 u8 type = btrfs_file_extent_type(leaf, fi);
9391060 int compress_type = btrfs_file_extent_compression(leaf, fi);
9401061
941
- em->bdev = fs_info->fs_devices->latest_bdev;
9421062 btrfs_item_key_to_cpu(leaf, &key, slot);
9431063 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
-
1064
+ extent_end = btrfs_file_extent_end(path);
9561065 em->ram_bytes = btrfs_file_extent_ram_bytes(leaf, fi);
9571066 if (type == BTRFS_FILE_EXTENT_REG ||
9581067 type == BTRFS_FILE_EXTENT_PREALLOC) {
....@@ -999,3 +1108,30 @@
9991108 root->root_key.objectid);
10001109 }
10011110 }
1111
+
1112
+/*
1113
+ * Returns the end offset (non inclusive) of the file extent item the given path
1114
+ * points to. If it points to an inline extent, the returned offset is rounded
1115
+ * up to the sector size.
1116
+ */
1117
+u64 btrfs_file_extent_end(const struct btrfs_path *path)
1118
+{
1119
+ const struct extent_buffer *leaf = path->nodes[0];
1120
+ const int slot = path->slots[0];
1121
+ struct btrfs_file_extent_item *fi;
1122
+ struct btrfs_key key;
1123
+ u64 end;
1124
+
1125
+ btrfs_item_key_to_cpu(leaf, &key, slot);
1126
+ ASSERT(key.type == BTRFS_EXTENT_DATA_KEY);
1127
+ fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
1128
+
1129
+ if (btrfs_file_extent_type(leaf, fi) == BTRFS_FILE_EXTENT_INLINE) {
1130
+ end = btrfs_file_extent_ram_bytes(leaf, fi);
1131
+ end = ALIGN(key.offset + end, leaf->fs_info->sectorsize);
1132
+ } else {
1133
+ end = key.offset + btrfs_file_extent_num_bytes(leaf, fi);
1134
+ }
1135
+
1136
+ return end;
1137
+}