diff mbox series

[v5,49/52] btrfs: support encryption with log replay

Message ID d1ada7ac632c2ab554a840c7ba29b53a93b9855f.1706116485.git.josef@toxicpanda.com (mailing list archive)
State New, archived
Headers show
Series btrfs: add fscrypt support | expand

Commit Message

Josef Bacik Jan. 24, 2024, 5:19 p.m. UTC
Log replay needs a few tweaks in order to make sure everything works
with encryption.

1. Use the size of the item itself, not the size of the item object when
   we're replaying an extent.
2. Copy in the fscrypt context if we find one in the log.
3. Set NEEDS_FULL_SYNC when we update the inode context so all of the
   items are copied into the log at fsync time.

This makes replay of encrypted files work properly.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/fscrypt.c  |  1 +
 fs/btrfs/tree-log.c | 10 +++++++---
 2 files changed, 8 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/fs/btrfs/fscrypt.c b/fs/btrfs/fscrypt.c
index 83fa99a5be6e..b24591af3410 100644
--- a/fs/btrfs/fscrypt.c
+++ b/fs/btrfs/fscrypt.c
@@ -147,6 +147,7 @@  static int btrfs_fscrypt_set_context(struct inode *inode, const void *ctx,
 			goto out_err;
 	}
 
+	set_bit(BTRFS_INODE_NEEDS_FULL_SYNC, &BTRFS_I(inode)->runtime_flags);
 	leaf = path->nodes[0];
 	ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
 
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 6fc16612b9b8..42c2b90515be 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -715,6 +715,7 @@  static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
 	if (found_type == BTRFS_FILE_EXTENT_REG ||
 	    found_type == BTRFS_FILE_EXTENT_PREALLOC) {
 		u64 offset;
+		u32 item_size;
 		unsigned long dest_offset;
 		struct btrfs_key ins;
 
@@ -722,14 +723,16 @@  static noinline int replay_one_extent(struct btrfs_trans_handle *trans,
 		    btrfs_fs_incompat(fs_info, NO_HOLES))
 			goto update_inode;
 
+		item_size = btrfs_item_size(eb, slot);
+
 		ret = btrfs_insert_empty_item(trans, root, path, key,
-					      sizeof(*item));
+					      item_size);
 		if (ret)
 			goto out;
 		dest_offset = btrfs_item_ptr_offset(path->nodes[0],
 						    path->slots[0]);
 		copy_extent_buffer(path->nodes[0], eb, dest_offset,
-				(unsigned long)item,  sizeof(*item));
+				(unsigned long)item, item_size);
 
 		ins.objectid = btrfs_file_extent_disk_bytenr(eb, item);
 		ins.offset = btrfs_file_extent_disk_num_bytes(eb, item);
@@ -2511,7 +2514,8 @@  static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
 			continue;
 
 		/* these keys are simply copied */
-		if (key.type == BTRFS_XATTR_ITEM_KEY) {
+		if (key.type == BTRFS_XATTR_ITEM_KEY ||
+		    key.type == BTRFS_FSCRYPT_INODE_CTX_ITEM_KEY) {
 			ret = overwrite_item(wc->trans, root, path,
 					     eb, i, &key);
 			if (ret)