linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/8] btrfs-progs: add fscrypt support
@ 2023-10-10 20:28 Josef Bacik
  2023-10-10 20:28 ` [PATCH 1/8] btrfs-progs: check: fix max inline extent size Josef Bacik
                   ` (7 more replies)
  0 siblings, 8 replies; 11+ messages in thread
From: Josef Bacik @ 2023-10-10 20:28 UTC (permalink / raw)
  To: linux-btrfs

Hello,

These patches have been updated to reflect the new on-disk format that comes
along with the updated fscrypt support patches.  The only new change that I've
added is a fix around the maximum inline extent size, which is more of a general
thing that needed to be updated, but was exposed by the fscrypt support.
Thanks,

Josef

Josef Bacik (1):
  btrfs-progs: check: fix max inline extent size

Sweet Tea Dorminy (7):
  btrfs-progs: add new FEATURE_INCOMPAT_ENCRYPT flag
  btrfs-progs: start tracking extent encryption context info
  btrfs-progs: add inode encryption contexts
  btrfs-progs: interpret encrypted file extents.
  btrfs-progs: handle fscrypt context items
  btrfs-progs: escape unprintable characters in names
  btrfs-progs: check: update inline extent length checking

 check/main.c                    | 38 +++++++++++--------
 kernel-shared/accessors.h       | 48 ++++++++++++++++++++++++
 kernel-shared/ctree.h           |  3 +-
 kernel-shared/print-tree.c      | 62 +++++++++++++++++++++++++++++--
 kernel-shared/tree-checker.c    | 66 ++++++++++++++++++++++++++++-----
 kernel-shared/uapi/btrfs.h      |  1 +
 kernel-shared/uapi/btrfs_tree.h | 27 +++++++++++++-
 7 files changed, 215 insertions(+), 30 deletions(-)

-- 
2.41.0


^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/8] btrfs-progs: check: fix max inline extent size
  2023-10-10 20:28 [PATCH 0/8] btrfs-progs: add fscrypt support Josef Bacik
@ 2023-10-10 20:28 ` Josef Bacik
  2023-10-11 23:14   ` Neal Gompa
  2023-10-10 20:28 ` [PATCH 2/8] btrfs-progs: add new FEATURE_INCOMPAT_ENCRYPT flag Josef Bacik
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 11+ messages in thread
From: Josef Bacik @ 2023-10-10 20:28 UTC (permalink / raw)
  To: linux-btrfs

Fscrypt will use our entire inline extent range for symlinks, which
uncovered a bug in btrfs check where we set the maximum inline extent
size to

min(sectorsize - 1, BTRFS_MAX_INLINE_DATA_SIZE)

which isn't correct, we have always allowed sectorsize sized inline
extents, so fix check to use the correct maximum inline extent size.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 check/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/check/main.c b/check/main.c
index d387eb25..0979a8c6 100644
--- a/check/main.c
+++ b/check/main.c
@@ -1640,7 +1640,7 @@ static int process_file_extent(struct btrfs_root *root,
 	u64 disk_bytenr = 0;
 	u64 extent_offset = 0;
 	u64 mask = gfs_info->sectorsize - 1;
-	u32 max_inline_size = min_t(u32, mask,
+	u32 max_inline_size = min_t(u32, gfs_info->sectorsize,
 				BTRFS_MAX_INLINE_DATA_SIZE(gfs_info));
 	u8 compression;
 	int extent_type;
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/8] btrfs-progs: add new FEATURE_INCOMPAT_ENCRYPT flag
  2023-10-10 20:28 [PATCH 0/8] btrfs-progs: add fscrypt support Josef Bacik
  2023-10-10 20:28 ` [PATCH 1/8] btrfs-progs: check: fix max inline extent size Josef Bacik
@ 2023-10-10 20:28 ` Josef Bacik
  2023-10-10 20:28 ` [PATCH 3/8] btrfs-progs: start tracking extent encryption context info Josef Bacik
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Josef Bacik @ 2023-10-10 20:28 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Sweet Tea Dorminy

From: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>

Matches kernel change by the same name.

Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
---
 kernel-shared/ctree.h      | 3 ++-
 kernel-shared/uapi/btrfs.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/kernel-shared/ctree.h b/kernel-shared/ctree.h
