Re: [PATCH v4 05/46] blk-crypto: add a process bio callback

Eric Biggers
2023-12-05T04:54:04Z

On Fri, Dec 01, 2023 at 05:11:02PM -0500, Josef Bacik wrote:
> + /* Process the encrypted bio before we submit it. */
> + if (bc->bc_key->crypto_cfg.process_bio) {
> + blk_st = bc->bc_key->crypto_cfg.process_bio(src_bio, enc_bio);
> + if (blk_st != BLK_STS_OK) {
> + src_bio->bi_status = blk_st;
> + goto out_free_bounce_pages;
> + }
> + }
> +

How does this interact with the splitting that can happen at the beginning of
blk_crypto_fallback_encrypt_bio()? Won't src_bio differ from the original bio
in that case?

> + /*
> + * Process the bio first before trying to decrypt.
> + *
> + * NOTE: btrfs expects that this bio is the same that was submitted. If
> + * at any point this changes we will need to update process_bio to take
> + * f_ctx->crypt_iter in order to make sure we can iterate the pages for
> + * checksumming. We're currently saving this in our btrfs_bio, so this
> + * works, but if at any point in the future we start allocating a bounce
> + * bio or something we need to update this callback.
> + */
> + if (bc->bc_key->crypto_cfg.process_bio) {
> + blk_st = bc->bc_key->crypto_cfg.process_bio(bio, bio);
> + if (blk_st != BLK_STS_OK) {
> + bio->bi_status = blk_st;
> + goto out_no_keyslot;
> + }
> + }

The NOTE above feels a bit out of place. It doesn't make sense to use a bounce
bio for decryption, so the described concern doesn't seem too realistic.
Specific filesystems also shouldn't really be mentioned here. Maybe the comment
should just say that the contract of blk_crypto_process_bio_t requires
orig_bio == enc_bio for reads? Maybe it should be a comment on
blk_crypto_process_bio_t itself.

> +/**
> + * blk_crypto_cfg_supports_process_bio - check if this config supports
> + * process_bio
> + * @profile: the profile we're checking
> + *
> + * This is just a quick check to make sure @profile is the fallback profile, as
> + * no other offload implementations support process_bio.
> + */
> +bool blk_crypto_cfg_supports_process_bio(struct blk_crypto_profile *profile)
> +{
> + return profile == blk_crypto_fallback_profile;
> +}

How about calling this blk_crypto_profile_is_fallback()?

> diff --git a/include/linux/blk-crypto.h b/include/linux/blk-crypto.h
> index 5e5822c18ee4..194c1d727013 100644
> --- a/include/linux/blk-crypto.h
> +++ b/include/linux/blk-crypto.h
> @@ -6,7 +6,7 @@
> #ifndef __LINUX_BLK_CRYPTO_H
> #define __LINUX_BLK_CRYPTO_H
>
> -#include <linux/types.h>
> +#include <linux/blk_types.h>
>
> enum blk_crypto_mode_num {
> BLK_ENCRYPTION_MODE_INVALID,
> @@ -17,6 +17,9 @@ enum blk_crypto_mode_num {
> BLK_ENCRYPTION_MODE_MAX,
> };
>
> +typedef blk_status_t (blk_crypto_process_bio_t)(struct bio *orig_bio,
> + struct bio *enc_bio);

Usually people include a '*' in function pointer typedefs.

> +
> #define BLK_CRYPTO_MAX_KEY_SIZE 64
> /**
> * struct blk_crypto_config - an inline encryption key's crypto configuration

This kerneldoc comment is missing documentation for process_bio.

> @@ -31,6 +34,7 @@ struct blk_crypto_config {
> enum blk_crypto_mode_num crypto_mode;
> unsigned int data_unit_size;
> unsigned int dun_bytes;
> + blk_crypto_process_bio_t *process_bio;
> };

*process_bio => process_bio.

> diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h
> index 756f23fc3e83..5f5efb472fc9 100644
> --- a/include/linux/fscrypt.h
> +++ b/include/linux/fscrypt.h
> @@ -16,6 +16,7 @@
> #include <linux/fs.h>
> #include <linux/mm.h>
> #include <linux/slab.h>
> +#include <linux/blk-crypto.h>
> #include <uapi/linux/fscrypt.h>
>
> /*
> @@ -199,6 +200,19 @@ struct fscrypt_operations {
> */
> struct block_device **(*get_devices)(struct super_block *sb,
> unsigned int *num_devs);
> +
> + /*
> + * A callback if the file system requires the ability to process the
> + * encrypted bio.
> + *
> + * @orig_bio: the original bio submitted.
> + * @enc_bio: the encrypted bio.
> + *
> + * For writes the enc_bio will be different from the orig_bio, for reads
> + * they will be the same. For reads we get the bio before it is
> + * decrypted, for writes we get the bio before it is submitted.
> + */
> + blk_crypto_process_bio_t *process_bio;

Adding fscrypt support for process_bio should be a separate patch.

Also, the documentation for fscrypt_operations::process_bio should make it clear
that it only applies to inline encryption.

- Eric