diff mbox series

[v5,18/18] btrfs: allow encrypting compressed extents

Message ID b7d40ecc00427518aab87ed4a3ac6d48b951872a.1667389116.git.sweettea-kernel@dorminy.me (mailing list archive)
State New, archived
Headers show
Series btrfs: add fscrypt integration | expand

Commit Message

Sweet Tea Dorminy Nov. 2, 2022, 11:53 a.m. UTC
Conveniently, compressed extents are already padded to sector size, so
they can be encrypted in-place (which requires 16-byte alignment).

Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
---
 fs/btrfs/btrfs_inode.h |  3 ---
 fs/btrfs/compression.c | 23 +++++++++++++++++++++++
 2 files changed, 23 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index f0935a95ec70..d7f2b9a3d42b 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -385,9 +385,6 @@  static inline bool btrfs_inode_in_log(struct btrfs_inode *inode, u64 generation)
  */
 static inline bool btrfs_inode_can_compress(const struct btrfs_inode *inode)
 {
-	if (IS_ENCRYPTED(&inode->vfs_inode))
-		return false;
-
 	if (inode->flags & BTRFS_INODE_NODATACOW ||
 	    inode->flags & BTRFS_INODE_NODATASUM)
 		return false;
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 52df6c06cc91..038721a66414 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -202,6 +202,16 @@  static void end_compressed_bio_read(struct btrfs_bio *bbio)
 				status = errno_to_blk_status(ret);
 			}
 		}
+		if (fscrypt_inode_uses_fs_layer_crypto(inode)) {
+			int err;
+			u64 lblk_num = start >> fs_info->sectorsize_bits;
+			err = fscrypt_decrypt_block_inplace(inode, bv.bv_page,
+							    fs_info->sectorsize,
+							    bv.bv_offset,
+							    lblk_num);
+			if (err)
+				status = errno_to_blk_status(err);
+		}
 	}
 
 	if (status)
@@ -451,6 +461,19 @@  blk_status_t btrfs_submit_compressed_write(struct btrfs_inode *inode, u64 start,
 		real_size = min_t(u64, real_size, compressed_len - offset);
 		ASSERT(IS_ALIGNED(real_size, fs_info->sectorsize));
 
+		if (fscrypt_inode_uses_fs_layer_crypto(&inode->vfs_inode)) {
+			int err;
+			u64 lblk_num = start >> fs_info->sectorsize_bits;
+
+			err = fscrypt_encrypt_block_inplace(&inode->vfs_inode,
+							    page, real_size, 0,
+							    lblk_num, GFP_NOFS);
+			if (err) {
+				ret = errno_to_blk_status(err);
+				break;
+			}
+		}
+
 		if (use_append)
 			added = bio_add_zone_append_page(bio, page, real_size,
 					offset_in_page(offset));