From patchwork Sat Aug 6 15:27:56 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Alexandre Oliva X-Patchwork-Id: 1041762 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p76GVEEQ018080 for ; Sat, 6 Aug 2011 16:31:14 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753081Ab1HFQaW (ORCPT ); Sat, 6 Aug 2011 12:30:22 -0400 Received: from lsd-gw.ic.unicamp.br ([143.106.7.165]:43928 "EHLO boneca.lsd.ic.unicamp.br" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751417Ab1HFQaV convert rfc822-to-8bit (ORCPT ); Sat, 6 Aug 2011 12:30:21 -0400 X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Sat, 06 Aug 2011 16:31:14 +0000 (UTC) X-Greylist: delayed 3704 seconds by postgrey-1.27 at vger.kernel.org; Sat, 06 Aug 2011 12:30:21 EDT Received: from freie.oliva.athome.lsd.ic.unicamp.br (gw-to-emilia.oliva.athome.lsd.ic.unicamp.br [172.31.160.17] (may be forged)) by boneca.lsd.ic.unicamp.br (8.14.5/8.14.4) with ESMTP id p76FST6e029769; Sat, 6 Aug 2011 12:28:30 -0300 Received: from livre.localdomain (livre-to-gw.oliva.athome.lsd.ic.unicamp.br [172.31.160.19]) by freie.oliva.athome.lsd.ic.unicamp.br (8.14.4/8.14.4) with ESMTP id p76FRuMe018186; Sat, 6 Aug 2011 12:27:56 -0300 Received: from livre.localdomain (aoliva@localhost.localdomain [127.0.0.1]) by livre.localdomain (8.14.3/8.14.3/Debian-5+lenny1) with ESMTP id p76FRwFK026194; Sat, 6 Aug 2011 12:27:58 -0300 Received: (from aoliva@localhost) by livre.localdomain (8.14.3/8.14.3/Submit) id p76FRu5g026192; Sat, 6 Aug 2011 12:27:56 -0300 X-Authentication-Warning: livre.localdomain: aoliva set sender to oliva@lsd.ic.unicamp.br using -f From: Alexandre Oliva To: mpiechotka Cc: linux-btrfs@vger.kernel.org Subject: help recover from unmountable btrfs Organization: Free thinker, not speaking for University of Campinas Date: Sat, 06 Aug 2011 12:27:56 -0300 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) MIME-Version: 1.0 Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org After running one too many times into “parent transid verify failed” that prevents a filesystem from being mounted, I found out how to adjust some system blocks so that the kernel could get past that check and mount the filesystem. In one case, I could get all the data I wanted from the filesystem; in another, many checksums failed and I ended up throwing it all away, so no guarrantees. mpiechotka's running into the problem and bringing it up on IRC prompted me to post for wider consumption this patch for btrfsck, that will tell you what to do to make the filesystem mountable again. Add verbosity to btrfsck so that we can manually recover from a failure to update the roots. Signed-off-by: Alexandre Oliva --- disk-io.c | 41 +++++++++++++++++++++++++++++++++++++++++ volumes.c | 3 +++ 2 files changed, 44 insertions(+), 0 deletions(-) diff --git a/disk-io.c b/disk-io.c index a6e1000..6860c26 100644 --- a/disk-io.c +++ b/disk-io.c @@ -87,6 +87,22 @@ int csum_tree_block_size(struct extent_buffer *buf, u16 csum_size, printk("checksum verify failed on %llu wanted %X " "found %X\n", (unsigned long long)buf->start, *((int *)result), *((char *)buf->data)); + if (csum_size == 4) { + fprintf(stderr, "dd if=(fd %i) bs=1c skip=%llu count=4 | od -t x1:\n%02x %02x %02x %02x\n", + buf->fd, + (unsigned long long)buf->dev_bytenr, + (__u8)buf->data[0], + (__u8)buf->data[1], + (__u8)buf->data[2], + (__u8)buf->data[3]); + fprintf(stderr, "printf \"\\x%02x\\x%02x\\x%02x\\x%02x\" | dd of=(fd %i) bs=1c seek=%llu conv=notrunc count=4\n", + (__u8)result[0], + (__u8)result[1], + (__u8)result[2], + (__u8)result[3], + buf->fd, + (unsigned long long)buf->dev_bytenr); + } free(result); return 1; } @@ -165,6 +181,31 @@ static int verify_parent_transid(struct extent_io_tree *io_tree, (unsigned long long)eb->start, (unsigned long long)parent_transid, (unsigned long long)btrfs_header_generation(eb)); + fprintf(stderr, "dd if=(fd %i) bs=1c skip=%llu count=8 | od -t x1:\n%02x %02x %02x %02x %02x %02x %02x %02x\n", + eb->fd, + (unsigned long long)eb->dev_bytenr + + offsetof (struct btrfs_header, generation), + (__u8)eb->data[offsetof (struct btrfs_header, generation)], + (__u8)eb->data[offsetof (struct btrfs_header, generation) + 1], + (__u8)eb->data[offsetof (struct btrfs_header, generation) + 2], + (__u8)eb->data[offsetof (struct btrfs_header, generation) + 3], + (__u8)eb->data[offsetof (struct btrfs_header, generation) + 4], + (__u8)eb->data[offsetof (struct btrfs_header, generation) + 5], + (__u8)eb->data[offsetof (struct btrfs_header, generation) + 6], + (__u8)eb->data[offsetof (struct btrfs_header, generation) + 7]); + btrfs_set_header_generation(eb, parent_transid); + fprintf(stderr, "printf \"\\x%02x\\x%02x\\x%02x\\x%02x\\x%02x\\x%02x\\x%02x\\x%02x\" | dd of=(fd %i) bs=1c seek=%llu conv=notrunc count=8\n", + (__u8)eb->data[offsetof (struct btrfs_header, generation)], + (__u8)eb->data[offsetof (struct btrfs_header, generation) + 1], + (__u8)eb->data[offsetof (struct btrfs_header, generation) + 2], + (__u8)eb->data[offsetof (struct btrfs_header, generation) + 3], + (__u8)eb->data[offsetof (struct btrfs_header, generation) + 4], + (__u8)eb->data[offsetof (struct btrfs_header, generation) + 5], + (__u8)eb->data[offsetof (struct btrfs_header, generation) + 6], + (__u8)eb->data[offsetof (struct btrfs_header, generation) + 7], + eb->fd, + (unsigned long long)eb->dev_bytenr + + offsetof (struct btrfs_header, generation)); ret = 1; out: clear_extent_buffer_uptodate(io_tree, eb); diff --git a/volumes.c b/volumes.c index 7671855..c30a3ba 100644 --- a/volumes.c +++ b/volumes.c @@ -188,6 +188,9 @@ int btrfs_open_devices(struct btrfs_fs_devices *fs_devices, int flags) device->fd = fd; if (flags == O_RDWR) device->writeable = 1; + fprintf(stderr, "Device %llu (%s) opened in fd %i\n", + (unsigned long long)device->devid, + device->name, device->fd); } return 0; fail: