Btrfs-progs: Support UUID tree and UUID items in btrfs-debug-tree
authorStefan Behrens <sbehrens@giantdisaster.de>
Wed, 26 Jun 2013 15:17:55 +0000 (17:17 +0200)
committerDavid Sterba <dsterba@suse.cz>
Fri, 9 Aug 2013 12:32:31 +0000 (14:32 +0200)
Support printing these things.

Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
Signed-off-by: David Sterba <dsterba@suse.cz>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
ctree.h
print-tree.c

diff --git a/ctree.h b/ctree.h
index ea5925f..6f210b8 100644 (file)
--- a/ctree.h
+++ b/ctree.h
@@ -71,6 +71,8 @@ struct btrfs_free_space_ctl;
 #define BTRFS_CSUM_TREE_OBJECTID 7ULL
 #define BTRFS_QUOTA_TREE_OBJECTID 8ULL
 
+/* for storing items that use the BTRFS_UUID_KEY* */
+#define BTRFS_UUID_TREE_OBJECTID 9ULL
 
 /* for storing balance parameters in the root tree */
 #define BTRFS_BALANCE_OBJECTID -4ULL
@@ -1108,6 +1110,19 @@ struct btrfs_root {
 #define BTRFS_DEV_REPLACE_KEY  250
 
 /*
+ * Stores items that allow to quickly map UUIDs to something else.
+ * These items are part of the filesystem UUID tree.
+ * The key is built like this:
+ * (UUID_upper_64_bits, BTRFS_UUID_KEY*, UUID_lower_64_bits).
+ */
+#if BTRFS_UUID_SIZE != 16
+#error "UUID items require BTRFS_UUID_SIZE == 16!"
+#endif
+#define BTRFS_UUID_KEY_SUBVOL  251     /* for UUIDs assigned to subvols */
+#define BTRFS_UUID_KEY_RECEIVED_SUBVOL 252     /* for UUIDs assigned to
+                                                * received subvols */
+
+/*
  * string items are for debugging.  They just store a short string of
  * data in the FS
  */
index 4401a1a..761448d 100644 (file)
@@ -547,6 +547,12 @@ static void print_key_type(u64 objectid, u8 type)
        case BTRFS_DEV_STATS_KEY:
                printf("DEV_STATS_ITEM");
                break;
+       case BTRFS_UUID_KEY_SUBVOL:
+               printf("BTRFS_UUID_KEY_SUBVOL");
+               break;
+       case BTRFS_UUID_KEY_RECEIVED_SUBVOL:
+               printf("BTRFS_UUID_KEY_RECEIVED_SUBVOL");
+               break;
        default:
                printf("UNKNOWN.%d", type);
        };
@@ -554,15 +560,18 @@ static void print_key_type(u64 objectid, u8 type)
 
 static void print_objectid(u64 objectid, u8 type)
 {
-       if (type == BTRFS_DEV_EXTENT_KEY) {
+       switch (type) {
+       case BTRFS_DEV_EXTENT_KEY:
                printf("%llu", (unsigned long long)objectid); /* device id */
                return;
-       }
-       switch (type) {
        case BTRFS_QGROUP_RELATION_KEY:
                printf("%llu/%llu", objectid >> 48,
                        objectid & ((1ll << 48) - 1));
                return;
+       case BTRFS_UUID_KEY_SUBVOL:
+       case BTRFS_UUID_KEY_RECEIVED_SUBVOL:
+               printf("0x%016llx", (unsigned long long)objectid);
+               return;
        }
 
        switch (objectid) {
@@ -620,6 +629,9 @@ static void print_objectid(u64 objectid, u8 type)
        case BTRFS_QUOTA_TREE_OBJECTID:
                printf("QUOTA_TREE");
                break;
+       case BTRFS_UUID_TREE_OBJECTID:
+               printf("UUID_TREE");
+               break;
        case BTRFS_MULTIPLE_OBJECTIDS:
                printf("MULTIPLE");
                break;
@@ -654,6 +666,10 @@ void btrfs_print_key(struct btrfs_disk_key *disk_key)
                printf(" %llu/%llu)", (unsigned long long)(offset >> 48),
                        (unsigned long long)(offset & ((1ll << 48) - 1)));
                break;
+       case BTRFS_UUID_KEY_SUBVOL:
+       case BTRFS_UUID_KEY_RECEIVED_SUBVOL:
+               printf(" 0x%016llx)", (unsigned long long)offset);
+               break;
        default:
                if (offset == (u64)-1)
                        printf(" -1)");
@@ -663,6 +679,25 @@ void btrfs_print_key(struct btrfs_disk_key *disk_key)
        }
 }
 
+static void print_uuid_item(struct extent_buffer *l, unsigned long offset,
+                           u32 item_size)
+{
+       if (item_size & (sizeof(u64) - 1)) {
+               printf("btrfs: uuid item with illegal size %lu!\n",
+                      (unsigned long)item_size);
+               return;
+       }
+       while (item_size) {
+               u64 subvol_id;
+
+               read_extent_buffer(l, &subvol_id, offset, sizeof(u64));
+               subvol_id = le64_to_cpu(subvol_id);
+               printf("\t\tsubvol_id %llu\n", (unsigned long long)subvol_id);
+               item_size -= sizeof(u64);
+               offset += sizeof(u64);
+       }
+}
+
 void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
 {
        int i;
@@ -879,6 +914,11 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
                               (long long)
                               btrfs_qgroup_limit_rsv_exclusive(l, qg_limit));
                        break;
+               case BTRFS_UUID_KEY_SUBVOL:
+               case BTRFS_UUID_KEY_RECEIVED_SUBVOL:
+                       print_uuid_item(l, btrfs_item_ptr_offset(l, i),
+                                       btrfs_item_size_nr(l, i));
+                       break;
                case BTRFS_STRING_ITEM_KEY:
                        /* dirty, but it's simple */
                        str = l->data + btrfs_item_ptr_offset(l, i);