diff mbox series

[04/17] btrfs: move btrfs on disk definitions out of ctree.h

Message ID 058e41f7732823196f030916c04134418688cbe9.1663167823.git.josef@toxicpanda.com (mailing list archive)
State New, archived
Headers show
Series btrfs: initial ctree.h cleanups, simple stuff | expand

Commit Message

Josef Bacik Sept. 14, 2022, 3:06 p.m. UTC
The bulk of our on-disk definitions exist in btrfs_tree.h, which user
space can use.  Keep things consistent and move the rest of the on disk
definitions out of ctree.h into btrfs_tree.h.  Note I did have to update
all u8's to __u8, but otherwise this is a strict copy and paste.

Signed-off-by: Josef Bacik <josef@toxicpanda.com>
---
 fs/btrfs/ctree.h                | 215 +-------------------------------
 include/uapi/linux/btrfs_tree.h | 213 +++++++++++++++++++++++++++++++
 2 files changed, 214 insertions(+), 214 deletions(-)

Comments

Qu Wenruo Sept. 15, 2022, 9:07 a.m. UTC | #1
On 2022/9/14 23:06, Josef Bacik wrote:
> The bulk of our on-disk definitions exist in btrfs_tree.h, which user
> space can use.

Previously I tried to move some members to btrfs_tree.h, but didn't get 
approved, mostly due to the fact that, we have those members exposed 
through uapi is for TREE_SEARCH ioctl.

But I'm not buying that reason at all.

To me, all on-disk format, no matter if it's exposed through tree-search 
should be in btrfs_tree.h.

Although I'd prefer to rename btrfs_tree.h to btrfs_ondisk_format.h.

Thus to David:

Can we make it clear that, btrfs_tree.h is not only for tree search 
ioctl, but also all the on-disk format thing?

Reject once that's fine, but reject twice from two different guys, I 
think it's not correct.

>  Keep things consistent and move the rest of the on disk
> definitions out of ctree.h into btrfs_tree.h.  Note I did have to update
> all u8's to __u8, but otherwise this is a strict copy and paste.
> 
> Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>

Thanks,
Qu


