From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 58BBD3A1E67; Sun, 5 Jul 2026 19:48:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783280892; cv=none; b=nbpWZlLiq4sGu+Fzm03TKgxZ815hO9ojHCfZpnConDd6i+B7NM21SB5xEHBlVc7nAcVxuaPiG08fX1B2xTvyFfhsO42ew8msQM44zSBjVjyWNrGAGLVM1ArxqWzxEeSknRTZgsU1do+18bhXCue0rdoox3E8DctfWEwVKU2QzvA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783280892; c=relaxed/simple; bh=TQyWDqp3EVj8kEvv77n569ZFzPWNcyiYoqxYiEnYNCk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=V6eo8MeoUYNnOPEDZsedD0gKqaagH+clnR7kCbXo0FlPYkQSK6yMTJUh/s1wJ9bcQB5F2RLchdpJMHwfpNDkjILQxOo1W812j6qMoPBrz7AJqUwCIHmXp9wqCF/foO/XKLDQM2uQvoIGXFLaNkw5wzjJSOEVLagCnYDeSgajyWs= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=DzDhKMnH; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="DzDhKMnH" Received: by smtp.kernel.org (Postfix) with ESMTPSA id D0E561F00AC4; Sun, 5 Jul 2026 19:48:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1783280891; bh=MSLFNrO7YzcOapce6bl5+n1FNFmwuV69TgvzhMU3SXY=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=DzDhKMnHVrlEeEe/hSQ62dqb3eWUH9nDSlDFWXaNfiFMNQx3OQ/2quj12m7ZcfCeS 6+2opiF82sm2PA12poEAND4J+8WrSE7RHJpeas2XVFTBYC/K+y3+X7zU3+V/aqw83z gymlYPYgYwWaWzRICkiz0DkIBVEEYjM8mPwJ3IljurdR0MA7p2QPfHzz5nRhPyL1hZ RQnTI7SpaRBln+jFdP4NEwki15aKyRk/+QSWp/vd+3PIviKjxsaLBn/c3sykVLLdZZ HIADx6tqMT4bF4aooZNypecF6gCSREeiQDniNRkx5B4n9d0pXwUw5pplIiIUV8iELK RhOpA9Jq0LBwA== From: Eric Biggers To: linux-fscrypt@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-block@vger.kernel.org, Christoph Hellwig , Theodore Ts'o , Andreas Dilger , Baokun Li , Jan Kara , Ojaswin Mujoo , Ritesh Harjani , Zhang Yi , Jaegeuk Kim , Chao Yu , Eric Biggers Subject: [PATCH v2 16/17] fscrypt: Merge bio.c and inline_crypt.c into block.c Date: Sun, 5 Jul 2026 12:45:53 -0700 Message-ID: <20260705194555.75030-17-ebiggers@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260705194555.75030-1-ebiggers@kernel.org> References: <20260705194555.75030-1-ebiggers@kernel.org> Precedence: bulk X-Mailing-List: linux-ext4@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Now that fscrypt always uses blk-crypto on block-based filesystems, there's no meaningful difference between bio.c and inline_crypt.c. Therefore merge the two files into one named block.c. Note: I didn't carry over bio.c's "Copyright (C) 2015, Motorola Mobility", as none of the code that applied to remained. Reviewed-by: Christoph Hellwig Signed-off-by: Eric Biggers --- fs/crypto/Makefile | 3 +- fs/crypto/bio.c | 100 -------------------------- fs/crypto/{inline_crypt.c => block.c} | 96 +++++++++++++++++++++++-- fs/crypto/fscrypt_private.h | 2 +- include/linux/fscrypt.h | 22 +++--- 5 files changed, 101 insertions(+), 122 deletions(-) delete mode 100644 fs/crypto/bio.c rename fs/crypto/{inline_crypt.c => block.c} (79%) diff --git a/fs/crypto/Makefile b/fs/crypto/Makefile index 652c7180ec6d..b03e02f0f09d 100644 --- a/fs/crypto/Makefile +++ b/fs/crypto/Makefile @@ -10,5 +10,4 @@ fscrypto-y := crypto.o \ keysetup_v1.o \ policy.o -fscrypto-$(CONFIG_BLOCK) += bio.o -fscrypto-$(CONFIG_FS_ENCRYPTION_INLINE_CRYPT) += inline_crypt.o +fscrypto-$(CONFIG_BLOCK) += block.o diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c deleted file mode 100644 index db095258cfca..000000000000 --- a/fs/crypto/bio.c +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Utility functions for file contents encryption/decryption on - * block device-based filesystems. - * - * Copyright (C) 2015, Google, Inc. - * Copyright (C) 2015, Motorola Mobility - */ - -#include -#include -#include -#include -#include - -#include "fscrypt_private.h" - -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); -} - -/** - * fscrypt_zeroout_range() - zero out a range of blocks in an encrypted file - * @inode: the file's inode - * @pos: the first file position (in bytes) to zero out - * @sector: the first sector to zero out - * @len: bytes to zero out - * - * Zero out filesystem blocks in an encrypted regular file on-disk, i.e. write - * ciphertext blocks which decrypt to the all-zeroes block. The blocks must be - * both logically and physically contiguous. It's also assumed that the - * filesystem only uses a single block device, ->s_bdev. @len must be a - * multiple of the file system logical block size. - * - * Note that since each block uses a different IV, this involves writing a - * different ciphertext to each block; we can't simply reuse the same one. - * - * Return: 0 on success; -errno on failure. - */ -int fscrypt_zeroout_range(const struct inode *inode, loff_t pos, - sector_t sector, u64 len) -{ - struct fscrypt_zero_done done = { - .pending = ATOMIC_INIT(1), - .done = COMPLETION_INITIALIZER_ONSTACK(done.done), - }; - - if (len == 0) - return 0; - - do { - struct bio *bio; - unsigned int n; - - bio = bio_alloc(inode->i_sb->s_bdev, BIO_MAX_VECS, REQ_OP_WRITE, - GFP_NOFS); - bio->bi_iter.bi_sector = sector; - bio->bi_private = &done; - bio->bi_end_io = fscrypt_zeroout_range_end_io; - fscrypt_set_bio_crypt_ctx(bio, inode, pos, GFP_NOFS); - - for (n = 0; n < BIO_MAX_VECS; n++) { - unsigned int bytes_this_page = min(len, PAGE_SIZE); - - __bio_add_page(bio, ZERO_PAGE(0), bytes_this_page, 0); - len -= bytes_this_page; - pos += bytes_this_page; - sector += (bytes_this_page >> SECTOR_SHIFT); - if (!len || !fscrypt_mergeable_bio(bio, inode, pos)) - break; - } - - atomic_inc(&done.pending); - blk_crypto_submit_bio(bio); - } while (len); - - fscrypt_zeroout_range_done(&done); - - wait_for_completion(&done.done); - return blk_status_to_errno(done.status); -} -EXPORT_SYMBOL(fscrypt_zeroout_range); diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/block.c similarity index 79% rename from fs/crypto/inline_crypt.c rename to fs/crypto/block.c index 14c8af322c2f..059b7ecc70ea 100644 --- a/fs/crypto/inline_crypt.c +++ b/fs/crypto/block.c @@ -1,20 +1,20 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Inline encryption support for fscrypt + * File contents en/decryption on block-based filesystems * * Copyright 2019 Google LLC */ /* - * With "inline encryption", the block layer handles the decryption/encryption - * as part of the bio, instead of the filesystem doing the crypto itself via - * crypto API. See Documentation/block/inline-encryption.rst. fscrypt still - * provides the key and IV to use. + * This file implements fscrypt's file contents en/decryption using blk-crypto + * (Documentation/block/inline-encryption.rst). fscrypt assigns a bio_crypt_ctx + * with a key and IV to each bio, and the block layer does the en/decryption. + * + * This file's exported functions are called only by block-based filesystems. */ #include #include -#include #include #include #include @@ -341,3 +341,87 @@ u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, u64 nr_blocks) return min_t(u64, nr_blocks, (u64)U32_MAX + 1 - dun); } EXPORT_SYMBOL_GPL(fscrypt_limit_io_blocks); + +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); +} + +/** + * fscrypt_zeroout_range() - zero out a range of blocks in an encrypted file + * @inode: the file's inode + * @pos: the first file position (in bytes) to zero out + * @sector: the first sector to zero out + * @len: bytes to zero out + * + * Zero out filesystem blocks in an encrypted regular file on-disk, i.e. write + * ciphertext blocks which decrypt to the all-zeroes block. The blocks must be + * both logically and physically contiguous. It's also assumed that the + * filesystem only uses a single block device, ->s_bdev. @len must be a + * multiple of the file system logical block size. + * + * Note that since each block uses a different IV, this involves writing a + * different ciphertext to each block; we can't simply reuse the same one. + * + * Return: 0 on success; -errno on failure. + */ +int fscrypt_zeroout_range(const struct inode *inode, loff_t pos, + sector_t sector, u64 len) +{ + struct fscrypt_zero_done done = { + .pending = ATOMIC_INIT(1), + .done = COMPLETION_INITIALIZER_ONSTACK(done.done), + }; + + if (len == 0) + return 0; + + do { + struct bio *bio; + unsigned int n; + + bio = bio_alloc(inode->i_sb->s_bdev, BIO_MAX_VECS, REQ_OP_WRITE, + GFP_NOFS); + bio->bi_iter.bi_sector = sector; + bio->bi_private = &done; + bio->bi_end_io = fscrypt_zeroout_range_end_io; + fscrypt_set_bio_crypt_ctx(bio, inode, pos, GFP_NOFS); + + for (n = 0; n < BIO_MAX_VECS; n++) { + unsigned int bytes_this_page = min(len, PAGE_SIZE); + + __bio_add_page(bio, ZERO_PAGE(0), bytes_this_page, 0); + len -= bytes_this_page; + pos += bytes_this_page; + sector += (bytes_this_page >> SECTOR_SHIFT); + if (!len || !fscrypt_mergeable_bio(bio, inode, pos)) + break; + } + + atomic_inc(&done.pending); + blk_crypto_submit_bio(bio); + } while (len); + + fscrypt_zeroout_range_done(&done); + + wait_for_completion(&done.done); + return blk_status_to_errno(done.status); +} +EXPORT_SYMBOL(fscrypt_zeroout_range); diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h index da9040407d4a..74329e0953d1 100644 --- a/fs/crypto/fscrypt_private.h +++ b/fs/crypto/fscrypt_private.h @@ -395,7 +395,7 @@ void fscrypt_hkdf_expand(const struct hmac_sha512_key *hkdf, u8 context, const u8 *info, unsigned int infolen, u8 *okm, unsigned int okmlen); -/* inline_crypt.c */ +/* block.c */ #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT static inline bool fscrypt_using_inline_encryption(const struct fscrypt_inode_info *ci) diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index acf5b28eb9d7..52ff014aeae6 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -446,10 +446,6 @@ bool fscrypt_match_name(const struct fscrypt_name *fname, const u8 *de_name, u32 de_name_len); u64 fscrypt_fname_siphash(const struct inode *dir, const struct qstr *name); -/* bio.c */ -int fscrypt_zeroout_range(const struct inode *inode, loff_t pos, - sector_t sector, u64 len); - /* hooks.c */ int fscrypt_file_open(struct inode *inode, struct file *filp); int __fscrypt_prepare_link(struct inode *inode, struct inode *dir, @@ -737,14 +733,6 @@ static inline int fscrypt_d_revalidate(struct inode *dir, const struct qstr *nam return 1; } -/* bio.c */ - -static inline int fscrypt_zeroout_range(const struct inode *inode, loff_t pos, - sector_t sector, u64 len) -{ - return -EOPNOTSUPP; -} - /* hooks.c */ static inline int fscrypt_file_open(struct inode *inode, struct file *filp) @@ -844,7 +832,7 @@ static inline void fscrypt_set_ops(struct super_block *sb, #endif /* !CONFIG_FS_ENCRYPTION */ -/* inline_crypt.c */ +/* block.c */ #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT void fscrypt_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode, @@ -854,6 +842,8 @@ bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode, loff_t pos); u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, u64 nr_blocks); +int fscrypt_zeroout_range(const struct inode *inode, loff_t pos, + sector_t sector, u64 len); #else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */ @@ -873,6 +863,12 @@ static inline u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, { return nr_blocks; } + +static inline int fscrypt_zeroout_range(const struct inode *inode, loff_t pos, + sector_t sector, u64 len) +{ + return -EOPNOTSUPP; +} #endif /* !CONFIG_FS_ENCRYPTION_INLINE_CRYPT */ /** -- 2.54.0 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.sourceforge.net (lists.sourceforge.net [216.105.38.7]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 30184C43602 for ; Sun, 5 Jul 2026 19:48:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.sourceforge.net; s=beta; h=Content-Transfer-Encoding:Content-Type:Cc: Reply-To:From:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:Subject:MIME-Version:References:In-Reply-To: Message-ID:Date:To:Sender:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=pxsdoHMfN2Qmzszo6gx/BkGZM9XoOeFjwOQvMFAMXxw=; b=KG20j/6z+s+9WHx+PC16X+aQel EsCl5U8pY6Hz4bFNBBal0OAJjMnBbL0PGU12z8/WActcZxz5CqnCFKuV+X2TsFDwBo35HsJOqjw4f vnh1S9pvD2qO69xYrwB0Y3WpfmsSFNX1Pv7cX6s1tA2KlRtnuEoXKBiY6p0334QCuCK0=; Received: from [127.0.0.1] (helo=sfs-ml-4.v29.lw.sourceforge.com) by sfs-ml-4.v29.lw.sourceforge.com with esmtp (Exim 4.95) (envelope-from ) id 1wgSpE-0002SA-TQ; Sun, 05 Jul 2026 19:48:24 +0000 Received: from [172.30.29.66] (helo=mx.sourceforge.net) by sfs-ml-4.v29.lw.sourceforge.com with esmtps (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.95) (envelope-from ) id 1wgSpD-0002Ru-HE for linux-f2fs-devel@lists.sourceforge.net; Sun, 05 Jul 2026 19:48:23 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=Content-Transfer-Encoding:MIME-Version:References: In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=MSLFNrO7YzcOapce6bl5+n1FNFmwuV69TgvzhMU3SXY=; b=VGj0GQXjIw516FNj1v4mbumgdY t0TiUvFk8RFCQ6gbGwiYO5S71hGvS4UMB/P+6MWepyx7c9pA2/uVHep8blEytpHZg00LzMwpoiLPv jgO7O1Fe7LZ2A3AMZtsZ+xl5LSbUp/LwX86PqxlacHRrImsmlWgdDAVl9ux8nL0hQIF0=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID: Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=MSLFNrO7YzcOapce6bl5+n1FNFmwuV69TgvzhMU3SXY=; b=LyRCf/liEidpMyNmmY/RqSBZBW juHNnCXUFcKRVi6GbkMwDERfszZndweDnu2i9+ZlQKd0bXedIFB3hQ8jJBsU11NKdZmFQzN4uuhLn M1hqIqvKcdKO97coBvYiz7op0Ys41DU8NnerL8lpsp3wgZGOaWuVUnNmb3KaPQ0AWEvk=; Received: from sea.source.kernel.org ([172.234.252.31]) by sfi-mx-2.v28.lw.sourceforge.com with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.95) id 1wgSpB-0001I1-6u for linux-f2fs-devel@lists.sourceforge.net; Sun, 05 Jul 2026 19:48:23 +0000 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) by sea.source.kernel.org (Postfix) with ESMTP id 5C1A141462; Sun, 5 Jul 2026 19:48:11 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id D0E561F00AC4; Sun, 5 Jul 2026 19:48:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1783280891; bh=MSLFNrO7YzcOapce6bl5+n1FNFmwuV69TgvzhMU3SXY=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=DzDhKMnHVrlEeEe/hSQ62dqb3eWUH9nDSlDFWXaNfiFMNQx3OQ/2quj12m7ZcfCeS 6+2opiF82sm2PA12poEAND4J+8WrSE7RHJpeas2XVFTBYC/K+y3+X7zU3+V/aqw83z gymlYPYgYwWaWzRICkiz0DkIBVEEYjM8mPwJ3IljurdR0MA7p2QPfHzz5nRhPyL1hZ RQnTI7SpaRBln+jFdP4NEwki15aKyRk/+QSWp/vd+3PIviKjxsaLBn/c3sykVLLdZZ HIADx6tqMT4bF4aooZNypecF6gCSREeiQDniNRkx5B4n9d0pXwUw5pplIiIUV8iELK RhOpA9Jq0LBwA== To: linux-fscrypt@vger.kernel.org Date: Sun, 5 Jul 2026 12:45:53 -0700 Message-ID: <20260705194555.75030-17-ebiggers@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: <20260705194555.75030-1-ebiggers@kernel.org> References: <20260705194555.75030-1-ebiggers@kernel.org> MIME-Version: 1.0 X-Headers-End: 1wgSpB-0001I1-6u Subject: [f2fs-dev] [PATCH v2 16/17] fscrypt: Merge bio.c and inline_crypt.c into block.c X-BeenThere: linux-f2fs-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Eric Biggers via Linux-f2fs-devel Reply-To: Eric Biggers Cc: Ritesh Harjani , Theodore Ts'o , Zhang Yi , linux-f2fs-devel@lists.sourceforge.net, linux-block@vger.kernel.org, Andreas Dilger , Ojaswin Mujoo , Baokun Li , Jaegeuk Kim , linux-fsdevel@vger.kernel.org, Jan Kara , linux-ext4@vger.kernel.org, Christoph Hellwig , Eric Biggers Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: linux-f2fs-devel-bounces@lists.sourceforge.net Now that fscrypt always uses blk-crypto on block-based filesystems, there's no meaningful difference between bio.c and inline_crypt.c. Therefore merge the two files into one named block.c. Note: I didn't carry over bio.c's "Copyright (C) 2015, Motorola Mobility", as none of the code that applied to remained. Reviewed-by: Christoph Hellwig Signed-off-by: Eric Biggers --- fs/crypto/Makefile | 3 +- fs/crypto/bio.c | 100 -------------------------- fs/crypto/{inline_crypt.c => block.c} | 96 +++++++++++++++++++++++-- fs/crypto/fscrypt_private.h | 2 +- include/linux/fscrypt.h | 22 +++--- 5 files changed, 101 insertions(+), 122 deletions(-) delete mode 100644 fs/crypto/bio.c rename fs/crypto/{inline_crypt.c => block.c} (79%) diff --git a/fs/crypto/Makefile b/fs/crypto/Makefile index 652c7180ec6d..b03e02f0f09d 100644 --- a/fs/crypto/Makefile +++ b/fs/crypto/Makefile @@ -10,5 +10,4 @@ fscrypto-y := crypto.o \ keysetup_v1.o \ policy.o -fscrypto-$(CONFIG_BLOCK) += bio.o -fscrypto-$(CONFIG_FS_ENCRYPTION_INLINE_CRYPT) += inline_crypt.o +fscrypto-$(CONFIG_BLOCK) += block.o diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c deleted file mode 100644 index db095258cfca..000000000000 --- a/fs/crypto/bio.c +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Utility functions for file contents encryption/decryption on - * block device-based filesystems. - * - * Copyright (C) 2015, Google, Inc. - * Copyright (C) 2015, Motorola Mobility - */ - -#include -#include -#include -#include -#include - -#include "fscrypt_private.h" - -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); -} - -/** - * fscrypt_zeroout_range() - zero out a range of blocks in an encrypted file - * @inode: the file's inode - * @pos: the first file position (in bytes) to zero out - * @sector: the first sector to zero out - * @len: bytes to zero out - * - * Zero out filesystem blocks in an encrypted regular file on-disk, i.e. write - * ciphertext blocks which decrypt to the all-zeroes block. The blocks must be - * both logically and physically contiguous. It's also assumed that the - * filesystem only uses a single block device, ->s_bdev. @len must be a - * multiple of the file system logical block size. - * - * Note that since each block uses a different IV, this involves writing a - * different ciphertext to each block; we can't simply reuse the same one. - * - * Return: 0 on success; -errno on failure. - */ -int fscrypt_zeroout_range(const struct inode *inode, loff_t pos, - sector_t sector, u64 len) -{ - struct fscrypt_zero_done done = { - .pending = ATOMIC_INIT(1), - .done = COMPLETION_INITIALIZER_ONSTACK(done.done), - }; - - if (len == 0) - return 0; - - do { - struct bio *bio; - unsigned int n; - - bio = bio_alloc(inode->i_sb->s_bdev, BIO_MAX_VECS, REQ_OP_WRITE, - GFP_NOFS); - bio->bi_iter.bi_sector = sector; - bio->bi_private = &done; - bio->bi_end_io = fscrypt_zeroout_range_end_io; - fscrypt_set_bio_crypt_ctx(bio, inode, pos, GFP_NOFS); - - for (n = 0; n < BIO_MAX_VECS; n++) { - unsigned int bytes_this_page = min(len, PAGE_SIZE); - - __bio_add_page(bio, ZERO_PAGE(0), bytes_this_page, 0); - len -= bytes_this_page; - pos += bytes_this_page; - sector += (bytes_this_page >> SECTOR_SHIFT); - if (!len || !fscrypt_mergeable_bio(bio, inode, pos)) - break; - } - - atomic_inc(&done.pending); - blk_crypto_submit_bio(bio); - } while (len); - - fscrypt_zeroout_range_done(&done); - - wait_for_completion(&done.done); - return blk_status_to_errno(done.status); -} -EXPORT_SYMBOL(fscrypt_zeroout_range); diff --git a/fs/crypto/inline_crypt.c b/fs/crypto/block.c similarity index 79% rename from fs/crypto/inline_crypt.c rename to fs/crypto/block.c index 14c8af322c2f..059b7ecc70ea 100644 --- a/fs/crypto/inline_crypt.c +++ b/fs/crypto/block.c @@ -1,20 +1,20 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Inline encryption support for fscrypt + * File contents en/decryption on block-based filesystems * * Copyright 2019 Google LLC */ /* - * With "inline encryption", the block layer handles the decryption/encryption - * as part of the bio, instead of the filesystem doing the crypto itself via - * crypto API. See Documentation/block/inline-encryption.rst. fscrypt still - * provides the key and IV to use. + * This file implements fscrypt's file contents en/decryption using blk-crypto + * (Documentation/block/inline-encryption.rst). fscrypt assigns a bio_crypt_ctx + * with a key and IV to each bio, and the block layer does the en/decryption. + * + * This file's exported functions are called only by block-based filesystems. */ #include #include -#include #include #include #include @@ -341,3 +341,87 @@ u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, u64 nr_blocks) return min_t(u64, nr_blocks, (u64)U32_MAX + 1 - dun); } EXPORT_SYMBOL_GPL(fscrypt_limit_io_blocks); + +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); +} + +/** + * fscrypt_zeroout_range() - zero out a range of blocks in an encrypted file + * @inode: the file's inode + * @pos: the first file position (in bytes) to zero out + * @sector: the first sector to zero out + * @len: bytes to zero out + * + * Zero out filesystem blocks in an encrypted regular file on-disk, i.e. write + * ciphertext blocks which decrypt to the all-zeroes block. The blocks must be + * both logically and physically contiguous. It's also assumed that the + * filesystem only uses a single block device, ->s_bdev. @len must be a + * multiple of the file system logical block size. + * + * Note that since each block uses a different IV, this involves writing a + * different ciphertext to each block; we can't simply reuse the same one. + * + * Return: 0 on success; -errno on failure. + */ +int fscrypt_zeroout_range(const struct inode *inode, loff_t pos, + sector_t sector, u64 len) +{ + struct fscrypt_zero_done done = { + .pending = ATOMIC_INIT(1), + .done = COMPLETION_INITIALIZER_ONSTACK(done.done), + }; + + if (len == 0) + return 0; + + do { + struct bio *bio; + unsigned int n; + + bio = bio_alloc(inode->i_sb->s_bdev, BIO_MAX_VECS, REQ_OP_WRITE, + GFP_NOFS); + bio->bi_iter.bi_sector = sector; + bio->bi_private = &done; + bio->bi_end_io = fscrypt_zeroout_range_end_io; + fscrypt_set_bio_crypt_ctx(bio, inode, pos, GFP_NOFS); + + for (n = 0; n < BIO_MAX_VECS; n++) { + unsigned int bytes_this_page = min(len, PAGE_SIZE); + + __bio_add_page(bio, ZERO_PAGE(0), bytes_this_page, 0); + len -= bytes_this_page; + pos += bytes_this_page; + sector += (bytes_this_page >> SECTOR_SHIFT); + if (!len || !fscrypt_mergeable_bio(bio, inode, pos)) + break; + } + + atomic_inc(&done.pending); + blk_crypto_submit_bio(bio); + } while (len); + + fscrypt_zeroout_range_done(&done); + + wait_for_completion(&done.done); + return blk_status_to_errno(done.status); +} +EXPORT_SYMBOL(fscrypt_zeroout_range); diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h index da9040407d4a..74329e0953d1 100644 --- a/fs/crypto/fscrypt_private.h +++ b/fs/crypto/fscrypt_private.h @@ -395,7 +395,7 @@ void fscrypt_hkdf_expand(const struct hmac_sha512_key *hkdf, u8 context, const u8 *info, unsigned int infolen, u8 *okm, unsigned int okmlen); -/* inline_crypt.c */ +/* block.c */ #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT static inline bool fscrypt_using_inline_encryption(const struct fscrypt_inode_info *ci) diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index acf5b28eb9d7..52ff014aeae6 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -446,10 +446,6 @@ bool fscrypt_match_name(const struct fscrypt_name *fname, const u8 *de_name, u32 de_name_len); u64 fscrypt_fname_siphash(const struct inode *dir, const struct qstr *name); -/* bio.c */ -int fscrypt_zeroout_range(const struct inode *inode, loff_t pos, - sector_t sector, u64 len); - /* hooks.c */ int fscrypt_file_open(struct inode *inode, struct file *filp); int __fscrypt_prepare_link(struct inode *inode, struct inode *dir, @@ -737,14 +733,6 @@ static inline int fscrypt_d_revalidate(struct inode *dir, const struct qstr *nam return 1; } -/* bio.c */ - -static inline int fscrypt_zeroout_range(const struct inode *inode, loff_t pos, - sector_t sector, u64 len) -{ - return -EOPNOTSUPP; -} - /* hooks.c */ static inline int fscrypt_file_open(struct inode *inode, struct file *filp) @@ -844,7 +832,7 @@ static inline void fscrypt_set_ops(struct super_block *sb, #endif /* !CONFIG_FS_ENCRYPTION */ -/* inline_crypt.c */ +/* block.c */ #ifdef CONFIG_FS_ENCRYPTION_INLINE_CRYPT void fscrypt_set_bio_crypt_ctx(struct bio *bio, const struct inode *inode, @@ -854,6 +842,8 @@ bool fscrypt_mergeable_bio(struct bio *bio, const struct inode *inode, loff_t pos); u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, u64 nr_blocks); +int fscrypt_zeroout_range(const struct inode *inode, loff_t pos, + sector_t sector, u64 len); #else /* CONFIG_FS_ENCRYPTION_INLINE_CRYPT */ @@ -873,6 +863,12 @@ static inline u64 fscrypt_limit_io_blocks(const struct inode *inode, u64 lblk, { return nr_blocks; } + +static inline int fscrypt_zeroout_range(const struct inode *inode, loff_t pos, + sector_t sector, u64 len) +{ + return -EOPNOTSUPP; +} #endif /* !CONFIG_FS_ENCRYPTION_INLINE_CRYPT */ /** -- 2.54.0 _______________________________________________ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel