X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libbcachefs%2Fchecksum.c;h=43d22fe8131b00d720ed58702da1696577027f1b;hb=1ee7dc7a55273d34358a0ee525a9e823c999ffe6;hp=317efd047a463a0f12b214b826d144671f5438dc;hpb=03ed64edc88343665ebd38eaaeebeba0229b1974;p=bcachefs-tools-debian diff --git a/libbcachefs/checksum.c b/libbcachefs/checksum.c index 317efd0..43d22fe 100644 --- a/libbcachefs/checksum.c +++ b/libbcachefs/checksum.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include "bcachefs.h" #include "checksum.h" +#include "errcode.h" #include "super.h" #include "super-io.h" @@ -114,15 +115,41 @@ static inline int do_encrypt(struct crypto_sync_skcipher *tfm, struct nonce nonce, void *buf, size_t len) { - struct scatterlist sg; - - sg_init_table(&sg, 1); - sg_set_page(&sg, - is_vmalloc_addr(buf) - ? vmalloc_to_page(buf) - : virt_to_page(buf), - len, offset_in_page(buf)); - return do_encrypt_sg(tfm, nonce, &sg, len); + if (!is_vmalloc_addr(buf)) { + struct scatterlist sg; + + sg_init_table(&sg, 1); + sg_set_page(&sg, + is_vmalloc_addr(buf) + ? vmalloc_to_page(buf) + : virt_to_page(buf), + len, offset_in_page(buf)); + return do_encrypt_sg(tfm, nonce, &sg, len); + } else { + unsigned pages = buf_pages(buf, len); + struct scatterlist *sg; + size_t orig_len = len; + int ret, i; + + sg = kmalloc_array(pages, sizeof(*sg), GFP_KERNEL); + if (!sg) + return -ENOMEM; + + sg_init_table(sg, pages); + + for (i = 0; i < pages; i++) { + unsigned offset = offset_in_page(buf); + unsigned pg_len = min(len, PAGE_SIZE - offset); + + sg_set_page(sg + i, vmalloc_to_page(buf), pg_len, offset); + buf += pg_len; + len -= pg_len; + } + + ret = do_encrypt_sg(tfm, nonce, sg, orig_len); + kfree(sg); + return ret; + } } int bch2_chacha_encrypt_key(struct bch_key *key, struct nonce nonce, @@ -289,7 +316,7 @@ struct bch_csum bch2_checksum_bio(struct bch_fs *c, unsigned type, return __bch2_checksum_bio(c, type, nonce, bio, &iter); } -int bch2_encrypt_bio(struct bch_fs *c, unsigned type, +int __bch2_encrypt_bio(struct bch_fs *c, unsigned type, struct nonce nonce, struct bio *bio) { struct bio_vec bv; @@ -399,8 +426,17 @@ int bch2_rechecksum_bio(struct bch_fs *c, struct bio *bio, merged = bch2_checksum_bio(c, crc_old.csum_type, extent_nonce(version, crc_old), bio); - if (bch2_crc_cmp(merged, crc_old.csum)) + if (bch2_crc_cmp(merged, crc_old.csum)) { + bch_err(c, "checksum error in bch2_rechecksum_bio() (memory corruption or bug?)\n" + "expected %0llx:%0llx got %0llx:%0llx (old type %s new type %s)", + crc_old.csum.hi, + crc_old.csum.lo, + merged.hi, + merged.lo, + bch2_csum_types[crc_old.csum_type], + bch2_csum_types[new_csum_type]); return -EIO; + } for (i = splits; i < splits + ARRAY_SIZE(splits); i++) { if (i->crc) @@ -467,13 +503,15 @@ static int __bch2_request_key(char *key_description, struct bch_key *key) int bch2_request_key(struct bch_sb *sb, struct bch_key *key) { - char key_description[60]; - char uuid[40]; + struct printbuf key_description = PRINTBUF; + int ret; - uuid_unparse_lower(sb->user_uuid.b, uuid); - sprintf(key_description, "bcachefs:%s", uuid); + prt_printf(&key_description, "bcachefs:"); + pr_uuid(&key_description, sb->user_uuid.b); - return __bch2_request_key(key_description, key); + ret = __bch2_request_key(key_description.buf, key); + printbuf_exit(&key_description); + return ret; } int bch2_decrypt_sb_key(struct bch_fs *c, @@ -490,7 +528,7 @@ int bch2_decrypt_sb_key(struct bch_fs *c, ret = bch2_request_key(c->disk_sb.sb, &user_key); if (ret) { - bch_err(c, "error requesting encryption key: %i", ret); + bch_err(c, "error requesting encryption key: %s", bch2_err_str(ret)); goto err; } @@ -515,20 +553,24 @@ err: static int bch2_alloc_ciphers(struct bch_fs *c) { + int ret; + if (!c->chacha20) c->chacha20 = crypto_alloc_sync_skcipher("chacha20", 0, 0); - if (IS_ERR(c->chacha20)) { - bch_err(c, "error requesting chacha20 module: %li", - PTR_ERR(c->chacha20)); - return PTR_ERR(c->chacha20); + ret = PTR_ERR_OR_ZERO(c->chacha20); + + if (ret) { + bch_err(c, "error requesting chacha20 module: %s", bch2_err_str(ret)); + return ret; } if (!c->poly1305) c->poly1305 = crypto_alloc_shash("poly1305", 0, 0); - if (IS_ERR(c->poly1305)) { - bch_err(c, "error requesting poly1305 module: %li", - PTR_ERR(c->poly1305)); - return PTR_ERR(c->poly1305); + ret = PTR_ERR_OR_ZERO(c->poly1305); + + if (ret) { + bch_err(c, "error requesting poly1305 module: %s", bch2_err_str(ret)); + return ret; } return 0; @@ -589,7 +631,7 @@ int bch2_enable_encryption(struct bch_fs *c, bool keyed) if (keyed) { ret = bch2_request_key(c->disk_sb.sb, &user_key); if (ret) { - bch_err(c, "error requesting encryption key: %i", ret); + bch_err(c, "error requesting encryption key: %s", bch2_err_str(ret)); goto err; } @@ -641,9 +683,9 @@ int bch2_fs_encryption_init(struct bch_fs *c) pr_verbose_init(c->opts, ""); c->sha256 = crypto_alloc_shash("sha256", 0, 0); - if (IS_ERR(c->sha256)) { - bch_err(c, "error requesting sha256 module"); - ret = PTR_ERR(c->sha256); + ret = PTR_ERR_OR_ZERO(c->sha256); + if (ret) { + bch_err(c, "error requesting sha256 module: %s", bch2_err_str(ret)); goto out; }