| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| From: Eric Biggers <ebiggers@google.com> |
| Date: Fri, 24 Jul 2020 18:44:56 +0000 |
| Subject: ANDROID: direct-io: add support for fscrypt using blk-crypto |
| |
| Set bio crypt contexts on bios by calling into fscrypt when required, |
| and explicitly check for DUN continuity when adding pages to the bio. |
| (While DUN continuity is usually implied by logical block contiguity, |
| this is not the case when using certain fscrypt IV generation methods |
| like IV_INO_LBLK_32). |
| |
| [CPNOTE: 25/05/21] Lee: No update since v8 was posted in January - poked the MLs |
| [CPNOTE: 26/05/21] Lee: Satya will work to push these forward over the next week |
| [CPNOTE: 22/07/21] Lee: v9 was posted 7 weeks ago with no reviews - poked again |
| [CPNOTE: 04/08/21] Lee: Eric and Satya are still working on this [0] |
| |
| [0] https://lore.kernel.org/linux-xfs/YPmFSw4JbWnIozSZ@gmail.com/ |
| |
| Signed-off-by: Eric Biggers <ebiggers@google.com> |
| Co-developed-by: Satya Tangirala <satyat@google.com> |
| Signed-off-by: Satya Tangirala <satyat@google.com> |
| Reviewed-by: Jaegeuk Kim <jaegeuk@kernel.org> |
| |
| Bug: 162255927 |
| Link: https://lore.kernel.org/r/20200724184501.1651378-3-satyat@google.com |
| Change-Id: I57ff74185004371c01ec35d806b0749583375c58 |
| Signed-off-by: Eric Biggers <ebiggers@google.com> |
| --- |
| fs/direct-io.c | 15 ++++++++++++++- |
| 1 file changed, 14 insertions(+), 1 deletion(-) |
| |
| diff --git a/fs/direct-io.c b/fs/direct-io.c |
| --- a/fs/direct-io.c |
| +++ b/fs/direct-io.c |
| @@ -24,6 +24,7 @@ |
| #include <linux/module.h> |
| #include <linux/types.h> |
| #include <linux/fs.h> |
| +#include <linux/fscrypt.h> |
| #include <linux/mm.h> |
| #include <linux/slab.h> |
| #include <linux/highmem.h> |
| @@ -391,6 +392,7 @@ dio_bio_alloc(struct dio *dio, struct dio_submit *sdio, |
| sector_t first_sector, int nr_vecs) |
| { |
| struct bio *bio; |
| + struct inode *inode = dio->inode; |
| |
| /* |
| * bio_alloc() is guaranteed to return a bio when allowed to sleep and |
| @@ -398,6 +400,9 @@ dio_bio_alloc(struct dio *dio, struct dio_submit *sdio, |
| */ |
| bio = bio_alloc(GFP_KERNEL, nr_vecs); |
| |
| + fscrypt_set_bio_crypt_ctx(bio, inode, |
| + sdio->cur_page_fs_offset >> inode->i_blkbits, |
| + GFP_KERNEL); |
| bio_set_dev(bio, bdev); |
| bio->bi_iter.bi_sector = first_sector; |
| bio_set_op_attrs(bio, dio->op, dio->op_flags); |
| @@ -761,9 +766,17 @@ static inline int dio_send_cur_page(struct dio *dio, struct dio_submit *sdio, |
| * current logical offset in the file does not equal what would |
| * be the next logical offset in the bio, submit the bio we |
| * have. |
| + * |
| + * When fscrypt inline encryption is used, data unit number |
| + * (DUN) contiguity is also required. Normally that's implied |
| + * by logical contiguity. However, certain IV generation |
| + * methods (e.g. IV_INO_LBLK_32) don't guarantee it. So, we |
| + * must explicitly check fscrypt_mergeable_bio() too. |
| */ |
| if (sdio->final_block_in_bio != sdio->cur_page_block || |
| - cur_offset != bio_next_offset) |
| + cur_offset != bio_next_offset || |
| + !fscrypt_mergeable_bio(sdio->bio, dio->inode, |
| + cur_offset >> dio->inode->i_blkbits)) |
| dio_bio_submit(dio, sdio); |
| } |
| |