Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Patched btrfsck to allow rebuilding a superblock from an old tree / generation. #11

Open
wants to merge 40 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
0e6aead
Btrfs-progs: add an option for specifying the root to restore
Nov 1, 2011
9dee07a
Btrfs-progs: try other mirrors if decomression fails
Nov 4, 2011
ff0e1b1
Btrfs-progs: try other mirrors on read failure
Nov 7, 2011
1607360
btrfs-progs: Fix error handling for failed reads in restore tool when…
djmarcin Nov 9, 2011
baf3909
Merge pull request #3 from djmarcin/master
josefbacik Nov 10, 2011
a1ebf7b
btrfs-progs: Check metadata mirrors in find-root.
djmarcin Nov 16, 2011
741a5ca
Merge pull request #4 from djmarcin/for-josef
josefbacik Nov 28, 2011
266f413
restore: Split output directory and btrfs-local path search_dir() par…
Nov 25, 2011
2f0c2a2
restore: Add regex matching of paths and files to be restored
Nov 25, 2011
e8919ef
btrfs-progs: In find-root, dump bytenr for every slot.
djmarcin Nov 22, 2011
db874f1
btrfs-progs: Add utility to dump all superblocks found on a device.
djmarcin Nov 22, 2011
6330d8d
btrfs-progs: Add the ability to use the earliest super found when ope…
djmarcin Nov 22, 2011
a780325
btrfs-progs: Use oldest super for btrfs-select-super. Add required c…
djmarcin Nov 22, 2011
a08aa94
Merge pull request #5 from djmarcin/for-josef
josefbacik Nov 30, 2011
09564cd
Merge pull request #6 from djmarcin/rollback-super
josefbacik Nov 30, 2011
2fe4611
btrfs-progs: add lzo compression support to restore
Dec 2, 2011
1b8b3c3
btrfs-progs: fix regexec to only work if we actually have a regexec
Dec 2, 2011
3ceceda
btrfs-progs: Fix compilation errors with btrfs-select-super.c introdu…
djmarcin Dec 6, 2011
6d616e5
Merge pull request #7 from djmarcin/for-josef
josefbacik Dec 6, 2011
fb0cfed
Btrfs-progs: fix restore to fall back to the broken open_ctree
Dec 7, 2011
412d4f1
Btrfs-progs: don't bug out if we can't find the last root
Dec 7, 2011
df8b44a
Btrfs-progs: make find_and_setup_root return an error
Dec 7, 2011
4686f96
Btrfs-progs: check return value properly
Dec 8, 2011
9bb7aa7
Btrfs-progs: give restore a list roots option
Dec 9, 2011
767972e
Btrfs-progs: fix typo
Jan 4, 2012
b36b23b
Btrfs-progs: make find root spit out the size of the disk
Jan 4, 2012
d4d88fe
Btrfs-progs: add some verbose output to find-root
Jan 4, 2012
f034665
Btrfs-progs: fix restore to actually use the root location if specified
Jan 4, 2012
a3958e5
Btrfs-progs: remove the physical disk size check from find-root
Jan 4, 2012
5ec6eea
Btrfs-progs: fix error output and dont read from cache
Jan 4, 2012
a657103
Btrfs-progs: print the objectid of the root we find when doing find-root
Jan 4, 2012
87edb6f
Btrfs-progs: make specifying root objectid work if the fs is broken
Jan 4, 2012
77ac611
Btrfs-progs: don't free the existing node
Jan 4, 2012
2d18933
Fix long int size specifier in the printf format string
ivant Apr 5, 2012
0cd8e40
Fix undefined reference to pthreads build problem
ivant Apr 5, 2012
b2f74cb
Merge pull request #10 from ivant/master
josefbacik May 22, 2012
a2ee68a
Merge pull request #9 from mrq1/master
josefbacik May 22, 2012
2a43e2b
naive attempt to fix super block with found root
lakeman Jul 22, 2012
1605ee0
Reduce spam when trying to find the best valid tree
lakeman Jul 29, 2012
eba137a
Allow fsck to update super block (cross fingers)
lakeman Jul 29, 2012
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 9 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CC = gcc
AM_CFLAGS = -Wall -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2
CFLAGS = -g -O0
CFLAGS = -g -O0 -pthread
objects = ctree.o disk-io.o radix-tree.o extent-tree.o print-tree.o \
root-tree.o dir-item.o file-item.o inode-item.o \
inode-map.o crc32c.o rbtree.o extent-cache.o extent_io.o \
Expand All @@ -14,10 +14,11 @@ INSTALL = install
prefix ?= /usr/local
bindir = $(prefix)/bin
LIBS=-luuid
RESTORE_LIBS=-lz
RESTORE_LIBS=-lz -llzo2

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