index 59533879..6c9ff866 100644
--- a/kernel-shared/ctree.h
+++ b/kernel-shared/ctree.h
@@ -103,7 +103,8 @@ static inline u32 __BTRFS_LEAF_DATA_SIZE(u32 nodesize)
 	 BTRFS_FEATURE_INCOMPAT_RAID1C34 |		\
 	 BTRFS_FEATURE_INCOMPAT_METADATA_UUID |		\
 	 BTRFS_FEATURE_INCOMPAT_ZONED |			\
-	 BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2)
+	 BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2 |	\
+	 BTRFS_FEATURE_INCOMPAT_ENCRYPT)
 #else
 #define BTRFS_FEATURE_INCOMPAT_SUPP			\
 	(BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF |		\
diff --git a/kernel-shared/uapi/btrfs.h b/kernel-shared/uapi/btrfs.h
index 85b04f89..cd00be93 100644
--- a/kernel-shared/uapi/btrfs.h
+++ b/kernel-shared/uapi/btrfs.h
@@ -356,6 +356,7 @@ _static_assert(sizeof(struct btrfs_ioctl_fs_info_args) == 1024);
 #define BTRFS_FEATURE_INCOMPAT_RAID1C34		(1ULL << 11)
 #define BTRFS_FEATURE_INCOMPAT_ZONED		(1ULL << 12)
 #define BTRFS_FEATURE_INCOMPAT_EXTENT_TREE_V2	(1ULL << 13)
+#define BTRFS_FEATURE_INCOMPAT_ENCRYPT		(1ULL << 15)
 
 struct btrfs_ioctl_feature_flags {
 	__u64 compat_flags;
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/8] btrfs-progs: start tracking extent encryption context info
  2023-10-10 20:28 [PATCH 0/8] btrfs-progs: add fscrypt support Josef Bacik
  2023-10-10 20:28 ` [PATCH 1/8] btrfs-progs: check: fix max inline extent size Josef Bacik
  2023-10-10 20:28 ` [PATCH 2/8] btrfs-progs: add new FEATURE_INCOMPAT_ENCRYPT flag Josef Bacik
@ 2023-10-10 20:28 ` Josef Bacik
  2023-10-10 20:28 ` [PATCH 4/8] btrfs-progs: add inode encryption contexts Josef Bacik
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Josef Bacik @ 2023-10-10 20:28 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Sweet Tea Dorminy

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       | 48 ++++++++++++++++++++++++
 kernel-shared/tree-checker.c    | 66 ++++++++++++++++++++++++++++-----
 kernel-shared/uapi/btrfs_tree.h | 23 +++++++++++-
 3 files changed, 127 insertions(+), 10 deletions(-)

diff --git a/kernel-shared/accessors.h b/kernel-shared/accessors.h
index 539c20d0..04c0093c 100644
--- a/kernel-shared/accessors.h
+++ b/kernel-shared/accessors.h
@@ -932,6 +932,10 @@ 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);
@@ -970,6 +974,50 @@ 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(
+						const 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 10797589..282f9ba6 100644
--- a/kernel-shared/tree-checker.c
+++ b/kernel-shared/tree-checker.c
@@ -229,6 +229,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,
@@ -259,12 +261,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;
 	}
 
@@ -286,6 +288,13 @@ static int check_extent_data_item(struct extent_buffer *leaf,
 			btrfs_file_extent_encryption(leaf, fi));
 		return -EUCLEAN;
 	}
