1 Upstream-Status: Inappropriate [Backport]
2 From 70c6c10134b502fa69955746554031939b85fb0c Mon Sep 17 00:00:00 2001
3 From: Chris Mason <chris.mason@oracle.com>
4 Date: Thu, 9 Dec 2010 16:36:29 -0500
5 Subject: [PATCH 01/15] Btrfs-progs: add a btrfs-select-super command to overwrite the super
7 Btrfs stores multiple copies of the superblock, and for common power-failure
8 crashes where barriers were not in use, one of the super copies is often
9 valid while the first copy is not.
11 This adds a btrfs-select-super -s N /dev/xxx command, which can
12 overwrite all the super blocks with a copy that you have already
13 determined is valid with btrfsck -s
15 Signed-off-by: Chris Mason <chris.mason@oracle.com>
18 btrfs-select-super.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++
21 4 files changed, 104 insertions(+), 1 deletions(-)
22 create mode 100644 btrfs-select-super.c
24 diff --git a/Makefile b/Makefile
25 index 6e6f6c6..d65f6a2 100644
28 @@ -62,6 +62,9 @@ btrfs-debug-tree: $(objects) debug-tree.o
29 btrfs-zero-log: $(objects) btrfs-zero-log.o
30 gcc $(CFLAGS) -o btrfs-zero-log $(objects) btrfs-zero-log.o $(LDFLAGS) $(LIBS)
32 +btrfs-select-super: $(objects) btrfs-select-super.o
33 + gcc $(CFLAGS) -o btrfs-select-super $(objects) btrfs-select-super.o $(LDFLAGS) $(LIBS)
35 btrfstune: $(objects) btrfstune.o
36 gcc $(CFLAGS) -o btrfstune $(objects) btrfstune.o $(LDFLAGS) $(LIBS)
38 diff --git a/btrfs-select-super.c b/btrfs-select-super.c
40 index 0000000..f12f36c
42 +++ b/btrfs-select-super.c
45 + * Copyright (C) 2007 Oracle. All rights reserved.
47 + * This program is free software; you can redistribute it and/or
48 + * modify it under the terms of the GNU General Public
49 + * License v2 as published by the Free Software Foundation.
51 + * This program is distributed in the hope that it will be useful,
52 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
53 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
54 + * General Public License for more details.
56 + * You should have received a copy of the GNU General Public
57 + * License along with this program; if not, write to the
58 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
59 + * Boston, MA 021110-1307, USA.
62 +#define _XOPEN_SOURCE 500
63 +#define _GNU_SOURCE 1
68 +#include <sys/stat.h>
69 +#include "kerncompat.h"
72 +#include "print-tree.h"
73 +#include "transaction.h"
78 +static void print_usage(void)
80 + fprintf(stderr, "usage: btrfs-select-super -s number dev\n");
81 + fprintf(stderr, "%s\n", BTRFS_BUILD_VERSION);
85 +int main(int ac, char **av)
87 + struct btrfs_root *root;
94 + c = getopt(ac, av, "s:");
100 + bytenr = btrfs_sb_offset(num);
101 + printf("using SB copy %d, bytenr %llu\n", num,
102 + (unsigned long long)bytenr);
114 + fprintf(stderr, "Please select the super copy with -s\n");
120 + if((ret = check_mounted(av[optind])) < 0) {
121 + fprintf(stderr, "Could not check mount status: %s\n", strerror(ret));
124 + fprintf(stderr, "%s is currently mounted. Aborting.\n", av[optind]);
128 + root = open_ctree(av[optind], bytenr, 1);
133 + /* make the super writing code think we've read the first super */
134 + root->fs_info->super_bytenr = BTRFS_SUPER_INFO_OFFSET;
135 + ret = write_all_supers(root);
137 + /* we don't close the ctree or anything, because we don't want a real
138 + * transaction commit. We just want the super copy we pulled off the
139 + * disk to overwrite all the other copies
143 diff --git a/disk-io.c b/disk-io.c
144 index a6e1000..5bd9cfc 100644
147 @@ -828,7 +828,7 @@ int write_dev_supers(struct btrfs_root *root, struct btrfs_super_block *sb,
149 if (root->fs_info->super_bytenr != BTRFS_SUPER_INFO_OFFSET) {
150 btrfs_set_super_bytenr(sb, root->fs_info->super_bytenr);
152 +printk("speiiiiiiiiiiiiiiiiiiiiiiiiiiiii\n");
154 crc = btrfs_csum_data(NULL, (char *)sb + BTRFS_CSUM_SIZE, crc,
155 BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE);
156 diff --git a/disk-io.h b/disk-io.h
157 index 49e5692..7ebec24 100644
160 @@ -47,6 +47,7 @@ struct btrfs_root *open_ctree(const char *filename, u64 sb_bytenr, int writes);
161 struct btrfs_root *open_ctree_fd(int fp, const char *path, u64 sb_bytenr,
163 int close_ctree(struct btrfs_root *root);
164 +int write_all_supers(struct btrfs_root *root);
165 int write_ctree_super(struct btrfs_trans_handle *trans,
166 struct btrfs_root *root);
167 int btrfs_read_dev_super(int fd, struct btrfs_super_block *sb, u64 sb_bytenr);