From 2d9bc57b9ae79ad3648a57b431b9d82e88114132 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Tue, 18 Nov 2008 10:34:08 -0500 Subject: [PATCH] Add disk format requirements for subvol backward and forward refs --- ctree.h | 66 +++++++++++++++++++++++++++++++++++++++++++----------------- print-tree.c | 21 +++++++++++++++++++ root-tree.c | 2 +- 3 files changed, 70 insertions(+), 19 deletions(-) diff --git a/ctree.h b/ctree.h index 94a102d..f08429a 100644 --- a/ctree.h +++ b/ctree.h @@ -443,6 +443,15 @@ struct btrfs_root_item { u8 level; } __attribute__ ((__packed__)); +/* + * this is used for both forward and backward root refs + */ +struct btrfs_root_ref { + __le64 dirid; + __le64 sequence; + __le16 name_len; +} __attribute__ ((__packed__)); + #define BTRFS_FILE_EXTENT_INLINE 0 #define BTRFS_FILE_EXTENT_REG 1 #define BTRFS_FILE_EXTENT_PREALLOC 2 @@ -635,50 +644,64 @@ struct btrfs_root { * the FS */ #define BTRFS_INODE_ITEM_KEY 1 -#define BTRFS_INODE_REF_KEY 2 -#define BTRFS_XATTR_ITEM_KEY 8 -#define BTRFS_ORPHAN_ITEM_KEY 9 - -/* reserve 3-15 close to the inode for later flexibility */ +#define BTRFS_INODE_REF_KEY 12 +#define BTRFS_XATTR_ITEM_KEY 24 +#define BTRFS_ORPHAN_ITEM_KEY 48 +#define BTRFS_DIR_LOG_ITEM_KEY 60 +#define BTRFS_DIR_LOG_INDEX_KEY 72 /* * dir items are the name -> inode pointers in a directory. There is one * for every name in a directory. */ -#define BTRFS_DIR_ITEM_KEY 16 -#define BTRFS_DIR_INDEX_KEY 17 +#define BTRFS_DIR_ITEM_KEY 84 +#define BTRFS_DIR_INDEX_KEY 96 + /* * extent data is for file data */ -#define BTRFS_EXTENT_DATA_KEY 18 +#define BTRFS_EXTENT_DATA_KEY 108 + /* * csum items have the checksums for data in the extents */ -#define BTRFS_CSUM_ITEM_KEY 19 - -/* reserve 20-31 for other file stuff */ +#define BTRFS_CSUM_ITEM_KEY 120 /* * root items point to tree roots. There are typically in the root * tree used by the super block to find all the other trees */ -#define BTRFS_ROOT_ITEM_KEY 32 +#define BTRFS_ROOT_ITEM_KEY 132 + +/* + * root backrefs tie subvols and snapshots to the directory entries that + * reference them + */ +#define BTRFS_ROOT_BACKREF_KEY 144 + +/* + * root refs make a fast index for listing all of the snapshots and + * subvolumes referenced by a given root. They point directly to the + * directory item in the root that references the subvol + */ +#define BTRFS_ROOT_REF_KEY 156 + /* * extent items are in the extent map tree. These record which blocks * are used, and how many references there are to each block */ -#define BTRFS_EXTENT_ITEM_KEY 33 -#define BTRFS_EXTENT_REF_KEY 34 +#define BTRFS_EXTENT_ITEM_KEY 168 +#define BTRFS_EXTENT_REF_KEY 180 /* * block groups give us hints into the extent allocation trees. Which * blocks are free etc etc */ -#define BTRFS_BLOCK_GROUP_ITEM_KEY 50 +#define BTRFS_BLOCK_GROUP_ITEM_KEY 192 -#define BTRFS_DEV_EXTENT_KEY 75 -#define BTRFS_DEV_ITEM_KEY 76 -#define BTRFS_CHUNK_ITEM_KEY 77 +#define BTRFS_DEV_EXTENT_KEY 204 +#define BTRFS_DEV_ITEM_KEY 216 +#define BTRFS_CHUNK_ITEM_KEY 228 /* * string items are for debugging. They just store a short string of @@ -1104,6 +1127,13 @@ static inline void btrfs_set_item_key(struct extent_buffer *eb, write_eb_member(eb, item, struct btrfs_item, key, disk_key); } +/* + * struct btrfs_root_ref + */ +BTRFS_SETGET_FUNCS(root_ref_dirid, struct btrfs_root_ref, dirid, 64); +BTRFS_SETGET_FUNCS(root_ref_sequence, struct btrfs_root_ref, sequence, 64); +BTRFS_SETGET_FUNCS(root_ref_name_len, struct btrfs_root_ref, name_len, 16); + /* struct btrfs_dir_item */ BTRFS_SETGET_FUNCS(dir_data_len, struct btrfs_dir_item, data_len, 16); BTRFS_SETGET_FUNCS(dir_type, struct btrfs_dir_item, type, 8); diff --git a/print-tree.c b/print-tree.c index 96e1b34..eac4d52 100644 --- a/print-tree.c +++ b/print-tree.c @@ -159,6 +159,21 @@ static void print_file_extent_item(struct extent_buffer *eb, } +static void print_root_ref(struct extent_buffer *leaf, int slot, char *tag) +{ + struct btrfs_root_ref *ref; + char namebuf[BTRFS_NAME_LEN]; + int namelen; + + ref = btrfs_item_ptr(leaf, slot, struct btrfs_root_ref); + namelen = btrfs_root_ref_name_len(leaf, ref); + read_extent_buffer(leaf, namebuf, (unsigned long)(ref + 1), namelen); + printf("\t\troot %s key dirid %llu sequence %llu name %.*s\n", tag, + (unsigned long long)btrfs_root_ref_dirid(leaf, ref), + (unsigned long long)btrfs_root_ref_sequence(leaf, ref), + namelen, namebuf); +} + void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) { int i; @@ -240,6 +255,12 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) root_item.drop_level); } break; + case BTRFS_ROOT_REF_KEY: + print_root_ref(l, i, "ref"); + break; + case BTRFS_ROOT_BACKREF_KEY: + print_root_ref(l, i, "backref"); + break; case BTRFS_EXTENT_ITEM_KEY: ei = btrfs_item_ptr(l, i, struct btrfs_extent_item); printf("\t\textent data refs %u\n", diff --git a/root-tree.c b/root-tree.c index 019216c..189f82d 100644 --- a/root-tree.c +++ b/root-tree.c @@ -32,7 +32,7 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, int slot; search_key.objectid = objectid; - search_key.type = (u8)-1; + search_key.type = BTRFS_ROOT_ITEM_KEY; search_key.offset = (u64)-1; path = btrfs_alloc_path(); -- 2.11.4.GIT