+	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 range [0, %u]",
+			policy, BTRFS_NR_ENCRYPTION_TYPES - 1);
+		return -EUCLEAN;
+	}
 	if (btrfs_file_extent_type(leaf, fi) == BTRFS_FILE_EXTENT_INLINE) {
 		/* Inline extent must have 0 as key offset */
 		if (unlikely(key->offset)) {
@@ -312,12 +321,51 @@ 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 ad555e70..f49ae534 100644
--- a/kernel-shared/uapi/btrfs_tree.h
+++ b/kernel-shared/uapi/btrfs_tree.h
@@ -1016,6 +1016,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
@@ -1065,7 +1083,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.41.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/8] btrfs-progs: add inode encryption contexts
  2023-10-10 20:28 [PATCH 0/8] btrfs-progs: add fscrypt support Josef Bacik
                   ` (2 preceding siblings ...)
  2023-10-10 20:28 ` [PATCH 3/8] btrfs-progs: start tracking extent encryption context info Josef Bacik
@ 2023-10-10 20:28 ` Josef Bacik
  2023-10-10 20:28 ` [PATCH 5/8] btrfs-progs: interpret encrypted file extents Josef Bacik
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Josef Bacik @ 2023-10-10 20:28 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Sweet Tea Dorminy

From: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>

Recapitulates relevant parts of kernel change 'btrfs: add inode
encryption contexts'.

Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
---
 kernel-shared/uapi/btrfs_tree.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/kernel-shared/uapi/btrfs_tree.h b/kernel-shared/uapi/btrfs_tree.h
index f49ae534..37869fea 100644
--- a/kernel-shared/uapi/btrfs_tree.h
+++ b/kernel-shared/uapi/btrfs_tree.h
@@ -162,6 +162,8 @@
 #define BTRFS_VERITY_DESC_ITEM_KEY	36
 #define BTRFS_VERITY_MERKLE_ITEM_KEY	37
 
+#define BTRFS_FSCRYPT_CTXT_ITEM_KEY	41
+
 #define BTRFS_ORPHAN_ITEM_KEY		48
 /* reserve 2-15 close to the inode for later flexibility */
 
@@ -400,6 +402,7 @@ static inline __u8 btrfs_dir_flags_to_ftype(__u8 flags)
 #define BTRFS_INODE_NOATIME		(1U << 9)
 #define BTRFS_INODE_DIRSYNC		(1U << 10)
 #define BTRFS_INODE_COMPRESS		(1U << 11)
+#define BTRFS_INODE_ENCRYPT	(1U << 12)
 
 #define BTRFS_INODE_ROOT_ITEM_INIT	(1U << 31)
 
@@ -416,6 +419,7 @@ static inline __u8 btrfs_dir_flags_to_ftype(__u8 flags)
 	 BTRFS_INODE_NOATIME |						\
 	 BTRFS_INODE_DIRSYNC |						\
 	 BTRFS_INODE_COMPRESS |						\
+	 BTRFS_INODE_ENCRYPT |						\
 	 BTRFS_INODE_ROOT_ITEM_INIT)
 
 #define BTRFS_INODE_RO_VERITY		(1U << 0)
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 5/8] btrfs-progs: interpret encrypted file extents.
  2023-10-10 20:28 [PATCH 0/8] btrfs-progs: add fscrypt support Josef Bacik
                   ` (3 preceding siblings ...)
  2023-10-10 20:28 ` [PATCH 4/8] btrfs-progs: add inode encryption contexts Josef Bacik
@ 2023-10-10 20:28 ` Josef Bacik
  2023-10-10 20:28 ` [PATCH 6/8] btrfs-progs: handle fscrypt context items Josef Bacik
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 11+ messages in thread
From: Josef Bacik @ 2023-10-10 20:28 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Sweet Tea Dorminy

From: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>

Encrypted file extents now have the 'encryption' field set to a
encryption type plus a context length, and have an extent context
appended to the item.  This necessitates adjusting the struct to have a
variable-length fscrypt_context member at the end, and printing contexts
if one is provided.

Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
---
 check/main.c               | 12 +++++++++---
 kernel-shared/print-tree.c | 25 +++++++++++++++++++++++++
 2 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/check/main.c b/check/main.c
