-
Notifications
You must be signed in to change notification settings - Fork 0
/
0002-Btrfs-progs-fsck-handle-the-case-we-can-not-lookup-e.patch
99 lines (88 loc) · 2.76 KB
/
0002-Btrfs-progs-fsck-handle-the-case-we-can-not-lookup-e.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
From 3038c24736022cf2d7a194b08a7a16234bd450aa Mon Sep 17 00:00:00 2001
From: Wang Shilong <wangsl.fnst@cn.fujitsu.com>
Date: Fri, 28 Feb 2014 15:40:48 +0800
Subject: [PATCH 2/3] Btrfs-progs: fsck: handle the case we can not lookup
extent info
So we may fail to get extent item info from extent tree sometimes,
for example we have cleared extent tree before.
if we don't clear extent tree before, we just skip this corrupted
extent item. otherwise, avoid using full backref mode for now.
BTW. --init-extent-tree option dosen't work if broken filesystem
has several snapshots.
Signed-off-by: Wang Shilong <wangsl.fnst@cn.fujitsu.com>
---
cmds-check.c | 40 +++++++++++++++++++++++++++++++---------
1 file changed, 31 insertions(+), 9 deletions(-)
diff --git a/cmds-check.c b/cmds-check.c
index 98199ce..e431ae1 100644
--- a/cmds-check.c
+++ b/cmds-check.c
@@ -52,6 +52,7 @@ static LIST_HEAD(duplicate_extents);
static LIST_HEAD(delete_items);
static int repair = 0;
static int no_holes = 0;
+int init_extent_tree = 0;
struct extent_backref {
struct list_head list;
@@ -3918,8 +3919,19 @@ static int run_next_block(struct btrfs_trans_handle *trans,
ret = btrfs_lookup_extent_info(NULL, root, bytenr,
btrfs_header_level(buf), 1, NULL,
&flags);
- if (ret < 0)
- flags = BTRFS_BLOCK_FLAG_FULL_BACKREF;
+ /*
+ * In some cases, we could not find extent item in extent tree
+ * because of corrupt tree block or extent tree.for example we
+ * have recreated extent tree before.
+ *
+ * FIXME, we just skip this extent if it is corrupted.
+ */
+ if (ret < 0) {
+ if (init_extent_tree)
+ flags = 0;
+ else
+ goto out;
+ }
if (flags & BTRFS_BLOCK_FLAG_FULL_BACKREF) {
parent = bytenr;
@@ -5102,16 +5114,27 @@ static int fixup_extent_refs(struct btrfs_trans_handle *trans,
int allocated = 0;
u64 flags = 0;
+ path = btrfs_alloc_path();
+ if (!path)
+ return -ENOMEM;
+
/* remember our flags for recreating the extent */
ret = btrfs_lookup_extent_info(NULL, info->extent_root, rec->start,
rec->max_size, rec->metadata, NULL,
&flags);
- if (ret < 0)
- flags = BTRFS_BLOCK_FLAG_FULL_BACKREF;
-
- path = btrfs_alloc_path();
- if (!path)
- return -ENOMEM;
+ if (ret < 0) {
+ if (init_extent_tree)
+ flags = 0;
+ else {
+ /*
+ * we just discard this extent for now.
+ */
+ ret = delete_extent_records(trans, info->extent_root,
+ path, rec->start, rec->max_size);
+ if (ret < 0)
+ goto out;
+ }
+ }
if (rec->refs != rec->extent_item_refs && !rec->metadata) {
/*
@@ -6399,7 +6422,6 @@ int cmd_check(int argc, char **argv)
u64 num;
int option_index = 0;
int init_csum_tree = 0;
- int init_extent_tree = 0;
enum btrfs_open_ctree_flags ctree_flags =
OPEN_CTREE_PARTIAL | OPEN_CTREE_EXCLUSIVE;
--
1.9.0