ext4: Set the bio REQ_NOENCRYPT flag
Sets the REQ_NOENCRYPT flag for I/O requests that ext4 has already
encrypted. Lower layers such as dm-crypt can observe that flag to
avoid encrypting again if that's how the user configures the
environment.
Change-Id: I62a93e480a9f5788070446bd94694dfb9f83c277
Signed-off-by: Michael Halcrow <mhalcrow@google.com>
Git-repo: https://android.googlesource.com/kernel/common/
Git-commit: 7af2a1358e1577379c04d08b5c1d2ac4565c9418
[stummala@codeaurora.org: resolve merge conflicts]
Signed-off-by: Sahitya Tummala <stummala@codeaurora.org>
diff --git a/fs/crypto/bio.c b/fs/crypto/bio.c
index c629e97..c74e9ac 100644
--- a/fs/crypto/bio.c
+++ b/fs/crypto/bio.c
@@ -131,7 +131,7 @@
bio->bi_bdev = inode->i_sb->s_bdev;
bio->bi_iter.bi_sector =
pblk << (inode->i_sb->s_blocksize_bits - 9);
- bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
+ bio_set_op_attrs(bio, REQ_OP_WRITE, REQ_NOENCRYPT);
ret = bio_add_page(bio, ciphertext_page,
inode->i_sb->s_blocksize, 0);
if (ret != inode->i_sb->s_blocksize) {
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 0647538..f0d3daa 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -203,7 +203,10 @@
ssize_t size; /* size of the extent */
} ext4_io_end_t;
+#define EXT4_IO_ENCRYPTED 1
+
struct ext4_io_submit {
+ unsigned int io_flags;
struct writeback_control *io_wbc;
struct bio *io_bio;
ext4_io_end_t *io_end;
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index c38245d..2e4428c 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1150,11 +1150,12 @@
if (!buffer_uptodate(bh) && !buffer_delay(bh) &&
!buffer_unwritten(bh) &&
(block_start < from || block_end > to)) {
- ll_rw_block(REQ_OP_READ, 0, 1, &bh);
- *wait_bh++ = bh;
decrypt = ext4_encrypted_inode(inode) &&
S_ISREG(inode->i_mode) &&
!fscrypt_using_hardware_encryption(inode);
+ ll_rw_block(REQ_OP_READ, (decrypt ? REQ_NOENCRYPT : 0),
+ 1, &bh);
+ *wait_bh++ = bh;
}
}
/*
@@ -3772,6 +3773,7 @@
struct inode *inode = mapping->host;
struct buffer_head *bh;
struct page *page;
+ bool decrypt;
int err = 0;
page = find_or_create_page(mapping, from >> PAGE_SHIFT,
@@ -3814,14 +3816,15 @@
if (!buffer_uptodate(bh)) {
err = -EIO;
- ll_rw_block(REQ_OP_READ, 0, 1, &bh);
+ decrypt = S_ISREG(inode->i_mode) &&
+ ext4_encrypted_inode(inode) &&
+ !fscrypt_using_hardware_encryption(inode);
+ ll_rw_block(REQ_OP_READ, (decrypt ? REQ_NOENCRYPT : 0), 1, &bh);
wait_on_buffer(bh);
/* Uhhuh. Read error. Complain and punt. */
if (!buffer_uptodate(bh))
goto unlock;
- if (S_ISREG(inode->i_mode) &&
- ext4_encrypted_inode(inode) &&
- !fscrypt_using_hardware_encryption(inode)) {
+ if (decrypt) {
/* We expect the key to be set. */
BUG_ON(!fscrypt_has_encryption_key(inode));
BUG_ON(blocksize != PAGE_SIZE);
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c
index 8d4ec1a..228baa5 100644
--- a/fs/ext4/page-io.c
+++ b/fs/ext4/page-io.c
@@ -341,6 +341,8 @@
if (bio) {
int io_op_flags = io->io_wbc->sync_mode == WB_SYNC_ALL ?
WRITE_SYNC : 0;
+ if (io->io_flags & EXT4_IO_ENCRYPTED)
+ io_op_flags |= REQ_NOENCRYPT;
bio_set_op_attrs(io->io_bio, REQ_OP_WRITE, io_op_flags);
submit_bio(io->io_bio);
}
@@ -350,6 +352,7 @@
void ext4_io_submit_init(struct ext4_io_submit *io,
struct writeback_control *wbc)
{
+ io->io_flags = 0;
io->io_wbc = wbc;
io->io_bio = NULL;
io->io_end = NULL;
@@ -492,6 +495,8 @@
do {
if (!buffer_async_write(bh))
continue;
+ if (data_page)
+ io->io_flags |= EXT4_IO_ENCRYPTED;
ret = io_submit_add_bh(io, inode,
data_page ? data_page : page, bh);
if (ret) {
diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c
index c39a12d..270c4f4 100644
--- a/fs/ext4/readpage.c
+++ b/fs/ext4/readpage.c
@@ -297,7 +297,8 @@
bio->bi_iter.bi_sector = blocks[0] << (blkbits - 9);
bio->bi_end_io = mpage_end_io;
bio->bi_private = ctx;
- bio_set_op_attrs(bio, REQ_OP_READ, 0);
+ bio_set_op_attrs(bio, REQ_OP_READ,
+ ctx ? REQ_NOENCRYPT : 0);
}
length = first_hole << blkbits;