Add dedupe tree support for btrfs-debug-tree.
Signed-off-by: Qu Wenruo <[email protected]>
---
cmds-inspect-dump-tree.c | 4 ++
ctree.h | 7 +++
print-tree.c | 118 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 129 insertions(+)
diff --git a/cmds-inspect-dump-tree.c b/cmds-inspect-dump-tree.c
index 43c8b67..0c75a3c 100644
--- a/cmds-inspect-dump-tree.c
+++ b/cmds-inspect-dump-tree.c
@@ -496,6 +496,10 @@ again:
printf("multiple");
}
break;
+ case BTRFS_DEDUPE_TREE_OBJECTID:
+ if (!skip)
+ printf("dedupe");
+ break;
default:
if (!skip) {
printf("file");
diff --git a/ctree.h b/ctree.h
index 87ea684..15504b2 100644
--- a/ctree.h
+++ b/ctree.h
@@ -79,6 +79,9 @@ struct btrfs_free_space_ctl;
/* tracks free space in block groups. */
#define BTRFS_FREE_SPACE_TREE_OBJECTID 10ULL
+/* on-disk dedupe tree (EXPERIMENTAL) */
+#define BTRFS_DEDUPE_TREE_OBJECTID 11ULL
+
/* for storing balance parameters in the root tree */
#define BTRFS_BALANCE_OBJECTID -4ULL
@@ -1219,6 +1222,10 @@ struct btrfs_root {
#define BTRFS_DEV_ITEM_KEY 216
#define BTRFS_CHUNK_ITEM_KEY 228
+#define BTRFS_DEDUPE_STATUS_ITEM_KEY 230
+#define BTRFS_DEDUPE_HASH_ITEM_KEY 231
+#define BTRFS_DEDUPE_BYTENR_ITEM_KEY 232
+
#define BTRFS_BALANCE_ITEM_KEY 248
/*
diff --git a/print-tree.c b/print-tree.c
index d0f37a5..5b8b90c 100644
--- a/print-tree.c
+++ b/print-tree.c
@@ -25,6 +25,7 @@
#include "disk-io.h"
#include "print-tree.h"
#include "utils.h"
+#include "dedupe.h"
static void print_dir_item_type(struct extent_buffer *eb,
@@ -687,11 +688,31 @@ static void print_key_type(u64 objectid, u8 type)
case BTRFS_UUID_KEY_RECEIVED_SUBVOL:
printf("UUID_KEY_RECEIVED_SUBVOL");
break;
+ case BTRFS_DEDUPE_STATUS_ITEM_KEY:
+ printf("DEDUPE_STATUS_ITEM");
+ break;
+ case BTRFS_DEDUPE_HASH_ITEM_KEY:
+ printf("DEDUPE_HASH_ITEM");
+ break;
+ case BTRFS_DEDUPE_BYTENR_ITEM_KEY:
+ printf("DEDUPE_BYTENR_ITEM");
+ break;
default:
printf("UNKNOWN.%d", type);
};
}
+static void print_64bit_hash(u64 hash)
+{
+ int i;
+ unsigned char buf[8];
+
+ memcpy(buf, &hash, 8);
+ printf("0x");
+ for (i = 0; i < 8; i++)
+ printf("%02x", buf[i]);
+}
+
static void print_objectid(u64 objectid, u8 type)
{
switch (type) {
@@ -706,6 +727,9 @@ static void print_objectid(u64 objectid, u8 type)
case BTRFS_UUID_KEY_RECEIVED_SUBVOL:
printf("0x%016llx", (unsigned long long)objectid);
return;
+ case BTRFS_DEDUPE_HASH_ITEM_KEY:
+ print_64bit_hash(objectid);
+ return;
}
switch (objectid) {
@@ -772,6 +796,9 @@ static void print_objectid(u64 objectid, u8 type)
case BTRFS_MULTIPLE_OBJECTIDS:
printf("MULTIPLE");
break;
+ case BTRFS_DEDUPE_TREE_OBJECTID:
+ printf("DEDUPE_TREE");
+ break;
case (u64)-1:
printf("-1");
break;
@@ -807,6 +834,9 @@ void btrfs_print_key(struct btrfs_disk_key *disk_key)
case BTRFS_UUID_KEY_RECEIVED_SUBVOL:
printf(" 0x%016llx)", (unsigned long long)offset);
break;
+ case BTRFS_DEDUPE_BYTENR_ITEM_KEY:
+ print_64bit_hash(offset);
+ break;
default:
if (offset == (u64)-1)
printf(" -1)");
@@ -835,6 +865,85 @@ static void print_uuid_item(struct extent_buffer *l,
unsigned long offset,
}
}
+static void print_dedupe_status(struct extent_buffer *node, int slot)
+{
+ struct btrfs_dedupe_status_item *status_item;
+ u64 blocksize;
+ u64 limit;
+ u16 hash_type;
+ u16 backend;
+
+ status_item = btrfs_item_ptr(node, slot,
+ struct btrfs_dedupe_status_item);
+ blocksize = btrfs_dedupe_status_blocksize(node, status_item);
+ limit = btrfs_dedupe_status_limit(node, status_item);
+ hash_type = btrfs_dedupe_status_hash_type(node, status_item);
+ backend = btrfs_dedupe_status_backend(node, status_item);
+
+ printf("\t\tdedupe status item ");
+ if (backend == BTRFS_DEDUPE_BACKEND_INMEMORY)
+ printf("backend: inmemory\n");
+ else if (backend == BTRFS_DEDUPE_BACKEND_ONDISK)
+ printf("backend: ondisk\n");
+ else
+ printf("backend: Unrecognized(%u)\n", backend);
+
+ if (hash_type == BTRFS_DEDUPE_HASH_SHA256)
+ printf("\t\thash algorithm: SHA-256 ");
+ else
+ printf("\t\thash algorithm: Unrecognized(%u) ", hash_type);
+
+ printf("blocksize: %llu limit: %llu\n", blocksize, limit);
+}
+
+static void print_dedupe_hash(struct extent_buffer *eb, int slot,
+ unsigned long offset)
+{
+ struct btrfs_key key;
+ u8 buf[32];
+ int i;
+
+ read_extent_buffer(eb, buf, offset, 32 - 8);
+ btrfs_item_key_to_cpu(eb, &key, slot);
+ WARN_ON(key.type != BTRFS_DEDUPE_HASH_ITEM_KEY);
+ memcpy(buf + 32 - 8, &key.objectid, 8);
+
+ printf("\t\thash: ");
+ for (i = 0; i < 32; i++) {
+ if (i == 16)
+ printf("\n\t\t ");
+ if (i == 8 || i == 24)
+ printf("-");
+ printf("%02x", buf[i]);
+ }
+ printf("\n");
+}
+
+static void print_dedupe_hash_item(struct extent_buffer *eb, int slot)
+{
+ struct btrfs_dedupe_hash_item *hash_item;
+ char compress_str[16];
+
+ /*
+ * Check item size first, it's possible that it contains hash only
+ * structure which is designed for older kernels
+ * (without compression support)
+ */
+ if (btrfs_item_size_nr(eb, slot) == 256 / 8 - 8) {
+ print_dedupe_hash(eb, slot, btrfs_item_ptr_offset(eb, slot));
+ return;
+ }
+ hash_item = btrfs_item_ptr(eb, slot,
+ struct btrfs_dedupe_hash_item);
+ compress_type_to_str(btrfs_dedupe_hash_compression(eb, hash_item),
+ compress_str);
+
+ printf("\t\tdedupe hash item disk_num_bytes: %u\n",
+ btrfs_dedupe_hash_disk_len(eb, hash_item));
+ printf("\t\tdedupe hash compression %s\n", compress_str);
+ print_dedupe_hash(eb, slot, (unsigned long)(hash_item + 1));
+}
+
void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
{
int i;
@@ -856,6 +965,7 @@ void btrfs_print_leaf(struct btrfs_root *root, struct
extent_buffer *l)
struct btrfs_qgroup_info_item *qg_info;
struct btrfs_qgroup_limit_item *qg_limit;
struct btrfs_qgroup_status_item *qg_status;
+
u32 nr = btrfs_header_nritems(l);
u64 objectid;
u32 type;
@@ -1090,6 +1200,14 @@ void btrfs_print_leaf(struct btrfs_root *root, struct
extent_buffer *l)
case BTRFS_DEV_STATS_KEY:
printf("\t\tdevice stats\n");
break;
+ case BTRFS_DEDUPE_STATUS_ITEM_KEY:
+ print_dedupe_status(l, i);
+ break;
+ case BTRFS_DEDUPE_HASH_ITEM_KEY:
+ print_dedupe_hash_item(l, i);
+ break;
+ case BTRFS_DEDUPE_BYTENR_ITEM_KEY:
+ break;
};
fflush(stdout);
}
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html