# make C=1 to enable sparse
ifdef C
Expand Down Expand Up @@ -73,6 +74,9 @@ btrfs-zero-log: $(objects) btrfs-zero-log.o
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)

Expand Down Expand Up @@ -105,7 +109,8 @@ install-man:

clean :
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
cd man; make clean

install: $(progs) install-man
Expand Down
87 changes: 87 additions & 0 deletions btrfs-dump-super.c
Original file line number Diff line number Diff line change
@@ -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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#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;
}
38 changes: 30 additions & 8 deletions btrfs-select-super.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@

static void print_usage(void)
{
fprintf(stderr, "usage: btrfs-select-super -s number dev\n");
fprintf(stderr, "usage: btrfs-select-super [-c] [-e] -s number dev\n");
fprintf(stderr, " -c Commit changes to disk [IRREVERSIBLE]\n");
fprintf(stderr, " -e Use the earliest super found, may help recover transid verify problems\n");
fprintf(stderr, "%s\n", BTRFS_BUILD_VERSION);
exit(1);
}
Expand All @@ -45,10 +47,13 @@ int main(int ac, char **av)
int ret;
int num;
u64 bytenr = 0;
int commit = 0;
int use_earliest_bdev = 0;
int fp;

while(1) {
int c;
c = getopt(ac, av, "s:");
c = getopt(ac, av, "s:ce");
if (c < 0)
break;
switch(c) {
Expand All @@ -58,6 +63,12 @@ int main(int ac, char **av)
printf("using SB copy %d, bytenr %llu\n", num,
(unsigned long long)bytenr);
break;
case 'c':
commit = 1;
break;
case 'e':
use_earliest_bdev = 1;
break;
default:
print_usage();
}
Expand All @@ -74,22 +85,33 @@ int main(int ac, char **av)

radix_tree_init();

if((ret = check_mounted(av[optind])) < 0) {
if ((ret = check_mounted(av[optind])) < 0) {
fprintf(stderr, "Could not check mount status: %s\n", strerror(-ret));
return ret;
} else if(ret) {
} else if (ret) {
fprintf(stderr, "%s is currently mounted. Aborting.\n", av[optind]);
return -EBUSY;
}

root = open_ctree(av[optind], bytenr, 1);
fp = open(av[optind], O_CREAT|O_RDWR, 0600);
if (fp < 0) {
fprintf(stderr, "Could not open %s\n", av[optind]);
return 1;
}
root = open_ctree_fd(fp, av[optind], bytenr, 1, use_earliest_bdev);

if (root == NULL)
return 1;

/* make the super writing code think we've read the first super */
root->fs_info->super_bytenr = BTRFS_SUPER_INFO_OFFSET;
ret = write_all_supers(root);
fprintf(stderr, "Found superblock with generation %llu.\n", root->fs_info->super_copy.generation);

if (commit) {
fprintf(stderr, "Committing...\n");

/* make the super writing code think we've read the first super */
root->fs_info->super_bytenr = BTRFS_SUPER_INFO_OFFSET;
ret = write_all_supers(root);
}

/* we don't close the ctree or anything, because we don't want a real
* transaction commit. We just want the super copy we pulled off the
Expand Down
2 changes: 1 addition & 1 deletion btrfs_cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@ int do_scan(int argc, char **argv)
if( argc >= 2 && !strcmp(argv[1],"--all-devices")){

if( argc >2 ){
fprintf(stderr, "ERROR: too may arguments\n");
fprintf(stderr, "ERROR: too many arguments\n");
return 22;
}

Expand Down
26 changes: 22 additions & 4 deletions btrfsck.c
Original file line number Diff line number Diff line change
Expand Up @@ -2800,7 +2800,7 @@ static int check_extents(struct btrfs_root *root)

static void print_usage(void)
{
fprintf(stderr, "usage: btrfsck dev\n");
fprintf(stderr, "usage: btrfsck [-s superblock] [-t tree root] [-g generation] dev\n");
fprintf(stderr, "%s\n", BTRFS_BUILD_VERSION);
exit(1);
}
Expand All @@ -2810,12 +2810,15 @@ int main(int ac, char **av)
struct cache_tree root_cache;
struct btrfs_root *root;
u64 bytenr = 0;
u64 root_tree_bytenr = 0;
u64 root_tree_generation = 0;
int ret;
int num;

int writes=0;

while(1) {
int c;
c = getopt(ac, av, "s:");
c = getopt(ac, av, "s:t:g:c");
if (c < 0)
break;
switch(c) {
Expand All @@ -2825,6 +2828,17 @@ int main(int ac, char **av)
printf("using SB copy %d, bytenr %llu\n", num,
(unsigned long long)bytenr);
break;
case 't':
root_tree_bytenr = atoll(optarg);
printf("Using root tree %llu\n", root_tree_bytenr);
break;
case 'g':
root_tree_generation = atoll(optarg);
printf("Using generation %llu\n", root_tree_generation);
break;
case 'c':
writes=1;
break;
default:
print_usage();
}
Expand All @@ -2845,18 +2859,22 @@ int main(int ac, char **av)
return -EBUSY;
}

root = open_ctree(av[optind], bytenr, 0);
root = open_ctree_recovery(av[optind], bytenr, root_tree_bytenr, root_tree_generation, writes);

if (root == NULL)
return 1;

printf("Checking extents...\n");
ret = check_extents(root);
if (ret)
goto out;

printf("Checking fs roots...\n");
ret = check_fs_roots(root, &root_cache);
if (ret)
goto out;

printf("Checking root references...\n");
ret = check_root_refs(root, &root_cache);
out:
free_root_recs(&root_cache);
Expand Down
6 changes: 3 additions & 3 deletions convert.c
Original file line number Diff line number Diff line change
Expand Up @@ -2386,7 +2386,7 @@ int do_convert(const char *devname, int datacsum, int packing, int noxattr)
fprintf(stderr, "unable to update system chunk\n");
goto fail;
}
root = open_ctree_fd(fd, devname, super_bytenr, O_RDWR);
root = open_ctree_fd(fd, devname, super_bytenr, O_RDWR, 0);
if (!root) {
fprintf(stderr, "unable to open ctree\n");
goto fail;
Expand Down Expand Up @@ -2447,7 +2447,7 @@ int do_convert(const char *devname, int datacsum, int packing, int noxattr)
goto fail;
}

root = open_ctree_fd(fd, devname, 0, O_RDWR);
root = open_ctree_fd(fd, devname, 0, O_RDWR, 0);
if (!root) {
fprintf(stderr, "unable to open ctree\n");
goto fail;
Expand Down Expand Up @@ -2546,7 +2546,7 @@ int do_rollback(const char *devname, int force)
fprintf(stderr, "unable to open %s\n", devname);
goto fail;
}
root = open_ctree_fd(fd, devname, 0, O_RDWR);
root = open_ctree_fd(fd, devname, 0, O_RDWR, 0);
if (!root) {
fprintf(stderr, "unable to open ctree\n");
goto fail;
Expand Down
Loading