From patchwork Mon May 20 16:29:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 10951829 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8435316C1 for ; Mon, 20 May 2019 16:30:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 70CAC28704 for ; Mon, 20 May 2019 16:30:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 654AC28806; Mon, 20 May 2019 16:30:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, SUSPICIOUS_RECIPS autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3A2D82881B for ; Mon, 20 May 2019 16:30:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389638AbfETQaX (ORCPT ); Mon, 20 May 2019 12:30:23 -0400 Received: from mail.kernel.org ([198.145.29.99]:44880 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388956AbfETQaW (ORCPT ); Mon, 20 May 2019 12:30:22 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 1E89821479; Mon, 20 May 2019 16:30:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1558369821; bh=vPp+Zs7yN+33HNpsKkMC72PspxyOFK4Pkx8euK8UIMU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=c3GRVKCKj12MZpgIkI4ZGkM+bVCN8J93vN18xLutGrmYUIf5M/r/AgVIS3ngdXCrC aSicLlf5d2+4KuNdHMFvNmksuTBgTladrXFsmv0WIwtGI3JgsuRCSpbaGpGLVGDzCz jLbfSWyLfjOJJLPZ1OyUMdzqMGVWaMi2aV02e53Y= From: Eric Biggers To: linux-fscrypt@vger.kernel.org Cc: linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-mtd@lists.infradead.org, Chandan Rajendra Subject: [PATCH v2 01/14] fscrypt: simplify bounce page handling Date: Mon, 20 May 2019 09:29:39 -0700 Message-Id: <20190520162952.156212-2-ebiggers@kernel.org> X-Mailer: git-send-email 2.21.0.1020.gf2820cf01a-goog In-Reply-To: <20190520162952.156212-1-ebiggers@kernel.org> References: <20190520162952.156212-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Eric Biggers Currently, bounce page handling for writes to encrypted files is unnecessarily complicated. A fscrypt_ctx is allocated along with each bounce page, page_private(bounce_page) points to this fscrypt_ctx, and fscrypt_ctx::w::control_page points to the original pagecache page. However, because writes don't use the fscrypt_ctx for anything else, there's no reason why page_private(bounce_page) can't just point to the original pagecache page directly. Therefore, this patch makes this change. In the process, it also cleans up the API exposed to filesystems that allows testing whether a page is a bounce page, getting the pagecache page from a bounce page, and freeing a bounce page. Reviewed-by: Chandan Rajendra Signed-off-by: Eric Biggers --- fs/crypto/bio.c | 38 ++----------- fs/crypto/crypto.c | 104 ++++++++++++------------------------ fs/crypto/fscrypt_private.h | 4 +- fs/ext4/page-io.c | 36 +++++-------- fs/f2fs/data.c | 12 ++--- include/linux/fscrypt.h | 38 ++++++++----- 6 files changed, 84 insertions(+), 148 deletions(-) diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c index b46021ebde856..c857b70b5328c 100644 --- a/fs/crypto/bio.c +++ b/fs/crypto/bio.c @@ -70,46 +70,18 @@ void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx, struct bio *bio) } EXPORT_SYMBOL(fscrypt_enqueue_decrypt_bio); -void fscrypt_pullback_bio_page(struct page **page, bool restore) -{ - struct fscrypt_ctx *ctx; - struct page *bounce_page; - - /* The bounce data pages are unmapped. */ - if ((*page)->mapping) - return; - - /* The bounce data page is unmapped. */ - bounce_page = *page; - ctx = (struct fscrypt_ctx *)page_private(bounce_page); - - /* restore control page */ - *page = ctx->w.control_page; - - if (restore) - fscrypt_restore_control_page(bounce_page); -} -EXPORT_SYMBOL(fscrypt_pullback_bio_page); - int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, sector_t pblk, unsigned int len) { - struct fscrypt_ctx *ctx; - struct page *ciphertext_page = NULL; + struct page *ciphertext_page; struct bio *bio; int ret, err = 0; BUG_ON(inode->i_sb->s_blocksize != PAGE_SIZE); - ctx = fscrypt_get_ctx(GFP_NOFS); - if (IS_ERR(ctx)) - return PTR_ERR(ctx); - - ciphertext_page = fscrypt_alloc_bounce_page(ctx, GFP_NOWAIT); - if (IS_ERR(ciphertext_page)) { - err = PTR_ERR(ciphertext_page); - goto errout; - } + ciphertext_page = fscrypt_alloc_bounce_page(GFP_NOWAIT); + if (!ciphertext_page) + return -ENOMEM; while (len--) { err = fscrypt_do_page_crypto(inode, FS_ENCRYPT, lblk, @@ -147,7 +119,7 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, } err = 0; errout: - fscrypt_release_ctx(ctx); + fscrypt_free_bounce_page(ciphertext_page); return err; } EXPORT_SYMBOL(fscrypt_zeroout_range); diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index 68e2ca4c4af63..4b076f8daab75 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -63,18 +63,11 @@ EXPORT_SYMBOL(fscrypt_enqueue_decrypt_work); * * If the encryption context was allocated from the pre-allocated pool, returns * it to that pool. Else, frees it. - * - * If there's a bounce page in the context, this frees that. */ void fscrypt_release_ctx(struct fscrypt_ctx *ctx) { unsigned long flags; - if (ctx->flags & FS_CTX_HAS_BOUNCE_BUFFER_FL && ctx->w.bounce_page) { - mempool_free(ctx->w.bounce_page, fscrypt_bounce_page_pool); - ctx->w.bounce_page = NULL; - } - ctx->w.control_page = NULL; if (ctx->flags & FS_CTX_REQUIRES_FREE_ENCRYPT_FL) { kmem_cache_free(fscrypt_ctx_cachep, ctx); } else { @@ -99,14 +92,8 @@ struct fscrypt_ctx *fscrypt_get_ctx(gfp_t gfp_flags) unsigned long flags; /* - * We first try getting the ctx from a free list because in - * the common case the ctx will have an allocated and - * initialized crypto tfm, so it's probably a worthwhile - * optimization. For the bounce page, we first try getting it - * from the kernel allocator because that's just about as fast - * as getting it from a list and because a cache of free pages - * should generally be a "last resort" option for a filesystem - * to be able to do its job. + * First try getting a ctx from the free list so that we don't have to + * call into the slab allocator. */ spin_lock_irqsave(&fscrypt_ctx_lock, flags); ctx = list_first_entry_or_null(&fscrypt_free_ctxs, @@ -122,11 +109,31 @@ struct fscrypt_ctx *fscrypt_get_ctx(gfp_t gfp_flags) } else { ctx->flags &= ~FS_CTX_REQUIRES_FREE_ENCRYPT_FL; } - ctx->flags &= ~FS_CTX_HAS_BOUNCE_BUFFER_FL; return ctx; } EXPORT_SYMBOL(fscrypt_get_ctx); +struct page *fscrypt_alloc_bounce_page(gfp_t gfp_flags) +{ + return mempool_alloc(fscrypt_bounce_page_pool, gfp_flags); +} + +/** + * fscrypt_free_bounce_page() - free a ciphertext bounce page + * + * Free a bounce page that was allocated by fscrypt_encrypt_page(), or by + * fscrypt_alloc_bounce_page() directly. + */ +void fscrypt_free_bounce_page(struct page *bounce_page) +{ + if (!bounce_page) + return; + set_page_private(bounce_page, (unsigned long)NULL); + ClearPagePrivate(bounce_page); + mempool_free(bounce_page, fscrypt_bounce_page_pool); +} +EXPORT_SYMBOL(fscrypt_free_bounce_page); + void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num, const struct fscrypt_info *ci) { @@ -185,16 +192,6 @@ int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw, return 0; } -struct page *fscrypt_alloc_bounce_page(struct fscrypt_ctx *ctx, - gfp_t gfp_flags) -{ - ctx->w.bounce_page = mempool_alloc(fscrypt_bounce_page_pool, gfp_flags); - if (ctx->w.bounce_page == NULL) - return ERR_PTR(-ENOMEM); - ctx->flags |= FS_CTX_HAS_BOUNCE_BUFFER_FL; - return ctx->w.bounce_page; -} - /** * fscypt_encrypt_page() - Encrypts a page * @inode: The inode for which the encryption should take place @@ -209,22 +206,12 @@ struct page *fscrypt_alloc_bounce_page(struct fscrypt_ctx *ctx, * previously written data. * @gfp_flags: The gfp flag for memory allocation * - * Encrypts @page using the ctx encryption context. Performs encryption - * either in-place or into a newly allocated bounce page. - * Called on the page write path. - * - * Bounce page allocation is the default. - * In this case, the contents of @page are encrypted and stored in an - * allocated bounce page. @page has to be locked and the caller must call - * fscrypt_restore_control_page() on the returned ciphertext page to - * release the bounce buffer and the encryption context. - * - * In-place encryption is used by setting the FS_CFLG_OWN_PAGES flag in - * fscrypt_operations. Here, the input-page is returned with its content - * encrypted. + * Encrypts @page. If the filesystem set FS_CFLG_OWN_PAGES, then the data is + * encrypted in-place and @page is returned. Else, a bounce page is allocated, + * the data is encrypted into the bounce page, and the bounce page is returned. + * The caller is responsible for calling fscrypt_free_bounce_page(). * - * Return: A page with the encrypted content on success. Else, an - * error value or NULL. + * Return: A page containing the encrypted data on success, else an ERR_PTR() */ struct page *fscrypt_encrypt_page(const struct inode *inode, struct page *page, @@ -233,7 +220,6 @@ struct page *fscrypt_encrypt_page(const struct inode *inode, u64 lblk_num, gfp_t gfp_flags) { - struct fscrypt_ctx *ctx; struct page *ciphertext_page = page; int err; @@ -252,30 +238,20 @@ struct page *fscrypt_encrypt_page(const struct inode *inode, BUG_ON(!PageLocked(page)); - ctx = fscrypt_get_ctx(gfp_flags); - if (IS_ERR(ctx)) - return ERR_CAST(ctx); - /* The encryption operation will require a bounce page. */ - ciphertext_page = fscrypt_alloc_bounce_page(ctx, gfp_flags); - if (IS_ERR(ciphertext_page)) - goto errout; + ciphertext_page = fscrypt_alloc_bounce_page(gfp_flags); + if (!ciphertext_page) + return ERR_PTR(-ENOMEM); - ctx->w.control_page = page; err = fscrypt_do_page_crypto(inode, FS_ENCRYPT, lblk_num, page, ciphertext_page, len, offs, gfp_flags); if (err) { - ciphertext_page = ERR_PTR(err); - goto errout; + fscrypt_free_bounce_page(ciphertext_page); + return ERR_PTR(err); } SetPagePrivate(ciphertext_page); - set_page_private(ciphertext_page, (unsigned long)ctx); - lock_page(ciphertext_page); - return ciphertext_page; - -errout: - fscrypt_release_ctx(ctx); + set_page_private(ciphertext_page, (unsigned long)page); return ciphertext_page; } EXPORT_SYMBOL(fscrypt_encrypt_page); @@ -354,18 +330,6 @@ const struct dentry_operations fscrypt_d_ops = { .d_revalidate = fscrypt_d_revalidate, }; -void fscrypt_restore_control_page(struct page *page) -{ - struct fscrypt_ctx *ctx; - - ctx = (struct fscrypt_ctx *)page_private(page); - set_page_private(page, (unsigned long)NULL); - ClearPagePrivate(page); - unlock_page(page); - fscrypt_release_ctx(ctx); -} -EXPORT_SYMBOL(fscrypt_restore_control_page); - static void fscrypt_destroy(void) { struct fscrypt_ctx *pos, *n; diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h index 7da2761595933..4122ee1a0b7b1 100644 --- a/fs/crypto/fscrypt_private.h +++ b/fs/crypto/fscrypt_private.h @@ -94,7 +94,6 @@ typedef enum { } fscrypt_direction_t; #define FS_CTX_REQUIRES_FREE_ENCRYPT_FL 0x00000001 -#define FS_CTX_HAS_BOUNCE_BUFFER_FL 0x00000002 static inline bool fscrypt_valid_enc_modes(u32 contents_mode, u32 filenames_mode) @@ -123,8 +122,7 @@ extern int fscrypt_do_page_crypto(const struct inode *inode, struct page *dest_page, unsigned int len, unsigned int offs, gfp_t gfp_flags); -extern struct page *fscrypt_alloc_bounce_page(struct fscrypt_ctx *ctx, - gfp_t gfp_flags); +extern struct page *fscrypt_alloc_bounce_page(gfp_t gfp_flags); extern const struct dentry_operations fscrypt_d_ops; extern void __printf(3, 4) __cold diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 4690618a92e93..13d5ecc0af03f 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c @@ -66,9 +66,7 @@ static void ext4_finish_bio(struct bio *bio) bio_for_each_segment_all(bvec, bio, iter_all) { struct page *page = bvec->bv_page; -#ifdef CONFIG_FS_ENCRYPTION - struct page *data_page = NULL; -#endif + struct page *bounce_page = NULL; struct buffer_head *bh, *head; unsigned bio_start = bvec->bv_offset; unsigned bio_end = bio_start + bvec->bv_len; @@ -78,13 +76,10 @@ static void ext4_finish_bio(struct bio *bio) if (!page) continue; -#ifdef CONFIG_FS_ENCRYPTION - if (!page->mapping) { - /* The bounce data pages are unmapped. */ - data_page = page; - fscrypt_pullback_bio_page(&page, false); + if (fscrypt_is_bounce_page(page)) { + bounce_page = page; + page = fscrypt_pagecache_page(bounce_page); } -#endif if (bio->bi_status) { SetPageError(page); @@ -111,10 +106,7 @@ static void ext4_finish_bio(struct bio *bio) bit_spin_unlock(BH_Uptodate_Lock, &head->b_state); local_irq_restore(flags); if (!under_io) { -#ifdef CONFIG_FS_ENCRYPTION - if (data_page) - fscrypt_restore_control_page(data_page); -#endif + fscrypt_free_bounce_page(bounce_page); end_page_writeback(page); } } @@ -415,7 +407,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io, struct writeback_control *wbc, bool keep_towrite) { - struct page *data_page = NULL; + struct page *bounce_page = NULL; struct inode *inode = page->mapping->host; unsigned block_start; struct buffer_head *bh, *head; @@ -479,10 +471,10 @@ int ext4_bio_write_page(struct ext4_io_submit *io, gfp_t gfp_flags = GFP_NOFS; retry_encrypt: - data_page = fscrypt_encrypt_page(inode, page, PAGE_SIZE, 0, - page->index, gfp_flags); - if (IS_ERR(data_page)) { - ret = PTR_ERR(data_page); + bounce_page = fscrypt_encrypt_page(inode, page, PAGE_SIZE, 0, + page->index, gfp_flags); + if (IS_ERR(bounce_page)) { + ret = PTR_ERR(bounce_page); if (ret == -ENOMEM && wbc->sync_mode == WB_SYNC_ALL) { if (io->io_bio) { ext4_io_submit(io); @@ -491,7 +483,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io, gfp_flags |= __GFP_NOFAIL; goto retry_encrypt; } - data_page = NULL; + bounce_page = NULL; goto out; } } @@ -500,8 +492,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io, do { if (!buffer_async_write(bh)) continue; - ret = io_submit_add_bh(io, inode, - data_page ? data_page : page, bh); + ret = io_submit_add_bh(io, inode, bounce_page ?: page, bh); if (ret) { /* * We only get here on ENOMEM. Not much else @@ -517,8 +508,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io, /* Error stopped previous loop? Clean up buffers... */ if (ret) { out: - if (data_page) - fscrypt_restore_control_page(data_page); + fscrypt_free_bounce_page(bounce_page); printk_ratelimited(KERN_ERR "%s: ret = %d\n", __func__, ret); redirty_page_for_writepage(wbc, page); do { diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index eda4181d20926..968ebdbcb5834 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -185,7 +185,7 @@ static void f2fs_write_end_io(struct bio *bio) continue; } - fscrypt_pullback_bio_page(&page, true); + fscrypt_finalize_bounce_page(&page); if (unlikely(bio->bi_status)) { mapping_set_error(page->mapping, -EIO); @@ -362,10 +362,9 @@ static bool __has_merged_page(struct f2fs_bio_info *io, struct inode *inode, bio_for_each_segment_all(bvec, io->bio, iter_all) { - if (bvec->bv_page->mapping) - target = bvec->bv_page; - else - target = fscrypt_control_page(bvec->bv_page); + target = bvec->bv_page; + if (fscrypt_is_bounce_page(target)) + target = fscrypt_pagecache_page(target); if (inode && inode == target->mapping->host) return true; @@ -1900,8 +1899,7 @@ int f2fs_do_write_data_page(struct f2fs_io_info *fio) err = f2fs_inplace_write_data(fio); if (err) { if (f2fs_encrypted_file(inode)) - fscrypt_pullback_bio_page(&fio->encrypted_page, - true); + fscrypt_finalize_bounce_page(&fio->encrypted_page); if (PageWriteback(page)) end_page_writeback(page); } else { diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index f7680ef1abd2d..d016fa384d607 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -112,12 +112,17 @@ extern struct page *fscrypt_encrypt_page(const struct inode *, struct page *, extern int fscrypt_decrypt_page(const struct inode *, struct page *, unsigned int, unsigned int, u64); -static inline struct page *fscrypt_control_page(struct page *page) +static inline bool fscrypt_is_bounce_page(struct page *page) { - return ((struct fscrypt_ctx *)page_private(page))->w.control_page; + return page->mapping == NULL; } -extern void fscrypt_restore_control_page(struct page *); +static inline struct page *fscrypt_pagecache_page(struct page *bounce_page) +{ + return (struct page *)page_private(bounce_page); +} + +extern void fscrypt_free_bounce_page(struct page *bounce_page); /* policy.c */ extern int fscrypt_ioctl_set_policy(struct file *, const void __user *); @@ -223,7 +228,6 @@ static inline bool fscrypt_match_name(const struct fscrypt_name *fname, extern void fscrypt_decrypt_bio(struct bio *); extern void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx, struct bio *bio); -extern void fscrypt_pullback_bio_page(struct page **, bool); extern int fscrypt_zeroout_range(const struct inode *, pgoff_t, sector_t, unsigned int); @@ -300,15 +304,19 @@ static inline int fscrypt_decrypt_page(const struct inode *inode, return -EOPNOTSUPP; } -static inline struct page *fscrypt_control_page(struct page *page) +static inline bool fscrypt_is_bounce_page(struct page *page) +{ + return false; +} + +static inline struct page *fscrypt_pagecache_page(struct page *bounce_page) { WARN_ON_ONCE(1); return ERR_PTR(-EINVAL); } -static inline void fscrypt_restore_control_page(struct page *page) +static inline void fscrypt_free_bounce_page(struct page *bounce_page) { - return; } /* policy.c */ @@ -410,11 +418,6 @@ static inline void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx, { } -static inline void fscrypt_pullback_bio_page(struct page **page, bool restore) -{ - return; -} - static inline int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, sector_t pblk, unsigned int len) { @@ -692,4 +695,15 @@ static inline int fscrypt_encrypt_symlink(struct inode *inode, return 0; } +/* If *pagep is a bounce page, free it and set *pagep to the pagecache page */ +static inline void fscrypt_finalize_bounce_page(struct page **pagep) +{ + struct page *page = *pagep; + + if (fscrypt_is_bounce_page(page)) { + *pagep = fscrypt_pagecache_page(page); + fscrypt_free_bounce_page(page); + } +} + #endif /* _LINUX_FSCRYPT_H */ From patchwork Mon May 20 16:29:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 10951825 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 45E311390 for ; Mon, 20 May 2019 16:30:23 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 350E228704 for ; Mon, 20 May 2019 16:30:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 28A0728806; Mon, 20 May 2019 16:30:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, SUSPICIOUS_RECIPS autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B3B202880B for ; Mon, 20 May 2019 16:30:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389627AbfETQaW (ORCPT ); Mon, 20 May 2019 12:30:22 -0400 Received: from mail.kernel.org ([198.145.29.99]:44892 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2388958AbfETQaW (ORCPT ); Mon, 20 May 2019 12:30:22 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 76B6A21721; Mon, 20 May 2019 16:30:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1558369821; bh=XtXrJbffquLpHwtOpoiOVw/HH3tmVMU+GtpKaJDAspg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GHW4B9x7m3ZWBkOgpMwb5OP/nzyIPNmPuX/CqDCRwzqahKES9jD0BvdK2Qn1Rnhei fZhojbcoezA7K8IDMn3+ZvDpLoPcEGTgklnC5mhnC/QmVqknQ9TdAZ6YtZ8+60tvLc 0MzpUgCuqHIU7JDRfKRayIfjS1I9Cn2o6KNn9L7w= From: Eric Biggers To: linux-fscrypt@vger.kernel.org Cc: linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-mtd@lists.infradead.org, Chandan Rajendra Subject: [PATCH v2 02/14] fscrypt: remove the "write" part of struct fscrypt_ctx Date: Mon, 20 May 2019 09:29:40 -0700 Message-Id: <20190520162952.156212-3-ebiggers@kernel.org> X-Mailer: git-send-email 2.21.0.1020.gf2820cf01a-goog In-Reply-To: <20190520162952.156212-1-ebiggers@kernel.org> References: <20190520162952.156212-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Eric Biggers Now that fscrypt_ctx is not used for writes, remove the 'w' fields. Reviewed-by: Chandan Rajendra Signed-off-by: Eric Biggers --- fs/crypto/bio.c | 11 +++++------ fs/crypto/crypto.c | 14 +++++++------- include/linux/fscrypt.h | 7 ++----- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c index c857b70b5328c..c534253483874 100644 --- a/fs/crypto/bio.c +++ b/fs/crypto/bio.c @@ -53,9 +53,8 @@ EXPORT_SYMBOL(fscrypt_decrypt_bio); static void completion_pages(struct work_struct *work) { - struct fscrypt_ctx *ctx = - container_of(work, struct fscrypt_ctx, r.work); - struct bio *bio = ctx->r.bio; + struct fscrypt_ctx *ctx = container_of(work, struct fscrypt_ctx, work); + struct bio *bio = ctx->bio; __fscrypt_decrypt_bio(bio, true); fscrypt_release_ctx(ctx); @@ -64,9 +63,9 @@ static void completion_pages(struct work_struct *work) void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx, struct bio *bio) { - INIT_WORK(&ctx->r.work, completion_pages); - ctx->r.bio = bio; - fscrypt_enqueue_decrypt_work(&ctx->r.work); + INIT_WORK(&ctx->work, completion_pages); + ctx->bio = bio; + fscrypt_enqueue_decrypt_work(&ctx->work); } EXPORT_SYMBOL(fscrypt_enqueue_decrypt_bio); diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index 4b076f8daab75..ebfa13cfecb7d 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -58,11 +58,11 @@ void fscrypt_enqueue_decrypt_work(struct work_struct *work) EXPORT_SYMBOL(fscrypt_enqueue_decrypt_work); /** - * fscrypt_release_ctx() - Releases an encryption context - * @ctx: The encryption context to release. + * fscrypt_release_ctx() - Release a decryption context + * @ctx: The decryption context to release. * - * If the encryption context was allocated from the pre-allocated pool, returns - * it to that pool. Else, frees it. + * If the decryption context was allocated from the pre-allocated pool, return + * it to that pool. Else, free it. */ void fscrypt_release_ctx(struct fscrypt_ctx *ctx) { @@ -79,12 +79,12 @@ void fscrypt_release_ctx(struct fscrypt_ctx *ctx) EXPORT_SYMBOL(fscrypt_release_ctx); /** - * fscrypt_get_ctx() - Gets an encryption context + * fscrypt_get_ctx() - Get a decryption context * @gfp_flags: The gfp flag for memory allocation * - * Allocates and initializes an encryption context. + * Allocate and initialize a decryption context. * - * Return: A new encryption context on success; an ERR_PTR() otherwise. + * Return: A new decryption context on success; an ERR_PTR() otherwise. */ struct fscrypt_ctx *fscrypt_get_ctx(gfp_t gfp_flags) { diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index d016fa384d607..1c7287f146a98 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -63,16 +63,13 @@ struct fscrypt_operations { unsigned int max_namelen; }; +/* Decryption work */ struct fscrypt_ctx { union { - struct { - struct page *bounce_page; /* Ciphertext page */ - struct page *control_page; /* Original page */ - } w; struct { struct bio *bio; struct work_struct work; - } r; + }; struct list_head free_list; /* Free list */ }; u8 flags; /* Flags */ From patchwork Mon May 20 16:29:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 10951827 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0C32376 for ; Mon, 20 May 2019 16:30:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EF6D228704 for ; Mon, 20 May 2019 16:30:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E45232880B; Mon, 20 May 2019 16:30:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, SUSPICIOUS_RECIPS autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 794A028704 for ; Mon, 20 May 2019 16:30:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388956AbfETQaX (ORCPT ); Mon, 20 May 2019 12:30:23 -0400 Received: from mail.kernel.org ([198.145.29.99]:44894 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730795AbfETQaW (ORCPT ); Mon, 20 May 2019 12:30:22 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C7F352173B; Mon, 20 May 2019 16:30:21 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1558369822; bh=SOcJbbqhRxdEFcK2jyoo821iyc6Vy9fOspmpjn/YoXU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hn9O1LhVuFFUT6+gwic7GUq8fqtk7NLzwu97zIhC4CeEhGyFFm6ycdbEusitDGwKS rYTkbj78aIizPi1kdSZbf+s17paPdWO2K3HLebLco/XyWwkGlZVPEN1UCgLIeclM5A PiDcirluP255kpj8n6TkIJmxTTLJWTWYtgyZWceE= From: Eric Biggers To: linux-fscrypt@vger.kernel.org Cc: linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-mtd@lists.infradead.org, Chandan Rajendra Subject: [PATCH v2 03/14] fscrypt: rename fscrypt_do_page_crypto() to fscrypt_crypt_block() Date: Mon, 20 May 2019 09:29:41 -0700 Message-Id: <20190520162952.156212-4-ebiggers@kernel.org> X-Mailer: git-send-email 2.21.0.1020.gf2820cf01a-goog In-Reply-To: <20190520162952.156212-1-ebiggers@kernel.org> References: <20190520162952.156212-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Eric Biggers fscrypt_do_page_crypto() only does a single encryption or decryption operation, with a single logical block number (single IV). So it actually operates on a filesystem block, not a "page" per se. To reflect this, rename it to fscrypt_crypt_block(). Reviewed-by: Chandan Rajendra Signed-off-by: Eric Biggers --- fs/crypto/bio.c | 6 +++--- fs/crypto/crypto.c | 24 ++++++++++++------------ fs/crypto/fscrypt_private.h | 11 +++++------ 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c index c534253483874..92b2d5da5d8e1 100644 --- a/fs/crypto/bio.c +++ b/fs/crypto/bio.c @@ -83,9 +83,9 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, return -ENOMEM; while (len--) { - err = fscrypt_do_page_crypto(inode, FS_ENCRYPT, lblk, - ZERO_PAGE(0), ciphertext_page, - PAGE_SIZE, 0, GFP_NOFS); + err = fscrypt_crypt_block(inode, FS_ENCRYPT, lblk, + ZERO_PAGE(0), ciphertext_page, + PAGE_SIZE, 0, GFP_NOFS); if (err) goto errout; diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index ebfa13cfecb7d..e6802d7aca3c7 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -147,10 +147,11 @@ void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num, crypto_cipher_encrypt_one(ci->ci_essiv_tfm, iv->raw, iv->raw); } -int fscrypt_do_page_crypto(const struct inode *inode, fscrypt_direction_t rw, - u64 lblk_num, struct page *src_page, - struct page *dest_page, unsigned int len, - unsigned int offs, gfp_t gfp_flags) +/* Encrypt or decrypt a single filesystem block of file contents */ +int fscrypt_crypt_block(const struct inode *inode, fscrypt_direction_t rw, + u64 lblk_num, struct page *src_page, + struct page *dest_page, unsigned int len, + unsigned int offs, gfp_t gfp_flags) { union fscrypt_iv iv; struct skcipher_request *req = NULL; @@ -227,9 +228,9 @@ struct page *fscrypt_encrypt_page(const struct inode *inode, if (inode->i_sb->s_cop->flags & FS_CFLG_OWN_PAGES) { /* with inplace-encryption we just encrypt the page */ - err = fscrypt_do_page_crypto(inode, FS_ENCRYPT, lblk_num, page, - ciphertext_page, len, offs, - gfp_flags); + err = fscrypt_crypt_block(inode, FS_ENCRYPT, lblk_num, page, + ciphertext_page, len, offs, + gfp_flags); if (err) return ERR_PTR(err); @@ -243,9 +244,8 @@ struct page *fscrypt_encrypt_page(const struct inode *inode, if (!ciphertext_page) return ERR_PTR(-ENOMEM); - err = fscrypt_do_page_crypto(inode, FS_ENCRYPT, lblk_num, - page, ciphertext_page, len, offs, - gfp_flags); + err = fscrypt_crypt_block(inode, FS_ENCRYPT, lblk_num, page, + ciphertext_page, len, offs, gfp_flags); if (err) { fscrypt_free_bounce_page(ciphertext_page); return ERR_PTR(err); @@ -277,8 +277,8 @@ int fscrypt_decrypt_page(const struct inode *inode, struct page *page, if (!(inode->i_sb->s_cop->flags & FS_CFLG_OWN_PAGES)) BUG_ON(!PageLocked(page)); - return fscrypt_do_page_crypto(inode, FS_DECRYPT, lblk_num, page, page, - len, offs, GFP_NOFS); + return fscrypt_crypt_block(inode, FS_DECRYPT, lblk_num, page, page, + len, offs, GFP_NOFS); } EXPORT_SYMBOL(fscrypt_decrypt_page); diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h index 4122ee1a0b7b1..8978eec9d766d 100644 --- a/fs/crypto/fscrypt_private.h +++ b/fs/crypto/fscrypt_private.h @@ -116,12 +116,11 @@ static inline bool fscrypt_valid_enc_modes(u32 contents_mode, /* crypto.c */ extern struct kmem_cache *fscrypt_info_cachep; extern int fscrypt_initialize(unsigned int cop_flags); -extern int fscrypt_do_page_crypto(const struct inode *inode, - fscrypt_direction_t rw, u64 lblk_num, - struct page *src_page, - struct page *dest_page, - unsigned int len, unsigned int offs, - gfp_t gfp_flags); +extern int fscrypt_crypt_block(const struct inode *inode, + fscrypt_direction_t rw, u64 lblk_num, + struct page *src_page, struct page *dest_page, + unsigned int len, unsigned int offs, + gfp_t gfp_flags); extern struct page *fscrypt_alloc_bounce_page(gfp_t gfp_flags); extern const struct dentry_operations fscrypt_d_ops; From patchwork Mon May 20 16:29:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 10951835 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 51D7A16C1 for ; Mon, 20 May 2019 16:30:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 41C3928704 for ; Mon, 20 May 2019 16:30:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 365D52881B; Mon, 20 May 2019 16:30:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, SUSPICIOUS_RECIPS autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D354828806 for ; Mon, 20 May 2019 16:30:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389658AbfETQaY (ORCPT ); Mon, 20 May 2019 12:30:24 -0400 Received: from mail.kernel.org ([198.145.29.99]:44910 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389579AbfETQaW (ORCPT ); Mon, 20 May 2019 12:30:22 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 249E721726; Mon, 20 May 2019 16:30:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1558369822; bh=R+LKrmanbtXNSZ9aCaevL40joIkJjiQUGQoY5lghui0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=zUYjoQZ6VxD6QzIvpWgy0FCq3Ij2nX5S7S15m3oehysH76SCTGMtidJ4r6WRf95zK ZlOR/OCn3fkjrnuq6bVGbQNjoHZZYn8diig0hr31takBi5qxGbGdJTJQfWsOPyN0Lp NmmBn3GUmrPIvffTfoPuFStwqAR8dIeL4/gu8pxM= From: Eric Biggers To: linux-fscrypt@vger.kernel.org Cc: linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-mtd@lists.infradead.org, Chandan Rajendra Subject: [PATCH v2 04/14] fscrypt: clean up some BUG_ON()s in block encryption/decryption Date: Mon, 20 May 2019 09:29:42 -0700 Message-Id: <20190520162952.156212-5-ebiggers@kernel.org> X-Mailer: git-send-email 2.21.0.1020.gf2820cf01a-goog In-Reply-To: <20190520162952.156212-1-ebiggers@kernel.org> References: <20190520162952.156212-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Eric Biggers Replace some BUG_ON()s with WARN_ON_ONCE() and returning an error code, and move the check for len divisible by FS_CRYPTO_BLOCK_SIZE into fscrypt_crypt_block() so that it's done for both encryption and decryption, not just encryption. Reviewed-by: Chandan Rajendra Signed-off-by: Eric Biggers --- fs/crypto/crypto.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index e6802d7aca3c7..9cda0147fca95 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -161,7 +161,10 @@ int fscrypt_crypt_block(const struct inode *inode, fscrypt_direction_t rw, struct crypto_skcipher *tfm = ci->ci_ctfm; int res = 0; - BUG_ON(len == 0); + if (WARN_ON_ONCE(len <= 0)) + return -EINVAL; + if (WARN_ON_ONCE(len % FS_CRYPTO_BLOCK_SIZE != 0)) + return -EINVAL; fscrypt_generate_iv(&iv, lblk_num, ci); @@ -224,8 +227,6 @@ struct page *fscrypt_encrypt_page(const struct inode *inode, struct page *ciphertext_page = page; int err; - BUG_ON(len % FS_CRYPTO_BLOCK_SIZE != 0); - if (inode->i_sb->s_cop->flags & FS_CFLG_OWN_PAGES) { /* with inplace-encryption we just encrypt the page */ err = fscrypt_crypt_block(inode, FS_ENCRYPT, lblk_num, page, @@ -237,7 +238,8 @@ struct page *fscrypt_encrypt_page(const struct inode *inode, return ciphertext_page; } - BUG_ON(!PageLocked(page)); + if (WARN_ON_ONCE(!PageLocked(page))) + return ERR_PTR(-EINVAL); /* The encryption operation will require a bounce page. */ ciphertext_page = fscrypt_alloc_bounce_page(gfp_flags); @@ -274,8 +276,9 @@ EXPORT_SYMBOL(fscrypt_encrypt_page); int fscrypt_decrypt_page(const struct inode *inode, struct page *page, unsigned int len, unsigned int offs, u64 lblk_num) { - if (!(inode->i_sb->s_cop->flags & FS_CFLG_OWN_PAGES)) - BUG_ON(!PageLocked(page)); + if (WARN_ON_ONCE(!PageLocked(page) && + !(inode->i_sb->s_cop->flags & FS_CFLG_OWN_PAGES))) + return -EINVAL; return fscrypt_crypt_block(inode, FS_DECRYPT, lblk_num, page, page, len, offs, GFP_NOFS); From patchwork Mon May 20 16:29:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 10951833 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 067CD76 for ; Mon, 20 May 2019 16:30:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E937F2880B for ; Mon, 20 May 2019 16:30:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DB51128704; Mon, 20 May 2019 16:30:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, SUSPICIOUS_RECIPS autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4A6FC28704 for ; Mon, 20 May 2019 16:30:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392217AbfETQaY (ORCPT ); Mon, 20 May 2019 12:30:24 -0400 Received: from mail.kernel.org ([198.145.29.99]:44922 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389633AbfETQaX (ORCPT ); Mon, 20 May 2019 12:30:23 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 75E952173C; Mon, 20 May 2019 16:30:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1558369822; bh=YFNzSvg/+MDLitcd1QNpcVpA4+wyTUZ+/r0vkLTqq0k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=O7pAok8IEBV5OA3zUbAW5iySnocSDF3dhyW8Rs8LYjILJ5FvABSYFGTSBZ58+cDGu S2zJ0aE0WC89S1owYpzQSV3tpJLo9BPKDbwRstlx76JVH15V5vHz1XPlsSn65NzymM 1eqHXVBf5ot+HAmebVIHFTRF/zGf3VEA+tAXaVQg= From: Eric Biggers To: linux-fscrypt@vger.kernel.org Cc: linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-mtd@lists.infradead.org, Chandan Rajendra Subject: [PATCH v2 05/14] fscrypt: introduce fscrypt_encrypt_block_inplace() Date: Mon, 20 May 2019 09:29:43 -0700 Message-Id: <20190520162952.156212-6-ebiggers@kernel.org> X-Mailer: git-send-email 2.21.0.1020.gf2820cf01a-goog In-Reply-To: <20190520162952.156212-1-ebiggers@kernel.org> References: <20190520162952.156212-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Eric Biggers fscrypt_encrypt_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_encrypt_block_inplace(). This is in preparation for allowing encryption on ext4 filesystems with blocksize != PAGE_SIZE. Reviewed-by: Chandan Rajendra Signed-off-by: Eric Biggers --- fs/crypto/crypto.c | 50 +++++++++++++++++++++++++---------------- fs/ubifs/crypto.c | 12 +++++----- include/linux/fscrypt.h | 13 +++++++++++ 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index 9cda0147fca95..6877b7c6165de 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -199,8 +199,7 @@ int fscrypt_crypt_block(const struct inode *inode, fscrypt_direction_t rw, /** * fscypt_encrypt_page() - Encrypts a page * @inode: The inode for which the encryption should take place - * @page: The page to encrypt. Must be locked for bounce-page - * encryption. + * @page: The page to encrypt. Must be locked. * @len: Length of data to encrypt in @page and encrypted * data in returned page. * @offs: Offset of data within @page and returned @@ -210,10 +209,9 @@ int fscrypt_crypt_block(const struct inode *inode, fscrypt_direction_t rw, * previously written data. * @gfp_flags: The gfp flag for memory allocation * - * Encrypts @page. If the filesystem set FS_CFLG_OWN_PAGES, then the data is - * encrypted in-place and @page is returned. Else, a bounce page is allocated, - * the data is encrypted into the bounce page, and the bounce page is returned. - * The caller is responsible for calling fscrypt_free_bounce_page(). + * Encrypts @page. A bounce page is allocated, the data is encrypted into the + * bounce page, and the bounce page is returned. The caller is responsible for + * calling fscrypt_free_bounce_page(). * * Return: A page containing the encrypted data on success, else an ERR_PTR() */ @@ -224,24 +222,12 @@ struct page *fscrypt_encrypt_page(const struct inode *inode, u64 lblk_num, gfp_t gfp_flags) { - struct page *ciphertext_page = page; + struct page *ciphertext_page; int err; - if (inode->i_sb->s_cop->flags & FS_CFLG_OWN_PAGES) { - /* with inplace-encryption we just encrypt the page */ - err = fscrypt_crypt_block(inode, FS_ENCRYPT, lblk_num, page, - ciphertext_page, len, offs, - gfp_flags); - if (err) - return ERR_PTR(err); - - return ciphertext_page; - } - if (WARN_ON_ONCE(!PageLocked(page))) return ERR_PTR(-EINVAL); - /* The encryption operation will require a bounce page. */ ciphertext_page = fscrypt_alloc_bounce_page(gfp_flags); if (!ciphertext_page) return ERR_PTR(-ENOMEM); @@ -258,6 +244,32 @@ struct page *fscrypt_encrypt_page(const struct inode *inode, } EXPORT_SYMBOL(fscrypt_encrypt_page); +/** + * fscrypt_encrypt_block_inplace() - Encrypt a filesystem block in-place + * @inode: The inode to which this block belongs + * @page: The page containing the block to encrypt + * @len: Size of block to encrypt. 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 encrypt begins + * @lblk_num: Filesystem logical block number of the block, i.e. the 0-based + * number of the block within the file + * @gfp_flags: Memory allocation flags + * + * Encrypt 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_encrypt_block_inplace(const struct inode *inode, struct page *page, + unsigned int len, unsigned int offs, + u64 lblk_num, gfp_t gfp_flags) +{ + return fscrypt_crypt_block(inode, FS_ENCRYPT, lblk_num, page, page, + len, offs, gfp_flags); +} +EXPORT_SYMBOL(fscrypt_encrypt_block_inplace); + /** * fscrypt_decrypt_page() - Decrypts a page in-place * @inode: The corresponding inode for the page to decrypt. diff --git a/fs/ubifs/crypto.c b/fs/ubifs/crypto.c index 4aaedf2d7f442..032efdad2e668 100644 --- a/fs/ubifs/crypto.c +++ b/fs/ubifs/crypto.c @@ -29,8 +29,8 @@ int ubifs_encrypt(const struct inode *inode, struct ubifs_data_node *dn, { struct ubifs_info *c = inode->i_sb->s_fs_info; void *p = &dn->data; - struct page *ret; unsigned int pad_len = round_up(in_len, UBIFS_CIPHER_BLOCK_SIZE); + int err; ubifs_assert(c, pad_len <= *out_len); dn->compr_size = cpu_to_le16(in_len); @@ -39,11 +39,11 @@ int ubifs_encrypt(const struct inode *inode, struct ubifs_data_node *dn, if (pad_len != in_len) memset(p + in_len, 0, pad_len - in_len); - ret = fscrypt_encrypt_page(inode, virt_to_page(&dn->data), pad_len, - offset_in_page(&dn->data), block, GFP_NOFS); - if (IS_ERR(ret)) { - ubifs_err(c, "fscrypt_encrypt_page failed: %ld", PTR_ERR(ret)); - return PTR_ERR(ret); + err = fscrypt_encrypt_block_inplace(inode, virt_to_page(p), pad_len, + offset_in_page(p), block, GFP_NOFS); + if (err) { + ubifs_err(c, "fscrypt_encrypt_block_inplace() failed: %d", err); + return err; } *out_len = pad_len; diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index 1c7287f146a98..a9b2d26e615d5 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -106,6 +106,10 @@ extern void fscrypt_release_ctx(struct fscrypt_ctx *); extern struct page *fscrypt_encrypt_page(const struct inode *, struct page *, unsigned int, unsigned int, u64, gfp_t); +extern int fscrypt_encrypt_block_inplace(const struct inode *inode, + struct page *page, unsigned int len, + unsigned int offs, u64 lblk_num, + gfp_t gfp_flags); extern int fscrypt_decrypt_page(const struct inode *, struct page *, unsigned int, unsigned int, u64); @@ -293,6 +297,15 @@ static inline struct page *fscrypt_encrypt_page(const struct inode *inode, return ERR_PTR(-EOPNOTSUPP); } +static inline int fscrypt_encrypt_block_inplace(const struct inode *inode, + struct page *page, + unsigned int len, + unsigned int offs, u64 lblk_num, + gfp_t gfp_flags) +{ + return -EOPNOTSUPP; +} + static inline int fscrypt_decrypt_page(const struct inode *inode, struct page *page, unsigned int len, unsigned int offs, From patchwork Mon May 20 16:29:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 10951837 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E16E676 for ; Mon, 20 May 2019 16:30:26 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D12F428806 for ; Mon, 20 May 2019 16:30:26 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C5F982881B; Mon, 20 May 2019 16:30:26 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, SUSPICIOUS_RECIPS autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 272922880B for ; Mon, 20 May 2019 16:30:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730795AbfETQaY (ORCPT ); Mon, 20 May 2019 12:30:24 -0400 Received: from mail.kernel.org ([198.145.29.99]:44894 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389658AbfETQaY (ORCPT ); Mon, 20 May 2019 12:30:24 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C6E8B2173E; Mon, 20 May 2019 16:30:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1558369823; bh=9QdpTEHuf1OrocytJjxo0GKTFXi55ekeZurQgDf8cyU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oP28H7RDt58UjtO464eTlhzvfLwquwG/s3VGS01lHee0Cmvt3cxQX8SYv5NnBnN4+ UzjaVmQyi31Xz/cZrcdpVv5gaMK82/xcCLb1cdB/VwUueDOY/bs77sc7sniiklHwtY 8J1vq0v6d8+Rgl6Z8VrGhAT5S+4BpQLpehTdLb3w= From: Eric Biggers To: linux-fscrypt@vger.kernel.org Cc: linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-mtd@lists.infradead.org, Chandan Rajendra Subject: [PATCH v2 06/14] fscrypt: support encrypting multiple filesystem blocks per page Date: Mon, 20 May 2019 09:29:44 -0700 Message-Id: <20190520162952.156212-7-ebiggers@kernel.org> X-Mailer: git-send-email 2.21.0.1020.gf2820cf01a-goog In-Reply-To: <20190520162952.156212-1-ebiggers@kernel.org> References: <20190520162952.156212-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Eric Biggers Rename fscrypt_encrypt_page() to fscrypt_encrypt_pagecache_blocks() and redefine its behavior to encrypt all filesystem blocks from the given region of the given page, rather than assuming that the region consists of just one filesystem block. Also remove the 'inode' and 'lblk_num' parameters, since they can be retrieved from the page as it's already assumed to be a pagecache page. This is in preparation for allowing encryption on ext4 filesystems with blocksize != PAGE_SIZE. This is based on work by Chandan Rajendra. Reviewed-by: Chandan Rajendra Signed-off-by: Eric Biggers --- fs/crypto/crypto.c | 67 ++++++++++++++++++++++++----------------- fs/ext4/page-io.c | 4 +-- fs/f2fs/data.c | 5 +-- include/linux/fscrypt.h | 17 ++++++----- 4 files changed, 53 insertions(+), 40 deletions(-) diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index 6877b7c6165de..7bdb985126d97 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -121,8 +121,8 @@ struct page *fscrypt_alloc_bounce_page(gfp_t gfp_flags) /** * fscrypt_free_bounce_page() - free a ciphertext bounce page * - * Free a bounce page that was allocated by fscrypt_encrypt_page(), or by - * fscrypt_alloc_bounce_page() directly. + * Free a bounce page that was allocated by fscrypt_encrypt_pagecache_blocks(), + * or by fscrypt_alloc_bounce_page() directly. */ void fscrypt_free_bounce_page(struct page *bounce_page) { @@ -197,52 +197,63 @@ int fscrypt_crypt_block(const struct inode *inode, fscrypt_direction_t rw, } /** - * fscypt_encrypt_page() - Encrypts a page - * @inode: The inode for which the encryption should take place - * @page: The page to encrypt. Must be locked. - * @len: Length of data to encrypt in @page and encrypted - * data in returned page. - * @offs: Offset of data within @page and returned - * page holding encrypted data. - * @lblk_num: Logical block number. This must be unique for multiple - * calls with same inode, except when overwriting - * previously written data. - * @gfp_flags: The gfp flag for memory allocation + * fscrypt_encrypt_pagecache_blocks() - Encrypt filesystem blocks from a pagecache page + * @page: The locked pagecache page containing the block(s) to encrypt + * @len: Total size of the block(s) to encrypt. Must be a nonzero + * multiple of the filesystem's block size. + * @offs: Byte offset within @page of the first block to encrypt. Must be + * a multiple of the filesystem's block size. + * @gfp_flags: Memory allocation flags + * + * A new bounce page is allocated, and the specified block(s) are encrypted into + * it. In the bounce page, the ciphertext block(s) will be located at the same + * offsets at which the plaintext block(s) were located in the source page; any + * other parts of the bounce page will be left uninitialized. However, normally + * blocksize == PAGE_SIZE and the whole page is encrypted at once. * - * Encrypts @page. A bounce page is allocated, the data is encrypted into the - * bounce page, and the bounce page is returned. The caller is responsible for - * calling fscrypt_free_bounce_page(). + * This is for use by the filesystem's ->writepages() method. * - * Return: A page containing the encrypted data on success, else an ERR_PTR() + * Return: the new encrypted bounce page on success; an ERR_PTR() on failure */ -struct page *fscrypt_encrypt_page(const struct inode *inode, - struct page *page, - unsigned int len, - unsigned int offs, - u64 lblk_num, gfp_t gfp_flags) +struct page *fscrypt_encrypt_pagecache_blocks(struct page *page, + unsigned int len, + unsigned int offs, + gfp_t gfp_flags) { + const struct inode *inode = page->mapping->host; + const unsigned int blockbits = inode->i_blkbits; + const unsigned int blocksize = 1 << blockbits; struct page *ciphertext_page; + u64 lblk_num = ((u64)page->index << (PAGE_SHIFT - blockbits)) + + (offs >> blockbits); + unsigned int i; int err; if (WARN_ON_ONCE(!PageLocked(page))) return ERR_PTR(-EINVAL); + if (WARN_ON_ONCE(len <= 0 || !IS_ALIGNED(len | offs, blocksize))) + return ERR_PTR(-EINVAL); + ciphertext_page = fscrypt_alloc_bounce_page(gfp_flags); if (!ciphertext_page) return ERR_PTR(-ENOMEM); - err = fscrypt_crypt_block(inode, FS_ENCRYPT, lblk_num, page, - ciphertext_page, len, offs, gfp_flags); - if (err) { - fscrypt_free_bounce_page(ciphertext_page); - return ERR_PTR(err); + for (i = offs; i < offs + len; i += blocksize, lblk_num++) { + err = fscrypt_crypt_block(inode, FS_ENCRYPT, lblk_num, + page, ciphertext_page, + blocksize, i, gfp_flags); + if (err) { + fscrypt_free_bounce_page(ciphertext_page); + return ERR_PTR(err); + } } SetPagePrivate(ciphertext_page); set_page_private(ciphertext_page, (unsigned long)page); return ciphertext_page; } -EXPORT_SYMBOL(fscrypt_encrypt_page); +EXPORT_SYMBOL(fscrypt_encrypt_pagecache_blocks); /** * fscrypt_encrypt_block_inplace() - Encrypt a filesystem block in-place diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 13d5ecc0af03f..40ee33df57649 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c @@ -471,8 +471,8 @@ int ext4_bio_write_page(struct ext4_io_submit *io, gfp_t gfp_flags = GFP_NOFS; retry_encrypt: - bounce_page = fscrypt_encrypt_page(inode, page, PAGE_SIZE, 0, - page->index, gfp_flags); + bounce_page = fscrypt_encrypt_pagecache_blocks(page, PAGE_SIZE, + 0, gfp_flags); if (IS_ERR(bounce_page)) { ret = PTR_ERR(bounce_page); if (ret == -ENOMEM && wbc->sync_mode == WB_SYNC_ALL) { diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 968ebdbcb5834..a546ac8685ea6 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -1726,8 +1726,9 @@ static int encrypt_one_page(struct f2fs_io_info *fio) f2fs_wait_on_block_writeback(inode, fio->old_blkaddr); retry_encrypt: - fio->encrypted_page = fscrypt_encrypt_page(inode, fio->page, - PAGE_SIZE, 0, fio->page->index, gfp_flags); + fio->encrypted_page = fscrypt_encrypt_pagecache_blocks(fio->page, + PAGE_SIZE, 0, + gfp_flags); if (IS_ERR(fio->encrypted_page)) { /* flush pending IOs and wait for a while in the ENOMEM case */ if (PTR_ERR(fio->encrypted_page) == -ENOMEM) { diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index a9b2d26e615d5..c7e16bd16a6c2 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -103,9 +103,11 @@ static inline void fscrypt_handle_d_move(struct dentry *dentry) extern void fscrypt_enqueue_decrypt_work(struct work_struct *); extern struct fscrypt_ctx *fscrypt_get_ctx(gfp_t); extern void fscrypt_release_ctx(struct fscrypt_ctx *); -extern struct page *fscrypt_encrypt_page(const struct inode *, struct page *, - unsigned int, unsigned int, - u64, gfp_t); + +extern struct page *fscrypt_encrypt_pagecache_blocks(struct page *page, + unsigned int len, + unsigned int offs, + gfp_t gfp_flags); extern int fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page, unsigned int len, unsigned int offs, u64 lblk_num, @@ -288,11 +290,10 @@ static inline void fscrypt_release_ctx(struct fscrypt_ctx *ctx) return; } -static inline struct page *fscrypt_encrypt_page(const struct inode *inode, - struct page *page, - unsigned int len, - unsigned int offs, - u64 lblk_num, gfp_t gfp_flags) +static inline struct page *fscrypt_encrypt_pagecache_blocks(struct page *page, + unsigned int len, + unsigned int offs, + gfp_t gfp_flags) { return ERR_PTR(-EOPNOTSUPP); } From patchwork Mon May 20 16:29:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 10951831 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3AB261390 for ; Mon, 20 May 2019 16:30:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2906828704 for ; Mon, 20 May 2019 16:30:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1D8B22880B; Mon, 20 May 2019 16:30:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, SUSPICIOUS_RECIPS autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BBA3328704 for ; Mon, 20 May 2019 16:30:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389712AbfETQaY (ORCPT ); Mon, 20 May 2019 12:30:24 -0400 Received: from mail.kernel.org ([198.145.29.99]:44942 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730795AbfETQaY (ORCPT ); Mon, 20 May 2019 12:30:24 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 23BF321743; Mon, 20 May 2019 16:30:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1558369823; bh=FsQP/22WhDGSwV7eheG5LJxh8F1YOJFtBPeRIUtSKqs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=1tTDTdCtFZWdMRppc12iWNivhCMli9AU6LE+jjt9uvdwTVFxa3KFrDikvO9dVkK3I U9zhYEYzW2vlWVUf/yTtQHCopNynk0H8CFyKpXGCmZzwblSxW/mZ660sNSuNYeyYBk CD6jBTj/f12yOD05IfYRdNc4yZUMaXnVj5CGCoTw= From: Eric Biggers To: linux-fscrypt@vger.kernel.org Cc: linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-mtd@lists.infradead.org, Chandan Rajendra Subject: [PATCH v2 07/14] fscrypt: handle blocksize < PAGE_SIZE in fscrypt_zeroout_range() Date: Mon, 20 May 2019 09:29:45 -0700 Message-Id: <20190520162952.156212-8-ebiggers@kernel.org> X-Mailer: git-send-email 2.21.0.1020.gf2820cf01a-goog In-Reply-To: <20190520162952.156212-1-ebiggers@kernel.org> References: <20190520162952.156212-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Eric Biggers Adjust fscrypt_zeroout_range() to encrypt a block at a time rather than a page at a time, so that it works when blocksize < PAGE_SIZE. This isn't optimized for performance, but then again this function already wasn't optimized for performance. As a future optimization, we could submit much larger bios here. This is in preparation for allowing encryption on ext4 filesystems with blocksize != PAGE_SIZE. This is based on work by Chandan Rajendra. Reviewed-by: Chandan Rajendra Signed-off-by: Eric Biggers --- fs/crypto/bio.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c index 92b2d5da5d8e1..f9111ffa12ffd 100644 --- a/fs/crypto/bio.c +++ b/fs/crypto/bio.c @@ -72,12 +72,12 @@ EXPORT_SYMBOL(fscrypt_enqueue_decrypt_bio); int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, sector_t pblk, unsigned int len) { + const unsigned int blockbits = inode->i_blkbits; + const unsigned int blocksize = 1 << blockbits; struct page *ciphertext_page; struct bio *bio; int ret, err = 0; - BUG_ON(inode->i_sb->s_blocksize != PAGE_SIZE); - ciphertext_page = fscrypt_alloc_bounce_page(GFP_NOWAIT); if (!ciphertext_page) return -ENOMEM; @@ -85,7 +85,7 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, while (len--) { err = fscrypt_crypt_block(inode, FS_ENCRYPT, lblk, ZERO_PAGE(0), ciphertext_page, - PAGE_SIZE, 0, GFP_NOFS); + blocksize, 0, GFP_NOFS); if (err) goto errout; @@ -95,14 +95,11 @@ int fscrypt_zeroout_range(const struct inode *inode, pgoff_t lblk, goto errout; } bio_set_dev(bio, inode->i_sb->s_bdev); - bio->bi_iter.bi_sector = - pblk << (inode->i_sb->s_blocksize_bits - 9); + bio->bi_iter.bi_sector = pblk << (blockbits - 9); bio_set_op_attrs(bio, REQ_OP_WRITE, 0); - ret = bio_add_page(bio, ciphertext_page, - inode->i_sb->s_blocksize, 0); - if (ret != inode->i_sb->s_blocksize) { + ret = bio_add_page(bio, ciphertext_page, blocksize, 0); + if (WARN_ON(ret != blocksize)) { /* should never happen! */ - WARN_ON(1); bio_put(bio); err = -EIO; goto errout; From patchwork Mon May 20 16:29:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 10951843 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 960EB16C1 for ; Mon, 20 May 2019 16:30:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 85BBF28824 for ; Mon, 20 May 2019 16:30:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7875F28823; Mon, 20 May 2019 16:30:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, SUSPICIOUS_RECIPS autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E9D802880B for ; Mon, 20 May 2019 16:30:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392231AbfETQa1 (ORCPT ); Mon, 20 May 2019 12:30:27 -0400 Received: from mail.kernel.org ([198.145.29.99]:44950 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389672AbfETQaY (ORCPT ); Mon, 20 May 2019 12:30:24 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 7727C21773; Mon, 20 May 2019 16:30:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1558369823; bh=GxxBp84liEESrFGEA5Xz5LCPPTKwa7tjP6Dd6snqoFg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BcgkoNrbokz9Pfll6PnRDKcSf68YnAWkmjiNV1XOohyU3XaaCLlxx7nY7b+fdROwu 9vxU0iFKqZcUOi+z1FxvEarXhrdy3lQeYkexV4XVkidXKLxdxm9TbDlIvvF7iCypFi Ms5aw6QQvZvZqZPJMJebW6RLpKf3gbMjexba17Hs= From: Eric Biggers To: linux-fscrypt@vger.kernel.org Cc: linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-mtd@lists.infradead.org, Chandan Rajendra Subject: [PATCH v2 08/14] fscrypt: introduce fscrypt_decrypt_block_inplace() Date: Mon, 20 May 2019 09:29:46 -0700 Message-Id: <20190520162952.156212-9-ebiggers@kernel.org> X-Mailer: git-send-email 2.21.0.1020.gf2820cf01a-goog In-Reply-To: <20190520162952.156212-1-ebiggers@kernel.org> References: <20190520162952.156212-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Eric Biggers Currently fscrypt_decrypt_page() does one of two logically distinct things depending on whether FS_CFLG_OWN_PAGES is set in the filesystem's fscrypt_operations: decrypt a pagecache page in-place, or decrypt a filesystem block in-place in any page. Currently these happen to share the same implementation, but this conflates the notion of blocks and pages. 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(). This mirrors fscrypt_encrypt_block_inplace(). This is in preparation for allowing encryption on ext4 filesystems with blocksize != PAGE_SIZE. Reviewed-by: Chandan Rajendra 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 c7e16bd16a6c2..315affc99b050 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) { @@ -315,6 +318,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; From patchwork Mon May 20 16:29:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 10951839 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5711F1390 for ; Mon, 20 May 2019 16:30:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4545B28704 for ; Mon, 20 May 2019 16:30:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 39D2E2880B; Mon, 20 May 2019 16:30:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, SUSPICIOUS_RECIPS autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AA71028704 for ; Mon, 20 May 2019 16:30:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392247AbfETQa0 (ORCPT ); Mon, 20 May 2019 12:30:26 -0400 Received: from mail.kernel.org ([198.145.29.99]:44958 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389680AbfETQaY (ORCPT ); Mon, 20 May 2019 12:30:24 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C852621744; Mon, 20 May 2019 16:30:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1558369824; bh=Cp2ESAfDj/HVxHCEM+s4Pwds+GJgxCmhBhAP50lPZjI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ItmYUDpuu5DYNarsTLaOVPOaPhwq3r3eWHN6em2jAOqDlWhuuErIo+yQxmCW3DPJ2 eie0Tyg7oct43KHYJwQJ9Ml/ZiLiqzAbs4NnnsONfUddSXay+Go9TplvYF0MKt/3pp tHCMm9QiNW32Crl85y/sh/eNqI0Dtei++w33G82c= From: Eric Biggers To: linux-fscrypt@vger.kernel.org Cc: linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-mtd@lists.infradead.org, Chandan Rajendra Subject: [PATCH v2 09/14] fscrypt: support decrypting multiple filesystem blocks per page Date: Mon, 20 May 2019 09:29:47 -0700 Message-Id: <20190520162952.156212-10-ebiggers@kernel.org> X-Mailer: git-send-email 2.21.0.1020.gf2820cf01a-goog In-Reply-To: <20190520162952.156212-1-ebiggers@kernel.org> References: <20190520162952.156212-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Eric Biggers Rename fscrypt_decrypt_page() to fscrypt_decrypt_pagecache_blocks() and redefine its behavior to decrypt all filesystem blocks in the given region of the given page, rather than assuming that the region consists of just one filesystem block. Also remove the 'inode' and 'lblk_num' parameters, since they can be retrieved from the page as it's already assumed to be a pagecache page. This is in preparation for allowing encryption on ext4 filesystems with blocksize != PAGE_SIZE. This is based on work by Chandan Rajendra. Reviewed-by: Chandan Rajendra Signed-off-by: Eric Biggers --- fs/crypto/bio.c | 3 +-- fs/crypto/crypto.c | 46 ++++++++++++++++++++++++++++------------- fs/ext4/inode.c | 7 +++---- include/linux/fscrypt.h | 12 +++++------ 4 files changed, 42 insertions(+), 26 deletions(-) diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c index f9111ffa12ffd..61da06fda45cc 100644 --- a/fs/crypto/bio.c +++ b/fs/crypto/bio.c @@ -33,8 +33,7 @@ static void __fscrypt_decrypt_bio(struct bio *bio, bool done) bio_for_each_segment_all(bv, bio, iter_all) { struct page *page = bv->bv_page; - int ret = fscrypt_decrypt_page(page->mapping->host, page, - PAGE_SIZE, 0, page->index); + int ret = fscrypt_decrypt_pagecache_blocks(page, PAGE_SIZE, 0); if (ret) SetPageError(page); diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c index 2e6fb5e4f7a7f..dcf630d7e4460 100644 --- a/fs/crypto/crypto.c +++ b/fs/crypto/crypto.c @@ -282,29 +282,47 @@ int fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page, 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. - * @len: Number of bytes in @page to be decrypted. - * @offs: Start of data in @page. - * @lblk_num: Logical block number. + * fscrypt_decrypt_pagecache_blocks() - Decrypt filesystem blocks in a pagecache page + * @page: The locked pagecache page containing the block(s) to decrypt + * @len: Total size of the block(s) to decrypt. Must be a nonzero + * multiple of the filesystem's block size. + * @offs: Byte offset within @page of the first block to decrypt. Must be + * a multiple of the filesystem's block size. * - * Decrypts page in-place using the ctx encryption context. + * The specified block(s) are decrypted in-place within the pagecache page, + * which must still be locked and not uptodate. Normally, blocksize == + * PAGE_SIZE and the whole page is decrypted at once. * - * Called from the read completion callback. + * This is for use by the filesystem's ->readpages() method. * - * Return: Zero on success, non-zero otherwise. + * Return: 0 on success; -errno on failure */ -int fscrypt_decrypt_page(const struct inode *inode, struct page *page, - unsigned int len, unsigned int offs, u64 lblk_num) +int fscrypt_decrypt_pagecache_blocks(struct page *page, unsigned int len, + unsigned int offs) { + const struct inode *inode = page->mapping->host; + const unsigned int blockbits = inode->i_blkbits; + const unsigned int blocksize = 1 << blockbits; + u64 lblk_num = ((u64)page->index << (PAGE_SHIFT - blockbits)) + + (offs >> blockbits); + unsigned int i; + int err; + if (WARN_ON_ONCE(!PageLocked(page))) return -EINVAL; - return fscrypt_crypt_block(inode, FS_DECRYPT, lblk_num, page, page, - len, offs, GFP_NOFS); + if (WARN_ON_ONCE(len <= 0 || !IS_ALIGNED(len | offs, blocksize))) + return -EINVAL; + + for (i = offs; i < offs + len; i += blocksize, lblk_num++) { + err = fscrypt_crypt_block(inode, FS_DECRYPT, lblk_num, page, + page, blocksize, i, GFP_NOFS); + if (err) + return err; + } + return 0; } -EXPORT_SYMBOL(fscrypt_decrypt_page); +EXPORT_SYMBOL(fscrypt_decrypt_pagecache_blocks); /** * fscrypt_decrypt_block_inplace() - Decrypt a filesystem block in-place diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 82298c63ea6d6..34fda4864c0eb 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1232,8 +1232,7 @@ static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len, if (unlikely(err)) page_zero_new_buffers(page, from, to); else if (decrypt) - err = fscrypt_decrypt_page(page->mapping->host, page, - PAGE_SIZE, 0, page->index); + err = fscrypt_decrypt_pagecache_blocks(page, PAGE_SIZE, 0); return err; } #endif @@ -4066,8 +4065,8 @@ static int __ext4_block_zero_page_range(handle_t *handle, /* We expect the key to be set. */ BUG_ON(!fscrypt_has_encryption_key(inode)); BUG_ON(blocksize != PAGE_SIZE); - WARN_ON_ONCE(fscrypt_decrypt_page(page->mapping->host, - page, PAGE_SIZE, 0, page->index)); + WARN_ON_ONCE(fscrypt_decrypt_pagecache_blocks( + page, PAGE_SIZE, 0)); } } if (ext4_should_journal_data(inode)) { diff --git a/include/linux/fscrypt.h b/include/linux/fscrypt.h index 315affc99b050..bd8f207a2fb68 100644 --- a/include/linux/fscrypt.h +++ b/include/linux/fscrypt.h @@ -112,8 +112,9 @@ extern int fscrypt_encrypt_block_inplace(const struct inode *inode, struct page *page, unsigned int len, unsigned int offs, u64 lblk_num, gfp_t gfp_flags); -extern int fscrypt_decrypt_page(const struct inode *, struct page *, unsigned int, - unsigned int, u64); + +extern int fscrypt_decrypt_pagecache_blocks(struct page *page, unsigned int len, + unsigned int offs); extern int fscrypt_decrypt_block_inplace(const struct inode *inode, struct page *page, unsigned int len, unsigned int offs, u64 lblk_num); @@ -310,10 +311,9 @@ static inline int fscrypt_encrypt_block_inplace(const struct inode *inode, return -EOPNOTSUPP; } -static inline int fscrypt_decrypt_page(const struct inode *inode, - struct page *page, - unsigned int len, unsigned int offs, - u64 lblk_num) +static inline int fscrypt_decrypt_pagecache_blocks(struct page *page, + unsigned int len, + unsigned int offs) { return -EOPNOTSUPP; } From patchwork Mon May 20 16:29:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 10951841 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 52AA176 for ; Mon, 20 May 2019 16:30:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 42D6D28704 for ; Mon, 20 May 2019 16:30:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3781F28821; Mon, 20 May 2019 16:30:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, SUSPICIOUS_RECIPS autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C99A028704 for ; Mon, 20 May 2019 16:30:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392350AbfETQa1 (ORCPT ); Mon, 20 May 2019 12:30:27 -0400 Received: from mail.kernel.org ([198.145.29.99]:44964 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390599AbfETQaY (ORCPT ); Mon, 20 May 2019 12:30:24 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 254B721783; Mon, 20 May 2019 16:30:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1558369824; bh=o0e8iPypj6yg/PXej9C7BCFNXDHwPIDoUEs1N2gsreM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=V3WypIvT53nUzt687xIv8X7+zzm9Q2xFxN4jz0ofhZURnAQ5c4fU0s/I61jcsJwXG cTB6wJ4w3DJGxyP5QnmI3QvLKWf3fgOJhVTB7vS5lJk+ra4zja9hZs9H6VM0dzXDBO ha1yDoBFkgl6IHXYqBjrsuemCqqQQTLJRN71rTbA= From: Eric Biggers To: linux-fscrypt@vger.kernel.org Cc: linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-mtd@lists.infradead.org, Chandan Rajendra Subject: [PATCH v2 10/14] fscrypt: decrypt only the needed blocks in __fscrypt_decrypt_bio() Date: Mon, 20 May 2019 09:29:48 -0700 Message-Id: <20190520162952.156212-11-ebiggers@kernel.org> X-Mailer: git-send-email 2.21.0.1020.gf2820cf01a-goog In-Reply-To: <20190520162952.156212-1-ebiggers@kernel.org> References: <20190520162952.156212-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Eric Biggers In __fscrypt_decrypt_bio(), only decrypt the blocks that actually comprise the bio, rather than assuming blocksize == PAGE_SIZE and decrypting the entirety of every page used in the bio. This is in preparation for allowing encryption on ext4 filesystems with blocksize != PAGE_SIZE. This is based on work by Chandan Rajendra. Reviewed-by: Chandan Rajendra Signed-off-by: Eric Biggers --- fs/crypto/bio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c index 61da06fda45cc..82da2510721f6 100644 --- a/fs/crypto/bio.c +++ b/fs/crypto/bio.c @@ -33,8 +33,8 @@ static void __fscrypt_decrypt_bio(struct bio *bio, bool done) bio_for_each_segment_all(bv, bio, iter_all) { struct page *page = bv->bv_page; - int ret = fscrypt_decrypt_pagecache_blocks(page, PAGE_SIZE, 0); - + int ret = fscrypt_decrypt_pagecache_blocks(page, bv->bv_len, + bv->bv_offset); if (ret) SetPageError(page); else if (done) From patchwork Mon May 20 16:29:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 10951849 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8280216C1 for ; Mon, 20 May 2019 16:30:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6E5C128704 for ; Mon, 20 May 2019 16:30:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 608962881B; Mon, 20 May 2019 16:30:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, SUSPICIOUS_RECIPS autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7DB352880B for ; Mon, 20 May 2019 16:30:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392283AbfETQa0 (ORCPT ); Mon, 20 May 2019 12:30:26 -0400 Received: from mail.kernel.org ([198.145.29.99]:44942 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2392210AbfETQaZ (ORCPT ); Mon, 20 May 2019 12:30:25 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 771892177B; Mon, 20 May 2019 16:30:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1558369824; bh=2VfMQcWxI7izVssKpNPFzAKV9+cNy5lJmumqc5qr+wM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sBgj5saciLvVrwohSAaTQGyUQML0D8dweuFggK7JAxrYNJ48w0hn6cbW3A61PEndn VWVdGZePP4z9MBXf+bcI3cwBzkOjpe9uXrFMc9wSSVEBr4oVVJt9lXYqQoehFSDNWo 9USOUK7vN2q8D+I+jQeoXnirC0yTEic2JTH89jSU= From: Eric Biggers To: linux-fscrypt@vger.kernel.org Cc: linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-mtd@lists.infradead.org, Chandan Rajendra Subject: [PATCH v2 11/14] ext4: clear BH_Uptodate flag on decryption error Date: Mon, 20 May 2019 09:29:49 -0700 Message-Id: <20190520162952.156212-12-ebiggers@kernel.org> X-Mailer: git-send-email 2.21.0.1020.gf2820cf01a-goog In-Reply-To: <20190520162952.156212-1-ebiggers@kernel.org> References: <20190520162952.156212-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Chandan Rajendra If decryption fails, ext4_block_write_begin() can return with the page's buffer_head marked with the BH_Uptodate flag. This commit clears the BH_Uptodate flag in such cases. Signed-off-by: Chandan Rajendra Signed-off-by: Eric Biggers --- fs/ext4/inode.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 34fda4864c0eb..0e6536a22a465 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1229,10 +1229,14 @@ static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len, if (!buffer_uptodate(*wait_bh)) err = -EIO; } - if (unlikely(err)) + if (unlikely(err)) { page_zero_new_buffers(page, from, to); - else if (decrypt) + } else if (decrypt) { err = fscrypt_decrypt_pagecache_blocks(page, PAGE_SIZE, 0); + if (err) + clear_buffer_uptodate(*wait_bh); + } + return err; } #endif From patchwork Mon May 20 16:29:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 10951847 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DFE401390 for ; Mon, 20 May 2019 16:30:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CE60528704 for ; Mon, 20 May 2019 16:30:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C2D9528823; Mon, 20 May 2019 16:30:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, SUSPICIOUS_RECIPS autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5DEDF28704 for ; Mon, 20 May 2019 16:30:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389680AbfETQa0 (ORCPT ); Mon, 20 May 2019 12:30:26 -0400 Received: from mail.kernel.org ([198.145.29.99]:44922 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2392231AbfETQaZ (ORCPT ); Mon, 20 May 2019 12:30:25 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C8212217D4; Mon, 20 May 2019 16:30:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1558369825; bh=jzDa4sIscNqlfHv7tNu4xnhMMMwK6J7mZB9Z89E3MiY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ob/JPjcP7714BGREu627MvS2LQxzV4JLdnXXWnMnDH1YTlzvo+9t2j3I8S0VudDhS 92QsFC9y2jHVMwi4utg/5SWjCEOHa1YtdAC7FNlADEUtX7+2Dy4fSi2Eh4HmQr2LUQ Yja0pYrVp6mCFfIxfZ6/DnkEoG3ukGh4lW90ADZk= From: Eric Biggers To: linux-fscrypt@vger.kernel.org Cc: linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-mtd@lists.infradead.org, Chandan Rajendra Subject: [PATCH v2 12/14] ext4: decrypt only the needed blocks in ext4_block_write_begin() Date: Mon, 20 May 2019 09:29:50 -0700 Message-Id: <20190520162952.156212-13-ebiggers@kernel.org> X-Mailer: git-send-email 2.21.0.1020.gf2820cf01a-goog In-Reply-To: <20190520162952.156212-1-ebiggers@kernel.org> References: <20190520162952.156212-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Chandan Rajendra In ext4_block_write_begin(), only decrypt the blocks that actually need to be decrypted (up to two blocks which intersect the boundaries of the region that will be written to), rather than assuming blocksize == PAGE_SIZE and decrypting the whole page. This is in preparation for allowing encryption on ext4 filesystems with blocksize != PAGE_SIZE. Signed-off-by: Chandan Rajendra (EB: rebase onto previous changes, improve the commit message, and move the check for encrypted inode) Signed-off-by: Eric Biggers --- fs/ext4/inode.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 0e6536a22a465..8b3ea9c8ac988 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1164,8 +1164,9 @@ static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len, int err = 0; unsigned blocksize = inode->i_sb->s_blocksize; unsigned bbits; - struct buffer_head *bh, *head, *wait[2], **wait_bh = wait; - bool decrypt = false; + struct buffer_head *bh, *head, *wait[2]; + int nr_wait = 0; + int i; BUG_ON(!PageLocked(page)); BUG_ON(from > PAGE_SIZE); @@ -1217,24 +1218,30 @@ static int ext4_block_write_begin(struct page *page, loff_t pos, unsigned len, !buffer_unwritten(bh) && (block_start < from || block_end > to)) { ll_rw_block(REQ_OP_READ, 0, 1, &bh); - *wait_bh++ = bh; - decrypt = IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode); + wait[nr_wait++] = bh; } } /* * If we issued read requests, let them complete. */ - while (wait_bh > wait) { - wait_on_buffer(*--wait_bh); - if (!buffer_uptodate(*wait_bh)) + for (i = 0; i < nr_wait; i++) { + wait_on_buffer(wait[i]); + if (!buffer_uptodate(wait[i])) err = -EIO; } if (unlikely(err)) { page_zero_new_buffers(page, from, to); - } else if (decrypt) { - err = fscrypt_decrypt_pagecache_blocks(page, PAGE_SIZE, 0); - if (err) - clear_buffer_uptodate(*wait_bh); + } else if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode)) { + for (i = 0; i < nr_wait; i++) { + int err2; + + err2 = fscrypt_decrypt_pagecache_blocks(page, blocksize, + bh_offset(wait[i])); + if (err2) { + clear_buffer_uptodate(wait[i]); + err = err2; + } + } } return err; From patchwork Mon May 20 16:29:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 10951845 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AD53C17E0 for ; Mon, 20 May 2019 16:30:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9CF782881B for ; Mon, 20 May 2019 16:30:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 91BEB2881D; Mon, 20 May 2019 16:30:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, SUSPICIOUS_RECIPS autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3728B2881D for ; Mon, 20 May 2019 16:30:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392315AbfETQa0 (ORCPT ); Mon, 20 May 2019 12:30:26 -0400 Received: from mail.kernel.org ([198.145.29.99]:44910 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389633AbfETQaZ (ORCPT ); Mon, 20 May 2019 12:30:25 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 253F2217D7; Mon, 20 May 2019 16:30:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1558369825; bh=bNfXVLtoITf8LG1OztsuiNKS3cmbu3tuokayi1NgBvg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ICE9E/nKHvk1KzmTsv7NT0zAmnnMv0GrRE2cFsDrCO79Pr0l3xR0tSZLRKaQVfww+ F04rJTlzFdv6lvY0pRaVYsuTSOPIoF++p0FCAK1lDPym0h4D0leBHCyOc51fQtejoy koS9Idc5jJ0aNk3g4RQTFT+39LtMR4UmJSSj47mg= From: Eric Biggers To: linux-fscrypt@vger.kernel.org Cc: linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-mtd@lists.infradead.org, Chandan Rajendra Subject: [PATCH v2 13/14] ext4: decrypt only the needed block in __ext4_block_zero_page_range() Date: Mon, 20 May 2019 09:29:51 -0700 Message-Id: <20190520162952.156212-14-ebiggers@kernel.org> X-Mailer: git-send-email 2.21.0.1020.gf2820cf01a-goog In-Reply-To: <20190520162952.156212-1-ebiggers@kernel.org> References: <20190520162952.156212-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Chandan Rajendra In __ext4_block_zero_page_range(), only decrypt the block that actually needs to be decrypted, rather than assuming blocksize == PAGE_SIZE and decrypting the whole page. This is in preparation for allowing encryption on ext4 filesystems with blocksize != PAGE_SIZE. Signed-off-by: Chandan Rajendra (EB: rebase onto previous changes, improve the commit message, and use bh_offset()) Signed-off-by: Eric Biggers --- fs/ext4/inode.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 8b3ea9c8ac988..77c43c50e4580 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4075,9 +4075,8 @@ static int __ext4_block_zero_page_range(handle_t *handle, if (S_ISREG(inode->i_mode) && IS_ENCRYPTED(inode)) { /* We expect the key to be set. */ BUG_ON(!fscrypt_has_encryption_key(inode)); - BUG_ON(blocksize != PAGE_SIZE); WARN_ON_ONCE(fscrypt_decrypt_pagecache_blocks( - page, PAGE_SIZE, 0)); + page, blocksize, bh_offset(bh))); } } if (ext4_should_journal_data(inode)) { From patchwork Mon May 20 16:29:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Biggers X-Patchwork-Id: 10951851 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E31A976 for ; Mon, 20 May 2019 16:30:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D055A28704 for ; Mon, 20 May 2019 16:30:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C49742880B; Mon, 20 May 2019 16:30:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-5.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, SUSPICIOUS_RECIPS autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1590F28806 for ; Mon, 20 May 2019 16:30:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392210AbfETQa0 (ORCPT ); Mon, 20 May 2019 12:30:26 -0400 Received: from mail.kernel.org ([198.145.29.99]:44894 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2392239AbfETQa0 (ORCPT ); Mon, 20 May 2019 12:30:26 -0400 Received: from ebiggers-linuxstation.mtv.corp.google.com (unknown [104.132.1.77]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 75FAB217D8; Mon, 20 May 2019 16:30:25 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1558369825; bh=nukFlueEKdgNJgzso/AFsN3Mr+EdXgyUtrGGf/8u+g8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=L1Vz3x+6nxyFBaE2h8BSCuzL5qFe0UHFxvGgBIrdA8tW7WyZbF/6R2LpBd+1TkCzr pB4VpfNErXPtOKrXOnjcA6qsOyyIUIO3CgBChitVl3yi1JSURZCiGD6g6S4l1QcvOE 4ZUU82xl6pdJqBCczP5WFk45xzIteoWph7h/RoPM= From: Eric Biggers To: linux-fscrypt@vger.kernel.org Cc: linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-mtd@lists.infradead.org, Chandan Rajendra Subject: [PATCH v2 14/14] ext4: encrypt only up to last block in ext4_bio_write_page() Date: Mon, 20 May 2019 09:29:52 -0700 Message-Id: <20190520162952.156212-15-ebiggers@kernel.org> X-Mailer: git-send-email 2.21.0.1020.gf2820cf01a-goog In-Reply-To: <20190520162952.156212-1-ebiggers@kernel.org> References: <20190520162952.156212-1-ebiggers@kernel.org> MIME-Version: 1.0 Sender: linux-fscrypt-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fscrypt@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Eric Biggers As an optimization, don't encrypt blocks fully beyond i_size, since those definitely won't need to be written out. Also add a comment. This is in preparation for allowing encryption on ext4 filesystems with blocksize != PAGE_SIZE. This is based on work by Chandan Rajendra. Reviewed-by: Chandan Rajendra Signed-off-by: Eric Biggers --- fs/ext4/page-io.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 40ee33df57649..a18a47a2a1d1a 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c @@ -467,11 +467,19 @@ int ext4_bio_write_page(struct ext4_io_submit *io, bh = head = page_buffers(page); + /* + * If any blocks are being written to an encrypted file, encrypt them + * into a bounce page. For simplicity, just encrypt until the last + * block which might be needed. This may cause some unneeded blocks + * (e.g. holes) to be unnecessarily encrypted, but this is rare and + * can't happen in the common case of blocksize == PAGE_SIZE. + */ if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode) && nr_to_submit) { gfp_t gfp_flags = GFP_NOFS; + unsigned int enc_bytes = round_up(len, i_blocksize(inode)); retry_encrypt: - bounce_page = fscrypt_encrypt_pagecache_blocks(page, PAGE_SIZE, + bounce_page = fscrypt_encrypt_pagecache_blocks(page, enc_bytes, 0, gfp_flags); if (IS_ERR(bounce_page)) { ret = PTR_ERR(bounce_page);