Skip to content

Commit d517857

Browse files
Johannes Thumshirnkdave
authored andcommitted
btrfs: directly call into crypto framework for checksumming
Currently btrfs_csum_data() relied on the crc32c() wrapper around the crypto framework for calculating the CRCs. As we have our own crypto_shash structure in the fs_info now, we can directly call into the crypto framework without going trough the wrapper. This way we can even remove the btrfs_csum_data() and btrfs_csum_final() wrappers. The module dependency on crc32c is preserved via MODULE_SOFTDEP("pre: crc32c"), which was previously provided by LIBCRC32C config option doing the same. Signed-off-by: Johannes Thumshirn <[email protected]> Reviewed-by: David Sterba <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 6d97c6e commit d517857

File tree

9 files changed

+89
-62
lines changed

9 files changed

+89
-62
lines changed

fs/btrfs/Kconfig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
config BTRFS_FS
44
tristate "Btrfs filesystem support"
5-
select LIBCRC32C
5+
select CRYPTO
6+
select CRYPTO_CRC32C
67
select ZLIB_INFLATE
78
select ZLIB_DEFLATE
89
select LZO_COMPRESS

fs/btrfs/check-integrity.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
#include <linux/blkdev.h>
8484
#include <linux/mm.h>
8585
#include <linux/string.h>
86-
#include <linux/crc32c.h>
86+
#include <crypto/hash.h>
8787
#include "ctree.h"
8888
#include "disk-io.h"
8989
#include "transaction.h"
@@ -1710,9 +1710,9 @@ static int btrfsic_test_for_metadata(struct btrfsic_state *state,
17101710
char **datav, unsigned int num_pages)
17111711
{
17121712
struct btrfs_fs_info *fs_info = state->fs_info;
1713+
SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
17131714
struct btrfs_header *h;
17141715
u8 csum[BTRFS_CSUM_SIZE];
1715-
u32 crc = ~(u32)0;
17161716
unsigned int i;
17171717

17181718
if (num_pages * PAGE_SIZE < state->metablock_size)
@@ -1723,14 +1723,17 @@ static int btrfsic_test_for_metadata(struct btrfsic_state *state,
17231723
if (memcmp(h->fsid, fs_info->fs_devices->fsid, BTRFS_FSID_SIZE))
17241724
return 1;
17251725

1726+
shash->tfm = fs_info->csum_shash;
1727+
crypto_shash_init(shash);
1728+
17261729
for (i = 0; i < num_pages; i++) {
17271730
u8 *data = i ? datav[i] : (datav[i] + BTRFS_CSUM_SIZE);
17281731
size_t sublen = i ? PAGE_SIZE :
17291732
(PAGE_SIZE - BTRFS_CSUM_SIZE);
17301733

1731-
crc = btrfs_csum_data(data, crc, sublen);
1734+
crypto_shash_update(shash, data, sublen);
17321735
}
1733-
btrfs_csum_final(crc, csum);
1736+
crypto_shash_final(shash, csum);
17341737
if (memcmp(csum, h->csum, state->csum_size))
17351738
return 1;
17361739

fs/btrfs/compression.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <linux/slab.h>
1818
#include <linux/sched/mm.h>
1919
#include <linux/log2.h>
20+
#include <crypto/hash.h>
2021
#include "ctree.h"
2122
#include "disk-io.h"
2223
#include "transaction.h"
@@ -58,29 +59,33 @@ static int check_compressed_csum(struct btrfs_inode *inode,
5859
u64 disk_start)
5960
{
6061
struct btrfs_fs_info *fs_info = inode->root->fs_info;
62+
SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
6163
const u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);
6264
int ret;
6365
struct page *page;
6466
unsigned long i;
6567
char *kaddr;
66-
u32 csum;
68+
u8 csum[BTRFS_CSUM_SIZE];
6769
u8 *cb_sum = cb->sums;
6870

6971
if (inode->flags & BTRFS_INODE_NODATASUM)
7072
return 0;
7173

74+
shash->tfm = fs_info->csum_shash;
75+
7276
for (i = 0; i < cb->nr_pages; i++) {
7377
page = cb->compressed_pages[i];
74-
csum = ~(u32)0;
7578

79+
crypto_shash_init(shash);
7680
kaddr = kmap_atomic(page);
77-
csum = btrfs_csum_data(kaddr, csum, PAGE_SIZE);
78-
btrfs_csum_final(csum, (u8 *)&csum);
81+
crypto_shash_update(shash, kaddr, PAGE_SIZE);
7982
kunmap_atomic(kaddr);
83+
crypto_shash_final(shash, (u8 *)&csum);
8084

8185
if (memcmp(&csum, cb_sum, csum_size)) {
82-
btrfs_print_data_csum_error(inode, disk_start, csum,
83-
*(u32 *)cb_sum, cb->mirror_num);
86+
btrfs_print_data_csum_error(inode, disk_start,
87+
*(u32 *)csum, *(u32 *)cb_sum,
88+
cb->mirror_num);
8489
ret = -EIO;
8590
goto fail;
8691
}

fs/btrfs/disk-io.c

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -246,33 +246,28 @@ struct extent_map *btree_get_extent(struct btrfs_inode *inode,
246246
return em;
247247
}
248248

249-
u32 btrfs_csum_data(const char *data, u32 seed, size_t len)
250-
{
251-
return crc32c(seed, data, len);
252-
}
253-
254-
void btrfs_csum_final(u32 crc, u8 *result)
255-
{
256-
put_unaligned_le32(~crc, result);
257-
}
258-
259249
/*
260250
* Compute the csum of a btree block and store the result to provided buffer.
261251
*
262252
* Returns error if the extent buffer cannot be mapped.
263253
*/
264254
static int csum_tree_block(struct extent_buffer *buf, u8 *result)
265255
{
256+
struct btrfs_fs_info *fs_info = buf->fs_info;
257+
SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
266258
unsigned long len;
267259
unsigned long cur_len;
268260
unsigned long offset = BTRFS_CSUM_SIZE;
269261
char *kaddr;
270262
unsigned long map_start;
271263
unsigned long map_len;
272264
int err;
273-
u32 crc = ~(u32)0;
265+
266+
shash->tfm = fs_info->csum_shash;
267+
crypto_shash_init(shash);
274268

275269
len = buf->len - offset;
270+
276271
while (len > 0) {
277272
/*
278273
* Note: we don't need to check for the err == 1 case here, as
@@ -285,14 +280,13 @@ static int csum_tree_block(struct extent_buffer *buf, u8 *result)
285280
if (WARN_ON(err))
286281
return err;
287282
cur_len = min(len, map_len - (offset - map_start));
288-
crc = btrfs_csum_data(kaddr + offset - map_start,
289-
crc, cur_len);
283+
crypto_shash_update(shash, kaddr + offset - map_start, cur_len);
290284
len -= cur_len;
291285
offset += cur_len;
292286
}
293287
memset(result, 0, BTRFS_CSUM_SIZE);
294288

295-
btrfs_csum_final(crc, result);
289+
crypto_shash_final(shash, result);
296290

297291
return 0;
298292
}
@@ -372,17 +366,20 @@ static int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
372366
{
373367
struct btrfs_super_block *disk_sb =
374368
(struct btrfs_super_block *)raw_disk_sb;
375-
u32 crc = ~(u32)0;
376369
char result[BTRFS_CSUM_SIZE];
370+
SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
371+
372+
shash->tfm = fs_info->csum_shash;
373+
crypto_shash_init(shash);
377374

378375
/*
379376
* The super_block structure does not span the whole
380377
* BTRFS_SUPER_INFO_SIZE range, we expect that the unused space is
381378
* filled with zeros and is included in the checksum.
382379
*/
383-
crc = btrfs_csum_data(raw_disk_sb + BTRFS_CSUM_SIZE,
384-
crc, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE);
385-
btrfs_csum_final(crc, result);
380+
crypto_shash_update(shash, raw_disk_sb + BTRFS_CSUM_SIZE,
381+
BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE);
382+
crypto_shash_final(shash, result);
386383

387384
if (memcmp(disk_sb->csum, result, btrfs_super_csum_size(disk_sb)))
388385
return 1;
@@ -3512,17 +3509,20 @@ struct buffer_head *btrfs_read_dev_super(struct block_device *bdev)
35123509
static int write_dev_supers(struct btrfs_device *device,
35133510
struct btrfs_super_block *sb, int max_mirrors)
35143511
{
3512+
struct btrfs_fs_info *fs_info = device->fs_info;
3513+
SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
35153514
struct buffer_head *bh;
35163515
int i;
35173516
int ret;
35183517
int errors = 0;
3519-
u32 crc;
35203518
u64 bytenr;
35213519
int op_flags;
35223520

35233521
if (max_mirrors == 0)
35243522
max_mirrors = BTRFS_SUPER_MIRROR_MAX;
35253523

3524+
shash->tfm = fs_info->csum_shash;
3525+
35263526
for (i = 0; i < max_mirrors; i++) {
35273527
bytenr = btrfs_sb_offset(i);
35283528
if (bytenr + BTRFS_SUPER_INFO_SIZE >=
@@ -3531,10 +3531,10 @@ static int write_dev_supers(struct btrfs_device *device,
35313531

35323532
btrfs_set_super_bytenr(sb, bytenr);
35333533

3534-
crc = ~(u32)0;
3535-
crc = btrfs_csum_data((const char *)sb + BTRFS_CSUM_SIZE, crc,
3536-
BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE);
3537-
btrfs_csum_final(crc, sb->csum);
3534+
crypto_shash_init(shash);
3535+
crypto_shash_update(shash, (const char *)sb + BTRFS_CSUM_SIZE,
3536+
BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE);
3537+
crypto_shash_final(shash, sb->csum);
35383538

35393539
/* One reference for us, and we leave it for the caller */
35403540
bh = __getblk(device->bdev, bytenr / BTRFS_BDEV_BLOCKSIZE,

fs/btrfs/disk-io.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,6 @@ int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid,
115115
int atomic);
116116
int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid, int level,
117117
struct btrfs_key *first_key);
118-
u32 btrfs_csum_data(const char *data, u32 seed, size_t len);
119-
void btrfs_csum_final(u32 crc, u8 *result);
120118
blk_status_t btrfs_bio_wq_end_io(struct btrfs_fs_info *info, struct bio *bio,
121119
enum btrfs_wq_endio_type metadata);
122120
blk_status_t btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct bio *bio,

fs/btrfs/file-item.c

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <linux/pagemap.h>
99
#include <linux/highmem.h>
1010
#include <linux/sched/mm.h>
11+
#include <crypto/hash.h>
1112
#include "ctree.h"
1213
#include "disk-io.h"
1314
#include "transaction.h"
@@ -432,6 +433,7 @@ blk_status_t btrfs_csum_one_bio(struct inode *inode, struct bio *bio,
432433
u64 file_start, int contig)
433434
{
434435
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
436+
SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
435437
struct btrfs_ordered_sum *sums;
436438
struct btrfs_ordered_extent *ordered = NULL;
437439
char *data;
@@ -465,6 +467,8 @@ blk_status_t btrfs_csum_one_bio(struct inode *inode, struct bio *bio,
465467
sums->bytenr = (u64)bio->bi_iter.bi_sector << 9;
466468
index = 0;
467469

470+
shash->tfm = fs_info->csum_shash;
471+
468472
bio_for_each_segment(bvec, bio, iter) {
469473
if (!contig)
470474
offset = page_offset(bvec.bv_page) + bvec.bv_offset;
@@ -479,8 +483,6 @@ blk_status_t btrfs_csum_one_bio(struct inode *inode, struct bio *bio,
479483
- 1);
480484

481485
for (i = 0; i < nr_sectors; i++) {
482-
u32 tmp;
483-
484486
if (offset >= ordered->file_offset + ordered->len ||
485487
offset < ordered->file_offset) {
486488
unsigned long bytes_left;
@@ -506,15 +508,13 @@ blk_status_t btrfs_csum_one_bio(struct inode *inode, struct bio *bio,
506508
index = 0;
507509
}
508510

509-
memset(&sums->sums[index], 0xff, csum_size);
511+
crypto_shash_init(shash);
510512
data = kmap_atomic(bvec.bv_page);
511-
tmp = btrfs_csum_data(data + bvec.bv_offset
512-
+ (i * fs_info->sectorsize),
513-
*(u32 *)&sums->sums[index],
514-
fs_info->sectorsize);
513+
crypto_shash_update(shash, data + bvec.bv_offset
514+
+ (i * fs_info->sectorsize),
515+
fs_info->sectorsize);
515516
kunmap_atomic(data);
516-
btrfs_csum_final(tmp,
517-
(char *)(sums->sums + index));
517+
crypto_shash_final(shash, (char *)(sums->sums + index));
518518
index += csum_size;
519519
offset += fs_info->sectorsize;
520520
this_sum_bytes += fs_info->sectorsize;

fs/btrfs/inode.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3203,23 +3203,30 @@ static int __readpage_endio_check(struct inode *inode,
32033203
int icsum, struct page *page,
32043204
int pgoff, u64 start, size_t len)
32053205
{
3206+
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
3207+
SHASH_DESC_ON_STACK(shash, fs_info->csum_shash);
32063208
char *kaddr;
3207-
u32 csum_expected;
3208-
u32 csum = ~(u32)0;
3209+
u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);
3210+
u8 *csum_expected;
3211+
u8 csum[BTRFS_CSUM_SIZE];
32093212

3210-
csum_expected = *(((u32 *)io_bio->csum) + icsum);
3213+
csum_expected = ((u8 *)io_bio->csum) + icsum * csum_size;
32113214

32123215
kaddr = kmap_atomic(page);
3213-
csum = btrfs_csum_data(kaddr + pgoff, csum, len);
3214-
btrfs_csum_final(csum, (u8 *)&csum);
3215-
if (csum != csum_expected)
3216+
shash->tfm = fs_info->csum_shash;
3217+
3218+
crypto_shash_init(shash);
3219+
crypto_shash_update(shash, kaddr + pgoff, len);
3220+
crypto_shash_final(shash, csum);
3221+
3222+
if (memcmp(csum, csum_expected, csum_size))
32163223
goto zeroit;
32173224

32183225
kunmap_atomic(kaddr);
32193226
return 0;
32203227
zeroit:
3221-
btrfs_print_data_csum_error(BTRFS_I(inode), start, csum, csum_expected,
3222-
io_bio->mirror_num);
3228+
btrfs_print_data_csum_error(BTRFS_I(inode), start, *(u32 *)csum,
3229+
*(u32 *)csum_expected, io_bio->mirror_num);
32233230
memset(kaddr + pgoff, 1, len);
32243231
flush_dcache_page(page);
32253232
kunmap_atomic(kaddr);

0 commit comments

Comments
 (0)