Skip to content

Instantly share code, notes, and snippets.

@rhenium
Last active October 20, 2017 05:55
Show Gist options
  • Save rhenium/47938183f9b9bfa458ce152319697abe to your computer and use it in GitHub Desktop.
Save rhenium/47938183f9b9bfa458ce152319697abe to your computer and use it in GitHub Desktop.
diff --git a/Makefile b/Makefile
index d0657aaea0f5..cf72ad5d9c7d 100644
--- a/Makefile
+++ b/Makefile
@@ -196,7 +196,8 @@ progs = $(progs_install) btrfsck btrfs-corrupt-block
progs_install = btrfs mkfs.btrfs btrfs-debug-tree \
btrfs-map-logical btrfs-image btrfs-zero-log \
btrfs-find-root btrfstune \
- btrfs-select-super
+ btrfs-select-super \
+ btrfs-poepoe
# other tools, not built by default
progs_extra = btrfs-fragments btrfs-calc-size btrfs-show-super
diff --git a/btrfs-poepoe.c b/btrfs-poepoe.c
new file mode 100644
index 000000000000..4eaf64f03b9d
--- /dev/null
+++ b/btrfs-poepoe.c
@@ -0,0 +1,85 @@
+/*
+ * $ btrfs inspect-internal dump-tree -b 3431741964288 /dev/sdc
+ * btrfs-progs v4.13
+ * node 3431741964288 level 1 items 331 free 162 generation 1702812 owner 269
+ * fs uuid c72a3e74-f1f9-42eb-95cc-a20b9e6e3d9b
+ * chunk uuid c817ddcd-62a9-44ac-ae3b-832d19409983
+ * key (256 INODE_ITEM 0) block 60145664 (3671) gen 1701848
+ * key (260 DIR_ITEM 3492357713) block 60178432 (3673) gen 1701848
+ * [...]
+ * key (1659 DIR_INDEX 3550) block 4093925834752 (249873403) gen 1701783
+ * key (1659 DIR_INDEX 3792) block 4093898473472 (249871733) gen 1701783
+ * key (1659 DIR_INDEX 4015) block 4093931552768 (249873752) gen 1701783
+ * key (1686 INODE_REF 1659) block 4093935747072 (249874008) gen 1701783
+ * key (2345 DIR_ITEM 73003351) block 4093927981056 (249873534) gen 1701783
+ * key (2345 DIR_ITEM 196376866) block 4093928898560 (249873590) gen 1701783
+ * key (2345 DIR_ITEM 306934370) block 4093928931328 (249873592) gen 1701783
+ * key (2345 DIR_ITEM 400602171) block 4093929013248 (249873597) gen 1701783
+ * key (2147485993 DIR_ITEM 518577612) block 4093927915520 (249873530) gen 1701783
+ * \-- 32nd bit is flipped
+ * key (2345 DIR_ITEM 620047019) block 4093927849984 (249873526) gen 1701783
+ * key (2345 DIR_ITEM 716204986) block 4093928144896 (249873544) gen 1701783
+ * key (2345 DIR_ITEM 831110486) block 4093927784448 (249873522) gen 1701783
+ * key (2345 DIR_ITEM 945856906) block 4093927604224 (249873511) gen 1701783
+ * key (2345 DIR_ITEM 1002422887) block 4093933371392 (249873863) gen 1701783
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#undef _NDEBUG
+#include <assert.h>
+#include "ctree.h"
+#include "disk-io.h"
+#include "print-tree.h"
+
+int main(void)
+{
+ struct btrfs_root *root;
+ struct btrfs_fs_info *fs_info;
+ struct extent_buffer *eb;
+ u64 block = 3431741964288ULL;
+ u32 i, nr;
+ struct btrfs_disk_key disk_key;
+
+ fs_info = open_ctree_fs_info("/dev/sdc", 0, 0, 0, OPEN_CTREE_WRITES);
+ assert(fs_info);
+
+ root = fs_info->chunk_root;
+ assert(root);
+
+ eb = read_tree_block(fs_info, block, 0);
+ assert(extent_buffer_uptodate(eb));
+ assert(btrfs_header_level(eb) == 1);
+
+ /* Find the corrupted item */
+ nr = btrfs_header_nritems(eb);
+ for (i = 0; i < nr; i++) {
+ btrfs_node_key(eb, &disk_key, i);
+ if (btrfs_disk_key_objectid(&disk_key) == 2147485993ULL &&
+ btrfs_disk_key_type(&disk_key) == BTRFS_DIR_ITEM_KEY &&
+ btrfs_disk_key_offset(&disk_key) == 518577612ULL) {
+ /* found key (2147485993 DIR_ITEM 518577612) */
+ break;
+ }
+ }
+ assert(i != nr);
+
+ /* Fix the objectid */
+ btrfs_print_key(&disk_key); printf("\n");
+ /* 2345 == 2147485993 - 2**31 */
+ btrfs_set_disk_key_objectid(&disk_key, 2345ULL);
+ btrfs_print_key(&disk_key); printf("\n");
+ btrfs_set_node_key(eb, &disk_key, i);
+
+ /* Write to disk */
+ if (1) {
+ printf("Writing to disk... ");
+ u16 csum_size = btrfs_super_csum_size(fs_info->super_copy);
+ csum_tree_block_size(eb, csum_size, 0);
+ write_extent_to_disk(eb);
+ printf("done.\n");
+ }
+
+ free_extent_buffer(eb);
+ return !!close_ctree(root);
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment