From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eric Biggers Subject: [PATCH 08/13] fscrypt: introduce fscrypt_decrypt_block_inplace() Date: Wed, 1 May 2019 15:45:10 -0700 Message-ID: <20190501224515.43059-9-ebiggers@kernel.org> References: <20190501224515.43059-1-ebiggers@kernel.org> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1hLxzX-0005Uu-98 for linux-f2fs-devel@lists.sourceforge.net; Wed, 01 May 2019 22:46:19 +0000 Received: from mail.kernel.org ([198.145.29.99]) by sfi-mx-4.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) id 1hLxzV-0025G2-W3 for linux-f2fs-devel@lists.sourceforge.net; Wed, 01 May 2019 22:46:19 +0000 In-Reply-To: <20190501224515.43059-1-ebiggers@kernel.org> List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linux-f2fs-devel-bounces@lists.sourceforge.net To: linux-fscrypt@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-ext4@vger.kernel.org, linux-mtd@lists.infradead.org, Chandan Rajendra , linux-f2fs-devel@lists.sourceforge.net From: Eric Biggers fscrypt_decrypt_page() behaves very differently depending on whether the filesystem set FS_CFLG_OWN_PAGES in its fscrypt_operations. This makes the function difficult to understand and document. It also makes it so that all callers have to provide inode and lblk_num, when fscrypt could determine these itself for pagecache pages. Therefore, move the FS_CFLG_OWN_PAGES behavior into a new function fscrypt_decrypt_block_inplace(). Signed-off-by: Eric Biggers --- fs/crypto/crypto.c | 31 +++++++++++++++++++++++++++---- fs/ubifs/crypto.c | 7 ++++--- include/linux/fscrypt.h | 11 +++++++++++ 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index 7bdb985126d97..2e6fb5e4f7a7f 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -284,8 +284,7 @@ EXPORT_SYMBOL(fscrypt_encrypt_block_inplace); /** * fscrypt_decrypt_page() - Decrypts a page in-place * @inode: The corresponding inode for the page to decrypt. - * @page: The page to decrypt. Must be locked in case - * it is a writeback page (FS_CFLG_OWN_PAGES unset). + * @page: The page to decrypt. Must be locked. * @len: Number of bytes in @page to be decrypted. * @offs: Start of data in @page. * @lblk_num: Logical block number. @@ -299,8 +298,7 @@ EXPORT_SYMBOL(fscrypt_encrypt_block_inplace); int fscrypt_decrypt_page(const struct inode *inode, struct page *page, unsigned int len, unsigned int offs, u64 lblk_num) { - if (WARN_ON_ONCE(!PageLocked(page) && - !(inode->i_sb->s_cop->flags & FS_CFLG_OWN_PAGES))) + if (WARN_ON_ONCE(!PageLocked(page))) return -EINVAL; return fscrypt_crypt_block(inode, FS_DECRYPT, lblk_num, page, page, @@ -308,6 +306,31 @@ int fscrypt_decrypt_page(const struct inode *inode, struct page *page, } EXPORT_SYMBOL(fscrypt_decrypt_page); +/** + * fscrypt_decrypt_block_inplace() - Decrypt a filesystem block in-place + * @inode: The inode to which this block belongs + * @page: The page containing the block to decrypt + * @len: Size of block to decrypt. Doesn't need to be a multiple of the + * fs block size, but must be a multiple of FS_CRYPTO_BLOCK_SIZE. + * @offs: Byte offset within @page at which the block to decrypt begins + * @lblk_num: Filesystem logical block number of the block, i.e. the 0-based + * number of the block within the file + * + * Decrypt a possibly-compressed filesystem block that is located in an + * arbitrary page, not necessarily in the original pagecache page. The @inode + * and @lblk_num must be specified, as they can't be determined from @page. + * + * Return: 0 on success; -errno on failure + */ +int fscrypt_decrypt_block_inplace(const struct inode *inode, struct page *page, + unsigned int len, unsigned int offs, + u64 lblk_num) +{ + return fscrypt_crypt_block(inode, FS_DECRYPT, lblk_num, page, page, + len, offs, GFP_NOFS); +} +EXPORT_SYMBOL(fscrypt_decrypt_block_inplace); + /* * Validate dentries in encrypted directories to make sure we aren't potentially * caching stale dentries after a key has been added. diff --git a/fs/ubifs/crypto.c b/fs/ubifs/crypto.c index 032efdad2e668..22be7aeb96c4f 100644 --- a/fs/ubifs/crypto.c +++ b/fs/ubifs/crypto.c @@ -64,10 +64,11 @@ int ubifs_decrypt(const struct inode *inode, struct ubifs_data_node *dn, } ubifs_assert(c, dlen <= UBIFS_BLOCK_SIZE); - err = fscrypt_decrypt_page(inode, virt_to_page(&dn->data), dlen, - offset_in_page(&dn->data), block); + err = fscrypt_decrypt_block_inplace(inode, virt_to_page(&dn->data), + dlen, offset_in_page(&dn->data), + block); if (err) { - ubifs_err(c, "fscrypt_decrypt_page failed: %i", err); + ubifs_err(c, "fscrypt_decrypt_block_inplace() failed: %d", err); return err; } *out_len = clen; diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index 39229fcdfac5c..f4890870ca984 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -114,6 +114,9 @@ extern int fscrypt_encrypt_block_inplace(const struct inode *inode, gfp_t gfp_flags); extern int fscrypt_decrypt_page(const struct inode *, struct page *, unsigned int, unsigned int, u64); +extern int fscrypt_decrypt_block_inplace(const struct inode *inode, + struct page *page, unsigned int len, + unsigned int offs, u64 lblk_num); static inline bool fscrypt_is_bounce_page(struct page *page) { @@ -310,6 +313,14 @@ static inline int fscrypt_decrypt_page(const struct inode *inode, return -EOPNOTSUPP; } +static inline int fscrypt_decrypt_block_inplace(const struct inode *inode, + struct page *page, + unsigned int len, + unsigned int offs, u64 lblk_num) +{ + return -EOPNOTSUPP; +} + static inline bool fscrypt_is_bounce_page(struct page *page) { return false; -- 2.21.0.593.g511ec345e18-goog