index 0979a8c6..e841ae9c 100644
--- a/check/main.c
+++ b/check/main.c
@@ -1698,7 +1698,6 @@ static int process_file_extent(struct btrfs_root *root,
 			rec->errors |= I_ERR_BAD_FILE_EXTENT;
 		if (extent_type == BTRFS_FILE_EXTENT_PREALLOC &&
 		    (btrfs_file_extent_compression(eb, fi) ||
-		     btrfs_file_extent_encryption(eb, fi) ||
 		     btrfs_file_extent_other_encoding(eb, fi)))
 			rec->errors |= I_ERR_BAD_FILE_EXTENT;
 		if (compression && rec->nodatasum)
@@ -6352,6 +6351,7 @@ static int run_next_block(struct btrfs_root *root,
 		for (i = 0; i < nritems; i++) {
 			struct btrfs_file_extent_item *fi;
 			unsigned long inline_offset;
+			size_t extra_size = 0;
 
 			inline_offset = offsetof(struct btrfs_file_extent_item,
 						 disk_bytenr);
@@ -6487,13 +6487,19 @@ static int run_next_block(struct btrfs_root *root,
 				continue;
 
 			/* Prealloc/regular extent must have fixed item size */
+			if (btrfs_file_extent_encryption(buf, fi))
+				extra_size = btrfs_file_extent_encryption_info_size(buf, fi) +
+					sizeof(struct btrfs_encryption_info);
+
 			if (btrfs_item_size(buf, i) !=
-			    sizeof(struct btrfs_file_extent_item)) {
+			    (sizeof(struct btrfs_file_extent_item) +
+			     extra_size)) {
 				ret = -EUCLEAN;
 				error(
 			"invalid file extent item size, have %u expect %zu",
 					btrfs_item_size(buf, i),
-					sizeof(struct btrfs_file_extent_item));
+					sizeof(struct btrfs_file_extent_item) +
+					extra_size);
 				continue;
 			}
 			/* key.offset (file offset) must be aligned */
diff --git a/kernel-shared/print-tree.c b/kernel-shared/print-tree.c
index d7ffeccd..859eb015 100644
--- a/kernel-shared/print-tree.c
+++ b/kernel-shared/print-tree.c
@@ -356,6 +356,26 @@ static void compress_type_to_str(u8 compress_type, char *ret)
 	}
 }
 
+static void generate_encryption_string(struct extent_buffer *leaf,
+				       struct btrfs_file_extent_item *fi,
+				       char *ret)
+{
+	u8 policy = btrfs_file_extent_encryption(leaf, fi);
+	u32 ctxsize = btrfs_file_extent_encryption_ctx_size(leaf, fi);
+	const __u8 *ctx = (__u8 *)(leaf->data +
+				   btrfs_file_extent_encryption_ctx_offset(fi));
+
+	ret += sprintf(ret, "(%hhu, %u", policy, ctxsize);
+
+	if (ctxsize) {
+		int i;
+		ret += sprintf(ret, ": context ");
+		for (i = 0; i < ctxsize; i++)
+			ret += sprintf(ret, "%02hhx", ctx[i]);
+	}
+	sprintf(ret, ")");
+}
+
 static const char* file_extent_type_to_str(u8 type)
 {
 	switch (type) {
@@ -372,9 +392,11 @@ static void print_file_extent_item(struct extent_buffer *eb,
 {
 	unsigned char extent_type = btrfs_file_extent_type(eb, fi);
 	char compress_str[16];
+	char encrypt_str[16];
 
 	compress_type_to_str(btrfs_file_extent_compression(eb, fi),
 			     compress_str);
+	generate_encryption_string(eb, fi, encrypt_str);
 
 	printf("\t\tgeneration %llu type %hhu (%s)\n",
 			btrfs_file_extent_generation(eb, fi),
@@ -407,6 +429,9 @@ static void print_file_extent_item(struct extent_buffer *eb,
 	printf("\t\textent compression %hhu (%s)\n",
 			btrfs_file_extent_compression(eb, fi),
 			compress_str);
+	printf("\t\textent encryption %hhu (%s)\n",
+			btrfs_file_extent_encryption(eb, fi),
+			encrypt_str);
 }
 
 /* Caller should ensure sizeof(*ret) >= 16("DATA|TREE_BLOCK") */
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 6/8] btrfs-progs: handle fscrypt context items
  2023-10-10 20:28 [PATCH 0/8] btrfs-progs: add fscrypt support Josef Bacik
                   ` (4 preceding siblings ...)
  2023-10-10 20:28 ` [PATCH 5/8] btrfs-progs: interpret encrypted file extents Josef Bacik
@ 2023-10-10 20:28 ` Josef Bacik
  2023-10-10 20:28 ` [PATCH 7/8] btrfs-progs: escape unprintable characters in names Josef Bacik
  2023-10-10 20:28 ` [PATCH 8/8] btrfs-progs: check: update inline extent length checking Josef Bacik
  7 siblings, 0 replies; 11+ messages in thread
From: Josef Bacik @ 2023-10-10 20:28 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Sweet Tea Dorminy

From: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>

Encrypted inodes have a new associated item, the fscrypt context, which
can be printed as a pure hex string in dump-tree.

Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
---
 kernel-shared/print-tree.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/kernel-shared/print-tree.c b/kernel-shared/print-tree.c
index 859eb015..38086275 100644
--- a/kernel-shared/print-tree.c
+++ b/kernel-shared/print-tree.c
@@ -99,6 +99,20 @@ static void print_dir_item(struct extent_buffer *eb, u32 size,
 	}
 }
 
+static void print_fscrypt_context(struct extent_buffer *eb, int slot)
+{
+	int i;
+	unsigned long ptr = btrfs_item_ptr_offset(eb, slot);
+	u32 item_size = btrfs_item_size(eb, slot);
+	u8 ctx_buf[item_size];
+
+	read_extent_buffer(eb, ctx_buf, ptr, item_size);
+	printf("\t\tvalue: ");
+	for(i = 0; i < item_size; i++)
+		printf("%02x", ctx_buf[i]);
+	printf("\n");
+}
+
 static void print_inode_extref_item(struct extent_buffer *eb, u32 size,
 		struct btrfs_inode_extref *extref)
 {
@@ -673,6 +687,7 @@ void print_key_type(FILE *stream, u64 objectid, u8 type)
 		[BTRFS_DIR_LOG_ITEM_KEY]	= "DIR_LOG_ITEM",
 		[BTRFS_DIR_LOG_INDEX_KEY]	= "DIR_LOG_INDEX",
 		[BTRFS_XATTR_ITEM_KEY]		= "XATTR_ITEM",
+		[BTRFS_FSCRYPT_CTXT_ITEM_KEY]   = "FSCRYPT_CTXT_ITEM",
 		[BTRFS_VERITY_DESC_ITEM_KEY]	= "VERITY_DESC_ITEM",
 		[BTRFS_VERITY_MERKLE_ITEM_KEY]	= "VERITY_MERKLE_ITEM",
 		[BTRFS_ORPHAN_ITEM_KEY]		= "ORPHAN_ITEM",
@@ -1393,6 +1408,9 @@ void btrfs_print_leaf(struct extent_buffer *eb, unsigned int mode)
 		case BTRFS_XATTR_ITEM_KEY:
 			print_dir_item(eb, item_size, ptr);
 			break;
+		case BTRFS_FSCRYPT_CTXT_ITEM_KEY:
+			print_fscrypt_context(eb, i);
+			break;
 		case BTRFS_DIR_LOG_INDEX_KEY:
 		case BTRFS_DIR_LOG_ITEM_KEY: {
 			struct btrfs_dir_log_item *dlog;
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 7/8] btrfs-progs: escape unprintable characters in names
  2023-10-10 20:28 [PATCH 0/8] btrfs-progs: add fscrypt support Josef Bacik
                   ` (5 preceding siblings ...)
  2023-10-10 20:28 ` [PATCH 6/8] btrfs-progs: handle fscrypt context items Josef Bacik
@ 2023-10-10 20:28 ` Josef Bacik
  2023-10-10 20:28 ` [PATCH 8/8] btrfs-progs: check: update inline extent length checking Josef Bacik
  7 siblings, 0 replies; 11+ messages in thread
From: Josef Bacik @ 2023-10-10 20:28 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Sweet Tea Dorminy

From: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>

There are several item types which have an associated name: inode refs
and dir items. While they could always be unprintable, the advent of
encryption makes it much more likely that the names contain characters
outside the normal ASCII range. As such, it's useful to print the
characters outside normal ASCII in hex format.

Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
---
 kernel-shared/print-tree.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/kernel-shared/print-tree.c b/kernel-shared/print-tree.c
index 38086275..9aa1ce16 100644
--- a/kernel-shared/print-tree.c
+++ b/kernel-shared/print-tree.c
@@ -30,6 +30,19 @@
 #include "kernel-shared/file-item.h"
 #include "common/utils.h"
 
+static void print_name(const char *buf, size_t len)
+{
+	size_t i;
+	printf("name: ");
+	for(i = 0; i < len; i++) {
+		if (buf[i] >= ' ' && buf[i] <= '~')
+			printf("%c", buf[i]);
+		else
+			printf("\\x%02hhx", buf[i]);
+	}
+	printf("\n");
+}
+
 static void print_dir_item_type(struct extent_buffer *eb,
                                 struct btrfs_dir_item *di)
 {
@@ -79,7 +92,7 @@ static void print_dir_item(struct extent_buffer *eb, u32 size,
 		} else {
 			read_extent_buffer(eb, namebuf,
 					(unsigned long)(di + 1), len);
-			printf("\t\tname: %.*s\n", len, namebuf);
+			print_name(namebuf, len);
 		}
 
 		if (data_len) {
@@ -137,7 +150,7 @@ static void print_inode_extref_item(struct extent_buffer *eb, u32 size,
 		} else {
 			read_extent_buffer(eb, namebuf,
 					(unsigned long)extref->name, len);
-			printf("name: %.*s\n", len, namebuf);
+			print_name(namebuf, len);
 		}
 
 		len = sizeof(*extref) + name_len;
@@ -167,7 +180,7 @@ static void print_inode_ref_item(struct extent_buffer *eb, u32 size,
 		} else {
 			read_extent_buffer(eb, namebuf,
 					(unsigned long)(ref + 1), len);
-			printf("name: %.*s\n", len, namebuf);
+			print_name(namebuf, len);
 		}
 		len = sizeof(*ref) + name_len;
 		ref = (struct btrfs_inode_ref *)((char *)ref + len);
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 8/8] btrfs-progs: check: update inline extent length checking
  2023-10-10 20:28 [PATCH 0/8] btrfs-progs: add fscrypt support Josef Bacik
                   ` (6 preceding siblings ...)
  2023-10-10 20:28 ` [PATCH 7/8] btrfs-progs: escape unprintable characters in names Josef Bacik
@ 2023-10-10 20:28 ` Josef Bacik
  7 siblings, 0 replies; 11+ messages in thread
From: Josef Bacik @ 2023-10-10 20:28 UTC (permalink / raw)
  To: linux-btrfs; +Cc: Sweet Tea Dorminy

From: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>

As part of the encryption changes, encrypted inline file extents record
their actual data length in ram_bytes, like compressed inline file
extents, while the item's length records the actual size. As such,
encrypted inline extents must be treated like compressed ones for
inode length consistency checking.

Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me>
---
 check/main.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/check/main.c b/check/main.c
index e841ae9c..a8c4c7cf 100644
--- a/check/main.c
+++ b/check/main.c
@@ -1642,7 +1642,7 @@ static int process_file_extent(struct btrfs_root *root,
 	u64 mask = gfs_info->sectorsize - 1;
 	u32 max_inline_size = min_t(u32, gfs_info->sectorsize,
 				BTRFS_MAX_INLINE_DATA_SIZE(gfs_info));
-	u8 compression;
+	u8 compression, encryption;
 	int extent_type;
 	int ret;
 
@@ -1667,25 +1667,25 @@ static int process_file_extent(struct btrfs_root *root,
 	fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
 	extent_type = btrfs_file_extent_type(eb, fi);
 	compression = btrfs_file_extent_compression(eb, fi);
+	encryption = btrfs_file_extent_encryption(eb, fi);
 
 	if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
-		num_bytes = btrfs_file_extent_ram_bytes(eb, fi);
-		if (num_bytes == 0)
+		u64 num_decoded_bytes = btrfs_file_extent_ram_bytes(eb, fi);
+		u64 num_disk_bytes =  btrfs_file_extent_inline_item_len(eb, slot);
+		if (num_decoded_bytes == 0)
 			rec->errors |= I_ERR_BAD_FILE_EXTENT;
-		if (compression) {
-			if (btrfs_file_extent_inline_item_len(eb, slot) >
-			    max_inline_size ||
-			    num_bytes > gfs_info->sectorsize)
+		if (compression || encryption) {
+			if (num_disk_bytes > max_inline_size ||
+			    num_decoded_bytes > gfs_info->sectorsize)
 				rec->errors |= I_ERR_FILE_EXTENT_TOO_LARGE;
 		} else {
-			if (num_bytes > max_inline_size)
+			if (num_decoded_bytes > max_inline_size)
 				rec->errors |= I_ERR_FILE_EXTENT_TOO_LARGE;
-			if (btrfs_file_extent_inline_item_len(eb, slot) !=
-			    num_bytes)
+			if (num_disk_bytes != num_decoded_bytes)
 				rec->errors |= I_ERR_INLINE_RAM_BYTES_WRONG;
 		}
-		rec->found_size += num_bytes;
-		num_bytes = (num_bytes + mask) & ~mask;
+		rec->found_size += num_decoded_bytes;
+		num_bytes = (num_decoded_bytes + mask) & ~mask;
 	} else if (extent_type == BTRFS_FILE_EXTENT_REG ||
 		   extent_type == BTRFS_FILE_EXTENT_PREALLOC) {
 		num_bytes = btrfs_file_extent_num_bytes(eb, fi);
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/8] btrfs-progs: check: fix max inline extent size
  2023-10-10 20:28 ` [PATCH 1/8] btrfs-progs: check: fix max inline extent size Josef Bacik
@ 2023-10-11 23:14   ` Neal Gompa
  0 siblings, 0 replies; 11+ messages in thread
From: Neal Gompa @ 2023-10-11 23:14 UTC (permalink / raw)
  To: Josef Bacik; +Cc: linux-btrfs

On Tue, Oct 10, 2023 at 4:28 PM Josef Bacik <josef@toxicpanda.com> wrote:
>
> Fscrypt will use our entire inline extent range for symlinks, which
> uncovered a bug in btrfs check where we set the maximum inline extent
> size to
>
> min(sectorsize - 1, BTRFS_MAX_INLINE_DATA_SIZE)
>
> which isn't correct, we have always allowed sectorsize sized inline
> extents, so fix check to use the correct maximum inline extent size.
>
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>
> ---
>  check/main.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/check/main.c b/check/main.c
> index d387eb25..0979a8c6 100644
> --- a/check/main.c
> +++ b/check/main.c
> @@ -1640,7 +1640,7 @@ static int process_file_extent(struct btrfs_root *root,
>         u64 disk_bytenr = 0;
>         u64 extent_offset = 0;
>         u64 mask = gfs_info->sectorsize - 1;
> -       u32 max_inline_size = min_t(u32, mask,
> +       u32 max_inline_size = min_t(u32, gfs_info->sectorsize,
>                                 BTRFS_MAX_INLINE_DATA_SIZE(gfs_info));
>         u8 compression;
>         int extent_type;
> --
> 2.41.0
>

LGTM.

Reviewed-by: Neal Gompa <neal@gompa.dev>


-- 
真実はいつも一つ!/ Always, there's only one truth!

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH 1/8] btrfs-progs: check: fix max inline extent size
  2025-10-15 12:11 [PATCH 0/8] btrfs-progs: fscrypt updates Daniel Vacek
@ 2025-10-15 12:11 ` Daniel Vacek
  0 siblings, 0 replies; 11+ messages in thread
From: Daniel Vacek @ 2025-10-15 12:11 UTC (permalink / raw)
  To: David Sterba; +Cc: linux-btrfs, Daniel Vacek, Josef Bacik, Sweet Tea Dorminy

From: Josef Bacik <josef@toxicpanda.com>

Fscrypt will use our entire inline extent range for symlinks, which
uncovered a bug in btrfs check where we set the maximum inline extent
size to

min(sectorsize - 1, BTRFS_MAX_INLINE_DATA_SIZE)

which isn't correct, we have always allowed sectorsize sized inline
extents, so fix check to use the correct maximum inline extent size.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 check/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/check/main.c b/check/main.c
index 91ce6d74..054a22d3 100644
--- a/check/main.c
+++ b/check/main.c
@@ -1719,7 +1719,7 @@ static int process_file_extent(struct btrfs_root *root,
 	u64 disk_bytenr = 0;
 	u64 extent_offset = 0;
 	u64 mask = gfs_info->sectorsize - 1;
-	u32 max_inline_size = min_t(u32, mask,
+	u32 max_inline_size = min_t(u32, gfs_info->sectorsize,
 				BTRFS_MAX_INLINE_DATA_SIZE(gfs_info));
 	u8 compression;
 	int extent_type;
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2025-10-15 12:12 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-10-10 20:28 [PATCH 0/8] btrfs-progs: add fscrypt support Josef Bacik
2023-10-10 20:28 ` [PATCH 1/8] btrfs-progs: check: fix max inline extent size Josef Bacik
2023-10-11 23:14   ` Neal Gompa
2023-10-10 20:28 ` [PATCH 2/8] btrfs-progs: add new FEATURE_INCOMPAT_ENCRYPT flag Josef Bacik
2023-10-10 20:28 ` [PATCH 3/8] btrfs-progs: start tracking extent encryption context info Josef Bacik
2023-10-10 20:28 ` [PATCH 4/8] btrfs-progs: add inode encryption contexts Josef Bacik
2023-10-10 20:28 ` [PATCH 5/8] btrfs-progs: interpret encrypted file extents Josef Bacik
2023-10-10 20:28 ` [PATCH 6/8] btrfs-progs: handle fscrypt context items Josef Bacik
2023-10-10 20:28 ` [PATCH 7/8] btrfs-progs: escape unprintable characters in names Josef Bacik
2023-10-10 20:28 ` [PATCH 8/8] btrfs-progs: check: update inline extent length checking Josef Bacik
  -- strict thread matches above, loose matches on Subject: below --
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

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).