> ---
>   fs/btrfs/ctree.h                | 215 +-------------------------------
>   include/uapi/linux/btrfs_tree.h | 213 +++++++++++++++++++++++++++++++
>   2 files changed, 214 insertions(+), 214 deletions(-)
> 
> diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
> index 5cf18a120dff..c3a8440d3223 100644
> --- a/fs/btrfs/ctree.h
> +++ b/fs/btrfs/ctree.h
> @@ -50,8 +50,6 @@ struct btrfs_ref;
>   struct btrfs_bio;
>   struct btrfs_ioctl_encoded_io_args;
>   
> -#define BTRFS_MAGIC 0x4D5F53665248425FULL /* ascii _BHRfS_M, no null */
> -
>   /*
>    * Maximum number of mirrors that can be available for all profiles counting
>    * the target device of dev-replace as one. During an active device replace
> @@ -63,8 +61,6 @@ struct btrfs_ioctl_encoded_io_args;
>    */
>   #define BTRFS_MAX_MIRRORS (4 + 1)
>   
> -#define BTRFS_MAX_LEVEL 8
> -
>   #define BTRFS_OLDEST_GENERATION	0ULL
>   
>   /*
> @@ -133,81 +129,9 @@ enum {
>   	BTRFS_FS_STATE_COUNT
>   };
>   
> -#define BTRFS_BACKREF_REV_MAX		256
> -#define BTRFS_BACKREF_REV_SHIFT		56
> -#define BTRFS_BACKREF_REV_MASK		(((u64)BTRFS_BACKREF_REV_MAX - 1) << \
> -					 BTRFS_BACKREF_REV_SHIFT)
> -
> -#define BTRFS_OLD_BACKREF_REV		0
> -#define BTRFS_MIXED_BACKREF_REV		1
> -
> -/*
> - * every tree block (leaf or node) starts with this header.
> - */
> -struct btrfs_header {
> -	/* these first four must match the super block */
> -	u8 csum[BTRFS_CSUM_SIZE];
> -	u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */
> -	__le64 bytenr; /* which block this node is supposed to live in */
> -	__le64 flags;
> -
> -	/* allowed to be different from the super from here on down */
> -	u8 chunk_tree_uuid[BTRFS_UUID_SIZE];
> -	__le64 generation;
> -	__le64 owner;
> -	__le32 nritems;
> -	u8 level;
> -} __attribute__ ((__packed__));
> -
> -/*
> - * this is a very generous portion of the super block, giving us
> - * room to translate 14 chunks with 3 stripes each.
> - */
> -#define BTRFS_SYSTEM_CHUNK_ARRAY_SIZE 2048
> -
> -/*
> - * just in case we somehow lose the roots and are not able to mount,
> - * we store an array of the roots from previous transactions
> - * in the super.
> - */
> -#define BTRFS_NUM_BACKUP_ROOTS 4
> -struct btrfs_root_backup {
> -	__le64 tree_root;
> -	__le64 tree_root_gen;
> -
> -	__le64 chunk_root;
> -	__le64 chunk_root_gen;
> -
> -	__le64 extent_root;
> -	__le64 extent_root_gen;
> -
> -	__le64 fs_root;
> -	__le64 fs_root_gen;
> -
> -	__le64 dev_root;
> -	__le64 dev_root_gen;
> -
> -	__le64 csum_root;
> -	__le64 csum_root_gen;
> -
> -	__le64 total_bytes;
> -	__le64 bytes_used;
> -	__le64 num_devices;
> -	/* future */
> -	__le64 unused_64[4];
> -
> -	u8 tree_root_level;
> -	u8 chunk_root_level;
> -	u8 extent_root_level;
> -	u8 fs_root_level;
> -	u8 dev_root_level;
> -	u8 csum_root_level;
> -	/* future and to align */
> -	u8 unused_8[10];
> -} __attribute__ ((__packed__));
> -
>   #define BTRFS_SUPER_INFO_OFFSET			SZ_64K
>   #define BTRFS_SUPER_INFO_SIZE			4096
> +static_assert(sizeof(struct btrfs_super_block) == BTRFS_SUPER_INFO_SIZE);
>   
>   /*
>    * The reserved space at the beginning of each device.
> @@ -216,69 +140,6 @@ struct btrfs_root_backup {
>    */
>   #define BTRFS_DEVICE_RANGE_RESERVED			(SZ_1M)
>   
> -/*
> - * the super block basically lists the main trees of the FS
> - * it currently lacks any block count etc etc
> - */
> -struct btrfs_super_block {
> -	/* the first 4 fields must match struct btrfs_header */
> -	u8 csum[BTRFS_CSUM_SIZE];
> -	/* FS specific UUID, visible to user */
> -	u8 fsid[BTRFS_FSID_SIZE];
> -	__le64 bytenr; /* this block number */
> -	__le64 flags;
> -
> -	/* allowed to be different from the btrfs_header from here own down */
> -	__le64 magic;
> -	__le64 generation;
> -	__le64 root;
> -	__le64 chunk_root;
> -	__le64 log_root;
> -
> -	/*
> -	 * This member has never been utilized since the very beginning, thus
> -	 * it's always 0 regardless of kernel version.  We always use
> -	 * generation + 1 to read log tree root.  So here we mark it deprecated.
> -	 */
> -	__le64 __unused_log_root_transid;
> -	__le64 total_bytes;
> -	__le64 bytes_used;
> -	__le64 root_dir_objectid;
> -	__le64 num_devices;
> -	__le32 sectorsize;
> -	__le32 nodesize;
> -	__le32 __unused_leafsize;
> -	__le32 stripesize;
> -	__le32 sys_chunk_array_size;
> -	__le64 chunk_root_generation;
> -	__le64 compat_flags;
> -	__le64 compat_ro_flags;
> -	__le64 incompat_flags;
> -	__le16 csum_type;
> -	u8 root_level;
> -	u8 chunk_root_level;
> -	u8 log_root_level;
> -	struct btrfs_dev_item dev_item;
> -
> -	char label[BTRFS_LABEL_SIZE];
> -
> -	__le64 cache_generation;
> -	__le64 uuid_tree_generation;
> -
> -	/* the UUID written into btree blocks */
> -	u8 metadata_uuid[BTRFS_FSID_SIZE];
> -
> -	/* future expansion */
> -	u8 reserved8[8];
> -	__le64 reserved[27];
> -	u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE];
> -	struct btrfs_root_backup super_roots[BTRFS_NUM_BACKUP_ROOTS];
> -
> -	/* Padded to 4096 bytes */
> -	u8 padding[565];
> -} __attribute__ ((__packed__));
> -static_assert(sizeof(struct btrfs_super_block) == BTRFS_SUPER_INFO_SIZE);
> -
>   /*
>    * Compat flags that we support.  If any incompat flags are set other than the
>    * ones specified below then we will fail to mount
> @@ -336,43 +197,6 @@ static_assert(sizeof(struct btrfs_super_block) == BTRFS_SUPER_INFO_SIZE);
>   	(BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF)
>   #define BTRFS_FEATURE_INCOMPAT_SAFE_CLEAR		0ULL
>   
> -/*
> - * A leaf is full of items. offset and size tell us where to find
> - * the item in the leaf (relative to the start of the data area)
> - */
> -struct btrfs_item {
> -	struct btrfs_disk_key key;
> -	__le32 offset;
> -	__le32 size;
> -} __attribute__ ((__packed__));
> -
> -/*
> - * leaves have an item area and a data area:
> - * [item0, item1....itemN] [free space] [dataN...data1, data0]
> - *
> - * The data is separate from the items to get the keys closer together
> - * during searches.
> - */
> -struct btrfs_leaf {
> -	struct btrfs_header header;
> -	struct btrfs_item items[];
> -} __attribute__ ((__packed__));
> -
> -/*
> - * all non-leaf blocks are nodes, they hold only keys and pointers to
> - * other blocks
> - */
> -struct btrfs_key_ptr {
> -	struct btrfs_disk_key key;
> -	__le64 blockptr;
> -	__le64 generation;
> -} __attribute__ ((__packed__));
> -
> -struct btrfs_node {
> -	struct btrfs_header header;
> -	struct btrfs_key_ptr ptrs[];
> -} __attribute__ ((__packed__));
> -
>   /* Read ahead values for struct btrfs_path.reada */
>   enum {
>   	READA_NONE,
> @@ -1633,43 +1457,6 @@ do {									\
>   #define btrfs_clear_pending(info, opt)	\
>   	clear_bit(BTRFS_PENDING_##opt, &(info)->pending_changes)
>   
> -/*
> - * Inode flags
> - */
> -#define BTRFS_INODE_NODATASUM		(1U << 0)
> -#define BTRFS_INODE_NODATACOW		(1U << 1)
> -#define BTRFS_INODE_READONLY		(1U << 2)
> -#define BTRFS_INODE_NOCOMPRESS		(1U << 3)
> -#define BTRFS_INODE_PREALLOC		(1U << 4)
> -#define BTRFS_INODE_SYNC		(1U << 5)
> -#define BTRFS_INODE_IMMUTABLE		(1U << 6)
> -#define BTRFS_INODE_APPEND		(1U << 7)
> -#define BTRFS_INODE_NODUMP		(1U << 8)
> -#define BTRFS_INODE_NOATIME		(1U << 9)
> -#define BTRFS_INODE_DIRSYNC		(1U << 10)
> -#define BTRFS_INODE_COMPRESS		(1U << 11)
> -
> -#define BTRFS_INODE_ROOT_ITEM_INIT	(1U << 31)
> -
> -#define BTRFS_INODE_FLAG_MASK						\
> -	(BTRFS_INODE_NODATASUM |					\
> -	 BTRFS_INODE_NODATACOW |					\
> -	 BTRFS_INODE_READONLY |						\
> -	 BTRFS_INODE_NOCOMPRESS |					\
> -	 BTRFS_INODE_PREALLOC |						\
> -	 BTRFS_INODE_SYNC |						\
> -	 BTRFS_INODE_IMMUTABLE |					\
> -	 BTRFS_INODE_APPEND |						\
> -	 BTRFS_INODE_NODUMP |						\
> -	 BTRFS_INODE_NOATIME |						\
> -	 BTRFS_INODE_DIRSYNC |						\
> -	 BTRFS_INODE_COMPRESS |						\
> -	 BTRFS_INODE_ROOT_ITEM_INIT)
> -
> -#define BTRFS_INODE_RO_VERITY		(1U << 0)
> -
> -#define BTRFS_INODE_RO_FLAG_MASK	(BTRFS_INODE_RO_VERITY)
> -
>   struct btrfs_map_token {
>   	struct extent_buffer *eb;
>   	char *kaddr;
> diff --git a/include/uapi/linux/btrfs_tree.h b/include/uapi/linux/btrfs_tree.h
> index 1f7a38ec6ac3..e6bf902b9c92 100644
> --- a/include/uapi/linux/btrfs_tree.h
> +++ b/include/uapi/linux/btrfs_tree.h
> @@ -10,6 +10,10 @@
>   #include <stddef.h>
>   #endif
>   
> +#define BTRFS_MAGIC 0x4D5F53665248425FULL /* ascii _BHRfS_M, no null */
> +
> +#define BTRFS_MAX_LEVEL 8
> +
>   /*
>    * This header contains the structure definitions and constants used
>    * by file system objects that can be retrieved using
> @@ -360,6 +364,43 @@ enum btrfs_csum_type {
>   #define BTRFS_FT_XATTR		8
>   #define BTRFS_FT_MAX		9
>   
> +/*
> + * Inode flags
> + */
> +#define BTRFS_INODE_NODATASUM		(1U << 0)
> +#define BTRFS_INODE_NODATACOW		(1U << 1)
> +#define BTRFS_INODE_READONLY		(1U << 2)
> +#define BTRFS_INODE_NOCOMPRESS		(1U << 3)
> +#define BTRFS_INODE_PREALLOC		(1U << 4)
> +#define BTRFS_INODE_SYNC		(1U << 5)
> +#define BTRFS_INODE_IMMUTABLE		(1U << 6)
> +#define BTRFS_INODE_APPEND		(1U << 7)
> +#define BTRFS_INODE_NODUMP		(1U << 8)
> +#define BTRFS_INODE_NOATIME		(1U << 9)
> +#define BTRFS_INODE_DIRSYNC		(1U << 10)
> +#define BTRFS_INODE_COMPRESS		(1U << 11)
> +
> +#define BTRFS_INODE_ROOT_ITEM_INIT	(1U << 31)
> +
> +#define BTRFS_INODE_FLAG_MASK						\
> +	(BTRFS_INODE_NODATASUM |					\
> +	 BTRFS_INODE_NODATACOW |					\
> +	 BTRFS_INODE_READONLY |						\
> +	 BTRFS_INODE_NOCOMPRESS |					\
> +	 BTRFS_INODE_PREALLOC |						\
> +	 BTRFS_INODE_SYNC |						\
> +	 BTRFS_INODE_IMMUTABLE |					\
> +	 BTRFS_INODE_APPEND |						\
> +	 BTRFS_INODE_NODUMP |						\
> +	 BTRFS_INODE_NOATIME |						\
> +	 BTRFS_INODE_DIRSYNC |						\
> +	 BTRFS_INODE_COMPRESS |						\
> +	 BTRFS_INODE_ROOT_ITEM_INIT)
> +
> +#define BTRFS_INODE_RO_VERITY		(1U << 0)
> +
> +#define BTRFS_INODE_RO_FLAG_MASK	(BTRFS_INODE_RO_VERITY)
> +
>   /*
>    * The key defines the order in the tree, and so it also defines (optimal)
>    * block layout.
> @@ -389,6 +430,108 @@ struct btrfs_key {
>   	__u64 offset;
>   } __attribute__ ((__packed__));
>   
> +/*
> + * every tree block (leaf or node) starts with this header.
> + */
> +struct btrfs_header {
> +	/* these first four must match the super block */
> +	__u8 csum[BTRFS_CSUM_SIZE];
> +	__u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */
> +	__le64 bytenr; /* which block this node is supposed to live in */
> +	__le64 flags;
> +
> +	/* allowed to be different from the super from here on down */
> +	__u8 chunk_tree_uuid[BTRFS_UUID_SIZE];
> +	__le64 generation;
> +	__le64 owner;
> +	__le32 nritems;
> +	__u8 level;
> +} __attribute__ ((__packed__));
> +
> +/*
> + * this is a very generous portion of the super block, giving us
> + * room to translate 14 chunks with 3 stripes each.
> + */
> +#define BTRFS_SYSTEM_CHUNK_ARRAY_SIZE 2048
> +
> +/*
> + * just in case we somehow lose the roots and are not able to mount,
> + * we store an array of the roots from previous transactions
> + * in the super.
> + */
> +#define BTRFS_NUM_BACKUP_ROOTS 4
> +struct btrfs_root_backup {
> +	__le64 tree_root;
> +	__le64 tree_root_gen;
> +
> +	__le64 chunk_root;
> +	__le64 chunk_root_gen;
> +
> +	__le64 extent_root;
> +	__le64 extent_root_gen;
> +
> +	__le64 fs_root;
> +	__le64 fs_root_gen;
> +
> +	__le64 dev_root;
> +	__le64 dev_root_gen;
> +
> +	__le64 csum_root;
> +	__le64 csum_root_gen;
> +
> +	__le64 total_bytes;
> +	__le64 bytes_used;
> +	__le64 num_devices;
> +	/* future */
> +	__le64 unused_64[4];
> +
> +	__u8 tree_root_level;
> +	__u8 chunk_root_level;
> +	__u8 extent_root_level;
> +	__u8 fs_root_level;
> +	__u8 dev_root_level;
> +	__u8 csum_root_level;
> +	/* future and to align */
> +	__u8 unused_8[10];
> +} __attribute__ ((__packed__));
> +
> +/*
> + * A leaf is full of items. offset and size tell us where to find
> + * the item in the leaf (relative to the start of the data area)
> + */
> +struct btrfs_item {
> +	struct btrfs_disk_key key;
> +	__le32 offset;
> +	__le32 size;
> +} __attribute__ ((__packed__));
> +
> +/*
> + * leaves have an item area and a data area:
> + * [item0, item1....itemN] [free space] [dataN...data1, data0]
> + *
> + * The data is separate from the items to get the keys closer together
> + * during searches.
> + */
> +struct btrfs_leaf {
> +	struct btrfs_header header;
> +	struct btrfs_item items[];
> +} __attribute__ ((__packed__));
> +
> +/*
> + * all non-leaf blocks are nodes, they hold only keys and pointers to
> + * other blocks
> + */
> +struct btrfs_key_ptr {
> +	struct btrfs_disk_key key;
> +	__le64 blockptr;
> +	__le64 generation;
> +} __attribute__ ((__packed__));
> +
> +struct btrfs_node {
> +	struct btrfs_header header;
> +	struct btrfs_key_ptr ptrs[];
> +} __attribute__ ((__packed__));
> +
>   struct btrfs_dev_item {
>   	/* the internal btrfs device id */
>   	__le64 devid;
> @@ -472,6 +615,68 @@ struct btrfs_chunk {
>   	/* additional stripes go here */
>   } __attribute__ ((__packed__));
>   
> +/*
> + * the super block basically lists the main trees of the FS
> + * it currently lacks any block count etc etc
> + */
> +struct btrfs_super_block {
> +	/* the first 4 fields must match struct btrfs_header */
> +	__u8 csum[BTRFS_CSUM_SIZE];
> +	/* FS specific UUID, visible to user */
> +	__u8 fsid[BTRFS_FSID_SIZE];
> +	__le64 bytenr; /* this block number */
> +	__le64 flags;
> +
> +	/* allowed to be different from the btrfs_header from here own down */
> +	__le64 magic;
> +	__le64 generation;
> +	__le64 root;
> +	__le64 chunk_root;
> +	__le64 log_root;
> +
> +	/*
> +	 * This member has never been utilized since the very beginning, thus
> +	 * it's always 0 regardless of kernel version.  We always use
> +	 * generation + 1 to read log tree root.  So here we mark it deprecated.
> +	 */
> +	__le64 __unused_log_root_transid;
> +	__le64 total_bytes;
> +	__le64 bytes_used;
> +	__le64 root_dir_objectid;
> +	__le64 num_devices;
> +	__le32 sectorsize;
> +	__le32 nodesize;
> +	__le32 __unused_leafsize;
> +	__le32 stripesize;
> +	__le32 sys_chunk_array_size;
> +	__le64 chunk_root_generation;
> +	__le64 compat_flags;
> +	__le64 compat_ro_flags;
> +	__le64 incompat_flags;
> +	__le16 csum_type;
> +	__u8 root_level;
> +	__u8 chunk_root_level;
> +	__u8 log_root_level;
> +	struct btrfs_dev_item dev_item;
> +
> +	char label[BTRFS_LABEL_SIZE];
> +
> +	__le64 cache_generation;
> +	__le64 uuid_tree_generation;
> +
> +	/* the UUID written into btree blocks */
> +	__u8 metadata_uuid[BTRFS_FSID_SIZE];
> +
> +	/* future expansion */
> +	__u8 reserved8[8];
> +	__le64 reserved[27];
> +	__u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE];
> +	struct btrfs_root_backup super_roots[BTRFS_NUM_BACKUP_ROOTS];
> +
> +	/* Padded to 4096 bytes */
> +	__u8 padding[565];
> +} __attribute__ ((__packed__));
> +
>   #define BTRFS_FREE_SPACE_EXTENT	1
>   #define BTRFS_FREE_SPACE_BITMAP	2
>   
> @@ -526,6 +731,14 @@ struct btrfs_extent_item_v0 {
>   /* use full backrefs for extent pointers in the block */
>   #define BTRFS_BLOCK_FLAG_FULL_BACKREF	(1ULL << 8)
>   
> +#define BTRFS_BACKREF_REV_MAX		256
> +#define BTRFS_BACKREF_REV_SHIFT		56
> +#define BTRFS_BACKREF_REV_MASK		(((u64)BTRFS_BACKREF_REV_MAX - 1) << \
> +					 BTRFS_BACKREF_REV_SHIFT)
> +
> +#define BTRFS_OLD_BACKREF_REV		0
> +#define BTRFS_MIXED_BACKREF_REV		1
> +
>   /*
>    * this flag is only used internally by scrub and may be changed at any time
>    * it is only declared here to avoid collisions
David Sterba Oct. 7, 2022, 5:07 p.m. UTC | #2
On Thu, Sep 15, 2022 at 05:07:42PM +0800, Qu Wenruo wrote:
> 
> 
> On 2022/9/14 23:06, Josef Bacik wrote:
> > The bulk of our on-disk definitions exist in btrfs_tree.h, which user
> > space can use.
> 
> Previously I tried to move some members to btrfs_tree.h, but didn't get 
> approved, mostly due to the fact that, we have those members exposed 
> through uapi is for TREE_SEARCH ioctl.
> 
> But I'm not buying that reason at all.
> 
> To me, all on-disk format, no matter if it's exposed through tree-search 
> should be in btrfs_tree.h.

All the structures are internal and not a guaranteed public API, we may
want to change them any time. So if we move the definitions to UAPI then
with a disclaimer that it's not a stable api and any compilation
failures outside of kernel are up to the users to fix.

Which does not work in practice as easy as said and we have reverted
some changes. See 34c51814b2b8 ("btrfs: re-instantiate the removed
BTRFS_SUBVOL_CREATE_ASYNC definition").

> Although I'd prefer to rename btrfs_tree.h to btrfs_ondisk_format.h.
> 
> Thus to David:
> 
> Can we make it clear that, btrfs_tree.h is not only for tree search 
> ioctl, but also all the on-disk format thing?

It is for on-disk format defitions, but that's a different problem than
the internal/external API.

> Reject once that's fine, but reject twice from two different guys, I 
> think it's not correct.
> 
> >  Keep things consistent and move the rest of the on disk
> > definitions out of ctree.h into btrfs_tree.h.  Note I did have to update
> > all u8's to __u8, but otherwise this is a strict copy and paste.
> > 
> > Signed-off-by: Josef Bacik <josef@toxicpanda.com>
> Reviewed-by: Qu Wenruo <wqu@suse.com>
Qu Wenruo Oct. 7, 2022, 11:50 p.m. UTC | #3
On 2022/10/8 01:07, David Sterba wrote:
> On Thu, Sep 15, 2022 at 05:07:42PM +0800, Qu Wenruo wrote:
>>
>>
>> On 2022/9/14 23:06, Josef Bacik wrote:
>>> The bulk of our on-disk definitions exist in btrfs_tree.h, which user
>>> space can use.
>>
>> Previously I tried to move some members to btrfs_tree.h, but didn't get
>> approved, mostly due to the fact that, we have those members exposed
>> through uapi is for TREE_SEARCH ioctl.
>>
>> But I'm not buying that reason at all.
>>
>> To me, all on-disk format, no matter if it's exposed through tree-search
>> should be in btrfs_tree.h.
> 
> All the structures are internal and not a guaranteed public API, we may
> want to change them any time. So if we move the definitions to UAPI then
> with a disclaimer that it's not a stable api and any compilation
> failures outside of kernel are up to the users to fix.

The point is, if we're changing the super block format, it's no 
difference than changing a on-disk structure.

It's still the same incompat/compat_ro/compat change depending on the 
member we change.

> 
> Which does not work in practice as easy as said and we have reverted
> some changes. See 34c51814b2b8 ("btrfs: re-instantiate the removed
> BTRFS_SUBVOL_CREATE_ASYNC definition").

That commit indeed teaches us something, even if we deprecated some 
features, it still has to be kept in the UAPI.

But that argument doesn't really affect the super block move AFAIK.

Since it's not even part of an ioctl, thus I don't think user-space tool 
would really both that.

> 
>> Although I'd prefer to rename btrfs_tree.h to btrfs_ondisk_format.h.
>>
>> Thus to David:
>>
>> Can we make it clear that, btrfs_tree.h is not only for tree search
>> ioctl, but also all the on-disk format thing?
> 
> It is for on-disk format defitions, but that's a different problem than
> the internal/external API.

Then, what's the proper way to export btrfs on-disk format?

 From an ioctl point of view, all those on-disk format things don't even 
need to be exported.

TREE_SEARCH ioctl is just returning a certain TLV formatted memory.
Yes, the basic things like btrfs_ioctl_search_header, but the content is 
still internal, not directly user-facing.

All the returned TLV members are really implementation related details, 
and even the TREE_SEARCH ioctl itself is more like a debug tool than 
proper interface.
A lot of things are done using TREE_SEARCH ioctl because we don't have 
better more defined interface.

Thanks,
Qu

> 
>> Reject once that's fine, but reject twice from two different guys, I
>> think it's not correct.
>>
>>>   Keep things consistent and move the rest of the on disk
>>> definitions out of ctree.h into btrfs_tree.h.  Note I did have to update
>>> all u8's to __u8, but otherwise this is a strict copy and paste.
>>>
>>> Signed-off-by: Josef Bacik <josef@toxicpanda.com>
>> Reviewed-by: Qu Wenruo <wqu@suse.com>
diff mbox series

Patch

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 5cf18a120dff..c3a8440d3223 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -50,8 +50,6 @@  struct btrfs_ref;
 struct btrfs_bio;
 struct btrfs_ioctl_encoded_io_args;
 
-#define BTRFS_MAGIC 0x4D5F53665248425FULL /* ascii _BHRfS_M, no null */
-
 /*
  * Maximum number of mirrors that can be available for all profiles counting
  * the target device of dev-replace as one. During an active device replace
@@ -63,8 +61,6 @@  struct btrfs_ioctl_encoded_io_args;
  */
 #define BTRFS_MAX_MIRRORS (4 + 1)
 
-#define BTRFS_MAX_LEVEL 8
-
 #define BTRFS_OLDEST_GENERATION	0ULL
 
 /*
@@ -133,81 +129,9 @@  enum {
 	BTRFS_FS_STATE_COUNT
 };
 
-#define BTRFS_BACKREF_REV_MAX		256
-#define BTRFS_BACKREF_REV_SHIFT		56
-#define BTRFS_BACKREF_REV_MASK		(((u64)BTRFS_BACKREF_REV_MAX - 1) << \
-					 BTRFS_BACKREF_REV_SHIFT)
-
-#define BTRFS_OLD_BACKREF_REV		0
-#define BTRFS_MIXED_BACKREF_REV		1
-
-/*
- * every tree block (leaf or node) starts with this header.
- */
-struct btrfs_header {
-	/* these first four must match the super block */
-	u8 csum[BTRFS_CSUM_SIZE];
-	u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */
-	__le64 bytenr; /* which block this node is supposed to live in */
-	__le64 flags;
-
-	/* allowed to be different from the super from here on down */
-	u8 chunk_tree_uuid[BTRFS_UUID_SIZE];
-	__le64 generation;
-	__le64 owner;
-	__le32 nritems;
-	u8 level;
-} __attribute__ ((__packed__));
-
-/*
- * this is a very generous portion of the super block, giving us
- * room to translate 14 chunks with 3 stripes each.
- */
-#define BTRFS_SYSTEM_CHUNK_ARRAY_SIZE 2048
-
-/*
- * just in case we somehow lose the roots and are not able to mount,
- * we store an array of the roots from previous transactions
- * in the super.
- */
-#define BTRFS_NUM_BACKUP_ROOTS 4
-struct btrfs_root_backup {
-	__le64 tree_root;
-	__le64 tree_root_gen;
-
-	__le64 chunk_root;
-	__le64 chunk_root_gen;
-
-	__le64 extent_root;
-	__le64 extent_root_gen;
-
-	__le64 fs_root;
-	__le64 fs_root_gen;
-
-	__le64 dev_root;
-	__le64 dev_root_gen;
-
-	__le64 csum_root;
-	__le64 csum_root_gen;
-
-	__le64 total_bytes;
-	__le64 bytes_used;
-	__le64 num_devices;
-	/* future */
-	__le64 unused_64[4];
-
-	u8 tree_root_level;
-	u8 chunk_root_level;
-	u8 extent_root_level;
-	u8 fs_root_level;
-	u8 dev_root_level;
-	u8 csum_root_level;
-	/* future and to align */
-	u8 unused_8[10];
-} __attribute__ ((__packed__));
-
 #define BTRFS_SUPER_INFO_OFFSET			SZ_64K
 #define BTRFS_SUPER_INFO_SIZE			4096
+static_assert(sizeof(struct btrfs_super_block) == BTRFS_SUPER_INFO_SIZE);
 
 /*
  * The reserved space at the beginning of each device.
@@ -216,69 +140,6 @@  struct btrfs_root_backup {
  */
 #define BTRFS_DEVICE_RANGE_RESERVED			(SZ_1M)
 
-/*
- * the super block basically lists the main trees of the FS
- * it currently lacks any block count etc etc
- */
-struct btrfs_super_block {
-	/* the first 4 fields must match struct btrfs_header */
-	u8 csum[BTRFS_CSUM_SIZE];
-	/* FS specific UUID, visible to user */
-	u8 fsid[BTRFS_FSID_SIZE];
-	__le64 bytenr; /* this block number */
-	__le64 flags;
-
-	/* allowed to be different from the btrfs_header from here own down */
-	__le64 magic;
-	__le64 generation;
-	__le64 root;
-	__le64 chunk_root;
-	__le64 log_root;
-
-	/*
-	 * This member has never been utilized since the very beginning, thus
-	 * it's always 0 regardless of kernel version.  We always use
-	 * generation + 1 to read log tree root.  So here we mark it deprecated.
-	 */
-	__le64 __unused_log_root_transid;
-	__le64 total_bytes;
-	__le64 bytes_used;
-	__le64 root_dir_objectid;
-	__le64 num_devices;
-	__le32 sectorsize;
-	__le32 nodesize;
-	__le32 __unused_leafsize;
-	__le32 stripesize;
-	__le32 sys_chunk_array_size;
-	__le64 chunk_root_generation;
-	__le64 compat_flags;
-	__le64 compat_ro_flags;
-	__le64 incompat_flags;
-	__le16 csum_type;
-	u8 root_level;
-	u8 chunk_root_level;
-	u8 log_root_level;
-	struct btrfs_dev_item dev_item;
-
-	char label[BTRFS_LABEL_SIZE];
-
-	__le64 cache_generation;
-	__le64 uuid_tree_generation;
-
-	/* the UUID written into btree blocks */
-	u8 metadata_uuid[BTRFS_FSID_SIZE];
-
-	/* future expansion */
-	u8 reserved8[8];
-	__le64 reserved[27];
-	u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE];
-	struct btrfs_root_backup super_roots[BTRFS_NUM_BACKUP_ROOTS];
-
-	/* Padded to 4096 bytes */
-	u8 padding[565];
-} __attribute__ ((__packed__));
-static_assert(sizeof(struct btrfs_super_block) == BTRFS_SUPER_INFO_SIZE);
-
 /*
  * Compat flags that we support.  If any incompat flags are set other than the
  * ones specified below then we will fail to mount
@@ -336,43 +197,6 @@  static_assert(sizeof(struct btrfs_super_block) == BTRFS_SUPER_INFO_SIZE);
 	(BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF)
 #define BTRFS_FEATURE_INCOMPAT_SAFE_CLEAR		0ULL
 
-/*
- * A leaf is full of items. offset and size tell us where to find
- * the item in the leaf (relative to the start of the data area)
- */
-struct btrfs_item {
-	struct btrfs_disk_key key;
-	__le32 offset;
-	__le32 size;
-} __attribute__ ((__packed__));
-
-/*
- * leaves have an item area and a data area:
- * [item0, item1....itemN] [free space] [dataN...data1, data0]
- *
- * The data is separate from the items to get the keys closer together
- * during searches.
- */
-struct btrfs_leaf {
-	struct btrfs_header header;
-	struct btrfs_item items[];
-} __attribute__ ((__packed__));
-
-/*
- * all non-leaf blocks are nodes, they hold only keys and pointers to
- * other blocks
- */
-struct btrfs_key_ptr {
-	struct btrfs_disk_key key;
-	__le64 blockptr;
-	__le64 generation;
-} __attribute__ ((__packed__));
-
-struct btrfs_node {
-	struct btrfs_header header;
-	struct btrfs_key_ptr ptrs[];
-} __attribute__ ((__packed__));
-
 /* Read ahead values for struct btrfs_path.reada */
 enum {
 	READA_NONE,
@@ -1633,43 +1457,6 @@  do {									\
 #define btrfs_clear_pending(info, opt)	\
 	clear_bit(BTRFS_PENDING_##opt, &(info)->pending_changes)
 
-/*
- * Inode flags
- */
-#define BTRFS_INODE_NODATASUM		(1U << 0)
-#define BTRFS_INODE_NODATACOW		(1U << 1)
-#define BTRFS_INODE_READONLY		(1U << 2)
-#define BTRFS_INODE_NOCOMPRESS		(1U << 3)
-#define BTRFS_INODE_PREALLOC		(1U << 4)
-#define BTRFS_INODE_SYNC		(1U << 5)
-#define BTRFS_INODE_IMMUTABLE		(1U << 6)
-#define BTRFS_INODE_APPEND		(1U << 7)
-#define BTRFS_INODE_NODUMP		(1U << 8)
-#define BTRFS_INODE_NOATIME		(1U << 9)
-#define BTRFS_INODE_DIRSYNC		(1U << 10)
-#define BTRFS_INODE_COMPRESS		(1U << 11)
-
-#define BTRFS_INODE_ROOT_ITEM_INIT	(1U << 31)
-
-#define BTRFS_INODE_FLAG_MASK						\
-	(BTRFS_INODE_NODATASUM |					\
-	 BTRFS_INODE_NODATACOW |					\
-	 BTRFS_INODE_READONLY |						\
-	 BTRFS_INODE_NOCOMPRESS |					\
-	 BTRFS_INODE_PREALLOC |						\
-	 BTRFS_INODE_SYNC |						\
-	 BTRFS_INODE_IMMUTABLE |					\
-	 BTRFS_INODE_APPEND |						\
-	 BTRFS_INODE_NODUMP |						\
-	 BTRFS_INODE_NOATIME |						\
-	 BTRFS_INODE_DIRSYNC |						\
-	 BTRFS_INODE_COMPRESS |						\
-	 BTRFS_INODE_ROOT_ITEM_INIT)
-
-#define BTRFS_INODE_RO_VERITY		(1U << 0)
-
-#define BTRFS_INODE_RO_FLAG_MASK	(BTRFS_INODE_RO_VERITY)
-
 struct btrfs_map_token {
 	struct extent_buffer *eb;
 	char *kaddr;
diff --git a/include/uapi/linux/btrfs_tree.h b/include/uapi/linux/btrfs_tree.h
index 1f7a38ec6ac3..e6bf902b9c92 100644
--- a/include/uapi/linux/btrfs_tree.h
+++ b/include/uapi/linux/btrfs_tree.h
@@ -10,6 +10,10 @@ 
 #include <stddef.h>
 #endif
 
+#define BTRFS_MAGIC 0x4D5F53665248425FULL /* ascii _BHRfS_M, no null */
+
+#define BTRFS_MAX_LEVEL 8
+
 /*
  * This header contains the structure definitions and constants used
  * by file system objects that can be retrieved using
@@ -360,6 +364,43 @@  enum btrfs_csum_type {
 #define BTRFS_FT_XATTR		8
 #define BTRFS_FT_MAX		9
 
+/*
+ * Inode flags
+ */
+#define BTRFS_INODE_NODATASUM		(1U << 0)
+#define BTRFS_INODE_NODATACOW		(1U << 1)
+#define BTRFS_INODE_READONLY		(1U << 2)
+#define BTRFS_INODE_NOCOMPRESS		(1U << 3)
+#define BTRFS_INODE_PREALLOC		(1U << 4)
+#define BTRFS_INODE_SYNC		(1U << 5)
+#define BTRFS_INODE_IMMUTABLE		(1U << 6)
+#define BTRFS_INODE_APPEND		(1U << 7)
+#define BTRFS_INODE_NODUMP		(1U << 8)
+#define BTRFS_INODE_NOATIME		(1U << 9)
+#define BTRFS_INODE_DIRSYNC		(1U << 10)
+#define BTRFS_INODE_COMPRESS		(1U << 11)
+
+#define BTRFS_INODE_ROOT_ITEM_INIT	(1U << 31)
+
+#define BTRFS_INODE_FLAG_MASK						\
+	(BTRFS_INODE_NODATASUM |					\
+	 BTRFS_INODE_NODATACOW |					\
+	 BTRFS_INODE_READONLY |						\
+	 BTRFS_INODE_NOCOMPRESS |					\
+	 BTRFS_INODE_PREALLOC |						\
+	 BTRFS_INODE_SYNC |						\
+	 BTRFS_INODE_IMMUTABLE |					\
+	 BTRFS_INODE_APPEND |						\
+	 BTRFS_INODE_NODUMP |						\
+	 BTRFS_INODE_NOATIME |						\
+	 BTRFS_INODE_DIRSYNC |						\
+	 BTRFS_INODE_COMPRESS |						\
+	 BTRFS_INODE_ROOT_ITEM_INIT)
+
+#define BTRFS_INODE_RO_VERITY		(1U << 0)
+
+#define BTRFS_INODE_RO_FLAG_MASK	(BTRFS_INODE_RO_VERITY)
+
 /*
  * The key defines the order in the tree, and so it also defines (optimal)
  * block layout.
@@ -389,6 +430,108 @@  struct btrfs_key {
 	__u64 offset;
 } __attribute__ ((__packed__));
 
+/*
+ * every tree block (leaf or node) starts with this header.
+ */
+struct btrfs_header {
+	/* these first four must match the super block */
+	__u8 csum[BTRFS_CSUM_SIZE];
+	__u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */
+	__le64 bytenr; /* which block this node is supposed to live in */
+	__le64 flags;
+
+	/* allowed to be different from the super from here on down */
+	__u8 chunk_tree_uuid[BTRFS_UUID_SIZE];
+	__le64 generation;
+	__le64 owner;
+	__le32 nritems;
+	__u8 level;
+} __attribute__ ((__packed__));
+
+/*
+ * this is a very generous portion of the super block, giving us
+ * room to translate 14 chunks with 3 stripes each.
+ */
+#define BTRFS_SYSTEM_CHUNK_ARRAY_SIZE 2048
+
+/*
+ * just in case we somehow lose the roots and are not able to mount,
+ * we store an array of the roots from previous transactions
+ * in the super.
+ */
+#define BTRFS_NUM_BACKUP_ROOTS 4
+struct btrfs_root_backup {
+	__le64 tree_root;
+	__le64 tree_root_gen;
+
+	__le64 chunk_root;
+	__le64 chunk_root_gen;
+
+	__le64 extent_root;
+	__le64 extent_root_gen;
+
+	__le64 fs_root;
+	__le64 fs_root_gen;
+
+	__le64 dev_root;
+	__le64 dev_root_gen;
+
+	__le64 csum_root;
+	__le64 csum_root_gen;
+
+	__le64 total_bytes;
+	__le64 bytes_used;
+	__le64 num_devices;
+	/* future */
+	__le64 unused_64[4];
+
+	__u8 tree_root_level;
+	__u8 chunk_root_level;
+	__u8 extent_root_level;
+	__u8 fs_root_level;
+	__u8 dev_root_level;
+	__u8 csum_root_level;
+	/* future and to align */
+	__u8 unused_8[10];
+} __attribute__ ((__packed__));
+
+/*
+ * A leaf is full of items. offset and size tell us where to find
+ * the item in the leaf (relative to the start of the data area)
+ */
+struct btrfs_item {
+	struct btrfs_disk_key key;
+	__le32 offset;
+	__le32 size;
+} __attribute__ ((__packed__));
+
+/*
+ * leaves have an item area and a data area:
+ * [item0, item1....itemN] [free space] [dataN...data1, data0]
+ *
+ * The data is separate from the items to get the keys closer together
+ * during searches.
+ */
+struct btrfs_leaf {
+	struct btrfs_header header;
+	struct btrfs_item items[];
+} __attribute__ ((__packed__));
+
+/*
+ * all non-leaf blocks are nodes, they hold only keys and pointers to
+ * other blocks
+ */
+struct btrfs_key_ptr {
+	struct btrfs_disk_key key;
+	__le64 blockptr;
+	__le64 generation;
+} __attribute__ ((__packed__));
+
+struct btrfs_node {
+	struct btrfs_header header;
+	struct btrfs_key_ptr ptrs[];
+} __attribute__ ((__packed__));
+
 struct btrfs_dev_item {
 	/* the internal btrfs device id */
 	__le64 devid;
@@ -472,6 +615,68 @@  struct btrfs_chunk {
 	/* additional stripes go here */
 } __attribute__ ((__packed__));
 
+/*
+ * the super block basically lists the main trees of the FS
+ * it currently lacks any block count etc etc
+ */
+struct btrfs_super_block {
+	/* the first 4 fields must match struct btrfs_header */
+	__u8 csum[BTRFS_CSUM_SIZE];
+	/* FS specific UUID, visible to user */
+	__u8 fsid[BTRFS_FSID_SIZE];
+	__le64 bytenr; /* this block number */
+	__le64 flags;
+
+	/* allowed to be different from the btrfs_header from here own down */
+	__le64 magic;
+	__le64 generation;
+	__le64 root;
+	__le64 chunk_root;
+	__le64 log_root;
+
+	/*
+	 * This member has never been utilized since the very beginning, thus
+	 * it's always 0 regardless of kernel version.  We always use
+	 * generation + 1 to read log tree root.  So here we mark it deprecated.
+	 */
+	__le64 __unused_log_root_transid;
+	__le64 total_bytes;
+	__le64 bytes_used;
+	__le64 root_dir_objectid;
+	__le64 num_devices;
+	__le32 sectorsize;
+	__le32 nodesize;
+	__le32 __unused_leafsize;
+	__le32 stripesize;
+	__le32 sys_chunk_array_size;
+	__le64 chunk_root_generation;
+	__le64 compat_flags;
+	__le64 compat_ro_flags;
+	__le64 incompat_flags;
+	__le16 csum_type;
+	__u8 root_level;
+	__u8 chunk_root_level;
+	__u8 log_root_level;
+	struct btrfs_dev_item dev_item;
+
+	char label[BTRFS_LABEL_SIZE];
+
+	__le64 cache_generation;
+	__le64 uuid_tree_generation;
+
+	/* the UUID written into btree blocks */
+	__u8 metadata_uuid[BTRFS_FSID_SIZE];
+
+	/* future expansion */
+	__u8 reserved8[8];
+	__le64 reserved[27];
+	__u8 sys_chunk_array[BTRFS_SYSTEM_CHUNK_ARRAY_SIZE];
+	struct btrfs_root_backup super_roots[BTRFS_NUM_BACKUP_ROOTS];
+
+	/* Padded to 4096 bytes */
+	__u8 padding[565];
+} __attribute__ ((__packed__));
+
 #define BTRFS_FREE_SPACE_EXTENT	1
 #define BTRFS_FREE_SPACE_BITMAP	2
 
@@ -526,6 +731,14 @@  struct btrfs_extent_item_v0 {
 /* use full backrefs for extent pointers in the block */
 #define BTRFS_BLOCK_FLAG_FULL_BACKREF	(1ULL << 8)
 
+#define BTRFS_BACKREF_REV_MAX		256
+#define BTRFS_BACKREF_REV_SHIFT		56
+#define BTRFS_BACKREF_REV_MASK		(((u64)BTRFS_BACKREF_REV_MAX - 1) << \
+					 BTRFS_BACKREF_REV_SHIFT)
+
+#define BTRFS_OLD_BACKREF_REV		0
+#define BTRFS_MIXED_BACKREF_REV		1
+
 /*
  * this flag is only used internally by scrub and may be changed at any time
  * it is only declared here to avoid collisions