Re: [PATCH 5/9] fscrypt: keep multiple bios in flight in fscrypt_zeroout_range_inline_crypt

Eric Biggers
2025-11-07T04:08:00Z

On Fri, Oct 31, 2025 at 10:34:35AM +0100, Christoph Hellwig wrote:
> This should slightly improve performance for large zeroing operations,
> but more importantly prepares for blk-crypto refactoring that requires
> all fscrypt users to call submit_bio directly.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> fs/crypto/bio.c | 84 +++++++++++++++++++++++++++++++------------------
> 1 file changed, 53 insertions(+), 31 deletions(-)
>
> diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c
> index 68b0424d879a..e59d342b4240 100644
> --- a/fs/crypto/bio.c
> +++ b/fs/crypto/bio.c
> @@ -47,49 +47,71 @@ bool fscrypt_decrypt_bio(struct bio *bio)
> }
> EXPORT_SYMBOL(fscrypt_decrypt_bio);
>
> +struct fscrypt_zero_done {
> + atomic_t pending;
> + blk_status_t status;
> + struct completion done;
> +};
> +
> +static void fscrypt_zeroout_range_done(struct fscrypt_zero_done *done)
> +{
> + if (atomic_dec_and_test(&done->pending))
> + complete(&done->done);
> +}
> +
> +static void fscrypt_zeroout_range_end_io(struct bio *bio)
> +{
> + struct fscrypt_zero_done *done = bio->bi_private;
> +
> + if (bio->bi_status)
> + cmpxchg(&done->status, 0, bio->bi_status);
> + fscrypt_zeroout_range_done(done);
> + bio_put(bio);
> +}
> +
> static int fscrypt_zeroout_range_inline_crypt(const struct inode *inode,
> pgoff_t lblk, sector_t sector,
> unsigned int len)
> {
> const unsigned int blockbits = inode->i_blkbits;
> const unsigned int blocks_per_page = 1 << (PAGE_SHIFT - blockbits);
> - struct bio *bio;
> - int ret, err = 0;
> - int num_pages = 0;
> + struct fscrypt_zero_done done = {};
>
> - /* This always succeeds since __GFP_DIRECT_RECLAIM is set. */
> - bio = bio_alloc(inode->i_sb->s_bdev, BIO_MAX_VECS, REQ_OP_WRITE,
> - GFP_NOFS);
> + atomic_set(&done.pending, 1);
> + init_completion(&done.done);

This could use:

struct fscrypt_zero_done done = {
.pending = ATOMIC_INIT(1),
.done = COMPLETION_INITIALIZER_ONSTACK(done.done),
};

Either way:

Reviewed-by: Eric Biggers <ebiggers@kernel.org>

- Eric