From db874f1e8924e86bbdee6600b0e5b3e6d11f9238 Mon Sep 17 00:00:00 2001 From: David Marcin Date: Tue, 22 Nov 2011 10:08:00 -0800 Subject: [PATCH 25/35] btrfs-progs: Add utility to dump all superblocks found on a device. Signed-off-by: David Marcin --- .gitignore | 4 ++ Makefile | 9 ++++- btrfs-dump-super.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 btrfs-dump-super.c Index: btrfs-progs-v0.19-117-g6da41f2/.gitignore =================================================================== --- btrfs-progs-v0.19-117-g6da41f2.orig/.gitignore +++ btrfs-progs-v0.19-117-g6da41f2/.gitignore @@ -3,12 +3,16 @@ version.h man/*.gz btrfs +btrfs-corrupt-block btrfs-debug-tree +btrfs-dump-super btrfs-map-logical +btrfs-select-super btrfs-show btrfs-vol btrfsck btrfsctl +calc-size find-root mkfs.btrfs repair Index: btrfs-progs-v0.19-117-g6da41f2/Makefile =================================================================== --- btrfs-progs-v0.19-117-g6da41f2.orig/Makefile +++ btrfs-progs-v0.19-117-g6da41f2/Makefile @@ -17,7 +17,8 @@ LIBS=-luuid RESTORE_LIBS=-lz progs = btrfsctl mkfs.btrfs btrfs-debug-tree btrfs-show btrfs-vol btrfsck \ - btrfs btrfs-map-logical restore find-root calc-size btrfs-corrupt-block + btrfs btrfs-map-logical restore find-root calc-size btrfs-corrupt-block \ + btrfs-dump-super btrfs_man_page_source = btrfs.c btrfs_cmds.c scrub.c @@ -76,6 +77,9 @@ btrfs-zero-log: $(objects) btrfs-zero-lo btrfs-select-super: $(objects) btrfs-select-super.o $(CC) $(CFLAGS) -o btrfs-select-super $(objects) btrfs-select-super.o $(LDFLAGS) $(LIBS) +btrfs-dump-super: $(objects) btrfs-dump-super.o + $(CC) $(CFLAGS) -o btrfs-dump-super $(objects) btrfs-dump-super.o $(LDFLAGS) $(LIBS) + btrfstune: $(objects) btrfstune.o $(CC) $(CFLAGS) -o btrfstune $(objects) btrfstune.o $(LDFLAGS) $(LIBS) @@ -128,7 +132,8 @@ install-man: clean : rm -f man/btrfs.8.in rm -f $(progs) cscope.out *.o .*.d btrfs-convert btrfs-image btrfs-select-super \ - btrfs-zero-log btrfstune dir-test ioctl-test quick-test version.h + btrfs-dump-super btrfs-zero-log btrfstune dir-test ioctl-test quick-test \ + version.h rm -f helpmsg.c cd man; make clean Index: btrfs-progs-v0.19-117-g6da41f2/btrfs-dump-super.c =================================================================== --- /dev/null +++ btrfs-progs-v0.19-117-g6da41f2/btrfs-dump-super.c @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2011 Google. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#define _XOPEN_SOURCE 500 +#define _GNU_SOURCE 1 +#include +#include +#include +#include +#include +#include "kerncompat.h" +#include "ctree.h" +#include "disk-io.h" +#include "version.h" + +static void print_usage(void) +{ + fprintf(stderr, "usage: btrfs-dump-super dev\n"); + fprintf(stderr, "%s\n", BTRFS_BUILD_VERSION); + exit(1); +} + +static int read_block(const char* filename, u64 bytenr, struct btrfs_super_block* sb) { + int fd = open(filename, O_RDONLY, 0600); + int block_size = sizeof(struct btrfs_super_block); + int bytes_read = 0; + + if (fd < 0) { + fprintf(stderr, "Could not open %s\n", filename); + return -1; + } + + bytes_read = pread(fd, sb, block_size, bytenr); + if (bytes_read < block_size) { + fprintf(stderr, "Only read %d bytes of %d.\n", bytes_read, block_size); + } + + close(fd); + return bytes_read; +} + +int main(int ac, char **av) +{ + int i; + + if (ac != 2) + print_usage(); + + for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { + u64 bytenr = btrfs_sb_offset(i); + int fd; + struct btrfs_super_block sb; + int block_size = sizeof(struct btrfs_super_block); + char filename[1024]; + int bytes_read = read_block(av[optind], bytenr, &sb); + if (bytes_read < block_size) + continue; + + sprintf(filename, "/tmp/block.%s.%llu", + strrchr(av[optind], '/') + 1, bytenr); + fd = open(filename, O_CREAT|O_WRONLY, 0644); + if (block_size != pwrite(fd, &sb, block_size, 0)) { + fprintf(stderr, "Failed to dump superblock %d", i); + continue; + } + fprintf(stderr, "Dumped superblock %s:%d, gen %llu to %s.\n", + av[optind], i, sb.generation, filename); + close(fd); + } + + return 0; +}