]> code.ossystems Code Review - openembedded-core.git/blob
2102f08e96cc437f2cbc7dd80d0776efa91b78da
[openembedded-core.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