From: Daniel Vacek <neelx@suse.com>
To: David Sterba <dsterba@suse.com>
Cc: linux-btrfs@vger.kernel.org, Daniel Vacek <neelx@suse.com>,
Josef Bacik <josef@toxicpanda.com>,
Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
Subject: [PATCH 3/8] btrfs-progs: start tracking extent encryption context info
Date: Wed, 15 Oct 2025 14:11:51 +0200 [thread overview]
Message-ID: <20251015121157.1348124-4-neelx@suse.com> (raw)
In-Reply-To: <20251015121157.1348124-1-neelx@suse.com>
From: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
This recapitulates the kernel change named 'btrfs: start tracking extent
encryption context info".
Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
---
kernel-shared/accessors.h | 43 ++++++++++++++++++++++
kernel-shared/tree-checker.c | 65 +++++++++++++++++++++++++++------
kernel-shared/uapi/btrfs_tree.h | 23 +++++++++++-
3 files changed, 118 insertions(+), 13 deletions(-)
diff --git a/kernel-shared/accessors.h b/kernel-shared/accessors.h
index cb96f3e2..5d90be76 100644
--- a/kernel-shared/accessors.h
+++ b/kernel-shared/accessors.h
@@ -935,6 +935,9 @@ BTRFS_SETGET_STACK_FUNCS(super_uuid_tree_generation, struct btrfs_super_block,
BTRFS_SETGET_STACK_FUNCS(super_nr_global_roots, struct btrfs_super_block,
nr_global_roots, 64);
+/* struct btrfs_file_extent_encryption_info */
+BTRFS_SETGET_FUNCS(encryption_info_size, struct btrfs_encryption_info, size, 32);
+
/* struct btrfs_file_extent_item */
BTRFS_SETGET_STACK_FUNCS(stack_file_extent_type, struct btrfs_file_extent_item,
type, 8);
@@ -973,6 +976,46 @@ BTRFS_SETGET_FUNCS(file_extent_encryption, struct btrfs_file_extent_item,
BTRFS_SETGET_FUNCS(file_extent_other_encoding, struct btrfs_file_extent_item,
other_encoding, 16);
+static inline struct btrfs_encryption_info *btrfs_file_extent_encryption_info(
+ const struct btrfs_file_extent_item *ei)
+{
+ unsigned long offset = (unsigned long)ei;
+
+ offset += offsetof(struct btrfs_file_extent_item, encryption_info);
+ return (struct btrfs_encryption_info *)offset;
+}
+
+static inline unsigned long btrfs_file_extent_encryption_ctx_offset(
+ const struct btrfs_file_extent_item *ei)
+{
+ unsigned long offset = (unsigned long)ei;
+
+ offset += offsetof(struct btrfs_file_extent_item, encryption_info);
+ return offset + offsetof(struct btrfs_encryption_info, context);
+}
+
+static inline u32 btrfs_file_extent_encryption_ctx_size(
+ const struct extent_buffer *eb,
+ const struct btrfs_file_extent_item *ei)
+{
+ return btrfs_encryption_info_size(eb, btrfs_file_extent_encryption_info(ei));
+}
+
+static inline void btrfs_set_file_extent_encryption_ctx_size(
+ struct extent_buffer *eb,
+ struct btrfs_file_extent_item *ei,
+ u32 val)
+{
+ btrfs_set_encryption_info_size(eb, btrfs_file_extent_encryption_info(ei), val);
+}
+
+static inline u32 btrfs_file_extent_encryption_info_size(
+ const struct extent_buffer *eb,
+ const struct btrfs_file_extent_item *ei)
+{
+ return btrfs_encryption_info_size(eb, btrfs_file_extent_encryption_info(ei));
+}
+
/* btrfs_qgroup_status_item */
BTRFS_SETGET_FUNCS(qgroup_status_generation, struct btrfs_qgroup_status_item,
generation, 64);
diff --git a/kernel-shared/tree-checker.c b/kernel-shared/tree-checker.c
index ccc1f1ea..93073979 100644
--- a/kernel-shared/tree-checker.c
+++ b/kernel-shared/tree-checker.c
@@ -242,6 +242,8 @@ static int check_extent_data_item(struct extent_buffer *leaf,
u32 sectorsize = fs_info->sectorsize;
u32 item_size = btrfs_item_size(leaf, slot);
u64 extent_end;
+ u8 policy;
+ u8 fe_type;
if (unlikely(!IS_ALIGNED(key->offset, sectorsize))) {
file_extent_err(leaf, slot,
@@ -272,12 +274,12 @@ static int check_extent_data_item(struct extent_buffer *leaf,
SZ_4K);
return -EUCLEAN;
}
- if (unlikely(btrfs_file_extent_type(leaf, fi) >=
- BTRFS_NR_FILE_EXTENT_TYPES)) {
+
+ fe_type = btrfs_file_extent_type(leaf, fi);
+ if (unlikely(fe_type >= BTRFS_NR_FILE_EXTENT_TYPES)) {
file_extent_err(leaf, slot,
"invalid type for file extent, have %u expect range [0, %u]",
- btrfs_file_extent_type(leaf, fi),
- BTRFS_NR_FILE_EXTENT_TYPES - 1);
+ fe_type, BTRFS_NR_FILE_EXTENT_TYPES - 1);
return -EUCLEAN;
}
@@ -293,10 +295,11 @@ static int check_extent_data_item(struct extent_buffer *leaf,
BTRFS_NR_COMPRESS_TYPES - 1);
return -EUCLEAN;
}
- if (unlikely(btrfs_file_extent_encryption(leaf, fi))) {
+ policy = btrfs_file_extent_encryption(leaf, fi);
+ if (unlikely(policy >= BTRFS_NR_ENCRYPTION_TYPES)) {
file_extent_err(leaf, slot,
- "invalid encryption for file extent, have %u expect 0",
- btrfs_file_extent_encryption(leaf, fi));
+ "invalid encryption for file extent, have %u expect range [0, %u]",
+ policy, BTRFS_NR_ENCRYPTION_TYPES - 1);
return -EUCLEAN;
}
if (btrfs_file_extent_type(leaf, fi) == BTRFS_FILE_EXTENT_INLINE) {
@@ -325,12 +328,50 @@ static int check_extent_data_item(struct extent_buffer *leaf,
return 0;
}
- /* Regular or preallocated extent has fixed item size */
- if (unlikely(item_size != sizeof(*fi))) {
- file_extent_err(leaf, slot,
+ if (policy == BTRFS_ENCRYPTION_FSCRYPT) {
+ size_t fe_size = sizeof(*fi) + sizeof(struct btrfs_encryption_info);
+ u32 ctxsize;
+
+ if (unlikely(item_size < fe_size)) {
+ file_extent_err(leaf, slot,
+ "invalid item size for encrypted file extent, have %u expect = %zu + size of u32",
+ item_size, sizeof(*fi));
+ return -EUCLEAN;
+ }
+
+ ctxsize = btrfs_file_extent_encryption_info_size(leaf, fi);
+ if (unlikely(item_size != (fe_size + ctxsize))) {
+ file_extent_err(leaf, slot,
+ "invalid item size for encrypted file extent, have %u expect = %zu + context of size %u",
+ item_size, fe_size, ctxsize);
+ return -EUCLEAN;
+ }
+
+ if (unlikely(ctxsize > BTRFS_MAX_EXTENT_CTX_SIZE)) {
+ file_extent_err(leaf, slot,
+ "invalid file extent context size, have %u expect a maximum of %u",
+ ctxsize, BTRFS_MAX_EXTENT_CTX_SIZE);
+ return -EUCLEAN;
+ }
+
+ /*
+ * Only regular and prealloc extents should have an encryption
+ * context.
+ */
+ if (unlikely(fe_type != BTRFS_FILE_EXTENT_REG &&
+ fe_type != BTRFS_FILE_EXTENT_PREALLOC)) {
+ file_extent_err(leaf, slot,
+ "invalid type for encrypted file extent, have %u",
+ btrfs_file_extent_type(leaf, fi));
+ return -EUCLEAN;
+ }
+ } else {
+ if (unlikely(item_size != sizeof(*fi))) {
+ file_extent_err(leaf, slot,
"invalid item size for reg/prealloc file extent, have %u expect %zu",
- item_size, sizeof(*fi));
- return -EUCLEAN;
+ item_size, sizeof(*fi));
+ return -EUCLEAN;
+ }
}
if (unlikely(CHECK_FE_ALIGNED(leaf, slot, fi, ram_bytes, sectorsize) ||
CHECK_FE_ALIGNED(leaf, slot, fi, disk_bytenr, sectorsize) ||
diff --git a/kernel-shared/uapi/btrfs_tree.h b/kernel-shared/uapi/btrfs_tree.h
index 7f3dffe6..4b4f45aa 100644
--- a/kernel-shared/uapi/btrfs_tree.h
+++ b/kernel-shared/uapi/btrfs_tree.h
@@ -1066,6 +1066,24 @@ enum {
BTRFS_NR_FILE_EXTENT_TYPES = 3,
};
+/*
+ * Currently just the FSCRYPT_SET_CONTEXT_MAX_SIZE, which is larger than the
+ * current extent context size from fscrypt, so this should give us plenty of
+ * breathing room for expansion later.
+ */
+#define BTRFS_MAX_EXTENT_CTX_SIZE 40
+
+enum {
+ BTRFS_ENCRYPTION_NONE,
+ BTRFS_ENCRYPTION_FSCRYPT,
+ BTRFS_NR_ENCRYPTION_TYPES,
+};
+
+struct btrfs_encryption_info {
+ __le32 size;
+ __u8 context[0];
+};
+
struct btrfs_file_extent_item {
/*
* transaction id that created this extent
@@ -1115,7 +1133,10 @@ struct btrfs_file_extent_item {
* always reflects the size uncompressed and without encoding.
*/
__le64 num_bytes;
-
+ /*
+ * the encryption info, if any
+ */
+ struct btrfs_encryption_info encryption_info[0];
} __attribute__ ((__packed__));
struct btrfs_csum_item {
--
2.51.0
next prev parent reply other threads:[~2025-10-15 12:12 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-10-15 12:11 [PATCH 0/8] btrfs-progs: fscrypt updates Daniel Vacek
2025-10-15 12:11 ` [PATCH 1/8] btrfs-progs: check: fix max inline extent size Daniel Vacek
2025-10-15 12:11 ` [PATCH 2/8] btrfs-progs: add new FEATURE_INCOMPAT_ENCRYPT flag Daniel Vacek
2025-10-24 21:16 ` David Sterba
2025-10-15 12:11 ` Daniel Vacek [this message]
2025-10-24 21:29 ` [PATCH 3/8] btrfs-progs: start tracking extent encryption context info David Sterba
2025-10-24 22:43 ` Qu Wenruo
2025-11-05 8:28 ` Daniel Vacek
2025-11-05 8:22 ` Daniel Vacek
2025-11-05 8:27 ` Daniel Vacek
2025-11-05 9:12 ` Qu Wenruo
2025-11-05 10:55 ` Daniel Vacek
2025-11-26 14:11 ` David Sterba
2025-11-27 8:40 ` Daniel Vacek
2025-10-15 12:11 ` [PATCH 4/8] btrfs-progs: add inode encryption contexts Daniel Vacek
2025-10-15 12:11 ` [PATCH 5/8] btrfs-progs: interpret encrypted file extents Daniel Vacek
2025-11-02 22:26 ` Qu Wenruo
2025-11-03 9:57 ` Daniel Vacek
2025-11-05 7:46 ` Daniel Vacek
2025-10-15 12:11 ` [PATCH 6/8] btrfs-progs: handle fscrypt context items Daniel Vacek
2025-10-15 12:11 ` [PATCH 7/8] btrfs-progs: check: update inline extent length checking Daniel Vacek
2025-10-15 12:11 ` [PATCH 8/8] btrfs-progs: string-utils: do not escape space while printing Daniel Vacek
2025-10-17 16:43 ` David Sterba
2025-10-18 17:50 ` Daniel Vacek
2025-10-15 21:10 ` [PATCH 0/8] btrfs-progs: fscrypt updates Qu Wenruo
2025-10-15 21:19 ` Daniel Vacek
2025-10-15 21:20 ` Qu Wenruo
2025-10-16 15:16 ` Johannes Thumshirn
2025-10-17 20:54 ` Mark Harmstone
2025-10-24 21:10 ` David Sterba
2025-10-17 16:45 ` David Sterba
2025-10-18 18:01 ` Daniel Vacek
2025-11-04 14:56 ` David Sterba
-- strict thread matches above, loose matches on Subject: below --
2023-10-10 20:28 [PATCH 0/8] btrfs-progs: add fscrypt support Josef Bacik
2023-10-10 20:28 ` [PATCH 3/8] btrfs-progs: start tracking extent encryption context info Josef Bacik
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251015121157.1348124-4-neelx@suse.com \
--to=neelx@suse.com \
--cc=dsterba@suse.com \
--cc=josef@toxicpanda.com \
--cc=linux-btrfs@vger.kernel.org \
--cc=sweettea-kernel@dorminy.me \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).