Last active
October 20, 2017 05:55
-
-
Save rhenium/47938183f9b9bfa458ce152319697abe to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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