]> git.ipfire.org Git - thirdparty/openembedded/openembedded-core-contrib.git/blob
2102f08e96cc437f2cbc7dd80d0776efa91b78da
[thirdparty/openembedded/openembedded-core-contrib.git] /
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
6
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.
10
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
14
15 Signed-off-by: Chris Mason <chris.mason@oracle.com>
16 ---
17 Makefile | 3 ++
18 btrfs-select-super.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++
19 disk-io.c | 2 +-
20 disk-io.h | 1 +
21 4 files changed, 104 insertions(+), 1 deletions(-)
22 create mode 100644 btrfs-select-super.c
23
24 diff --git a/Makefile b/Makefile
25 index 6e6f6c6..d65f6a2 100644
26 --- a/Makefile
27 +++ b/Makefile
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)
31
32 +btrfs-select-super: $(objects) btrfs-select-super.o
33 + gcc $(CFLAGS) -o btrfs-select-super $(objects) btrfs-select-super.o $(LDFLAGS) $(LIBS)
34 +
35 btrfstune: $(objects) btrfstune.o
36 gcc $(CFLAGS) -o btrfstune $(objects) btrfstune.o $(LDFLAGS) $(LIBS)
37
38 diff --git a/btrfs-select-super.c b/btrfs-select-super.c
39 new file mode 100644
40 index 0000000..f12f36c
41 --- /dev/null
42 +++ b/btrfs-select-super.c
43 @@ -0,0 +1,99 @@
44 +/*
45 + * Copyright (C) 2007 Oracle. All rights reserved.
46 + *
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.
50 + *
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.
55 + *
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.
60 + */
61 +
62 +#define _XOPEN_SOURCE 500
63 +#define _GNU_SOURCE 1
64 +#include <stdio.h>
65 +#include <stdlib.h>
66 +#include <unistd.h>
67 +#include <fcntl.h>
68 +#include <sys/stat.h>
69 +#include "kerncompat.h"
70 +#include "ctree.h"
71 +#include "disk-io.h"
72 +#include "print-tree.h"
73 +#include "transaction.h"
74 +#include "list.h"
75 +#include "version.h"
76 +#include "utils.h"
77 +
78 +static void print_usage(void)
79 +{
80 + fprintf(stderr, "usage: btrfs-select-super -s number dev\n");
81 + fprintf(stderr, "%s\n", BTRFS_BUILD_VERSION);
82 + exit(1);
83 +}
84 +
85 +int main(int ac, char **av)
86 +{
87 + struct btrfs_root *root;
88 + int ret;
89 + int num;
90 + u64 bytenr = 0;
91 +
92 + while(1) {
93 + int c;
94 + c = getopt(ac, av, "s:");
95 + if (c < 0)
96 + break;
97 + switch(c) {
98 + case 's':
99 + num = atol(optarg);
100 + bytenr = btrfs_sb_offset(num);
101 + printf("using SB copy %d, bytenr %llu\n", num,
102 + (unsigned long long)bytenr);
103 + break;
104 + default:
105 + print_usage();
106 + }
107 + }
108 + ac = ac - optind;
109 +
110 + if (ac != 1)
111 + print_usage();
112 +
113 + if (bytenr == 0) {
114 + fprintf(stderr, "Please select the super copy with -s\n");
115 + print_usage();
116 + }
117 +
118 + radix_tree_init();
119 +
120 + if((ret = check_mounted(av[optind])) < 0) {
121 + fprintf(stderr, "Could not check mount status: %s\n", strerror(ret));
122 + return ret;
123 + } else if(ret) {
124 + fprintf(stderr, "%s is currently mounted. Aborting.\n", av[optind]);
125 + return -EBUSY;
126 + }
127 +
128 + root = open_ctree(av[optind], bytenr, 1);
129 +
130 + if (root == NULL)
131 + return 1;
132 +
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);
136 +
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
140 + */
141 + return ret;
142 +}
143 diff --git a/disk-io.c b/disk-io.c
144 index a6e1000..5bd9cfc 100644
145 --- a/disk-io.c
146 +++ b/disk-io.c
147 @@ -828,7 +828,7 @@ int write_dev_supers(struct btrfs_root *root, struct btrfs_super_block *sb,
148
149 if (root->fs_info->super_bytenr != BTRFS_SUPER_INFO_OFFSET) {
150 btrfs_set_super_bytenr(sb, root->fs_info->super_bytenr);
151 -
152 +printk("speiiiiiiiiiiiiiiiiiiiiiiiiiiiii\n");
153 crc = ~(u32)0;
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
158 --- a/disk-io.h
159 +++ b/disk-io.h
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,
162 int writes);
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);
168 --
169 1.7.2.3
170