-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathe2fsck-add-problem-descriptions-and-check-inline-data
179 lines (166 loc) · 5.59 KB
/
e2fsck-add-problem-descriptions-and-check-inline-data
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
e2fsck: add problem descriptions and check inline data feature
From: Zheng Liu <wenqing.lz@taobao.com>
Signed-off-by: Zheng Liu <wenqing.lz@taobao.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---
e2fsck/pass1.c | 33 ++++++++++++++++++++++++++++++++-
e2fsck/problem.c | 15 +++++++++++++++
e2fsck/problem.h | 9 +++++++++
lib/ext2fs/ext2fs.h | 1 +
lib/ext2fs/inline_data.c | 28 ++++++++++++++++++++++++++++
5 files changed, 85 insertions(+), 1 deletion(-)
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index a20b57b..3ef9491 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -592,7 +592,7 @@ void e2fsck_pass1(e2fsck_t ctx)
struct ext2_super_block *sb = ctx->fs->super;
const char *old_op;
unsigned int save_type;
- int imagic_fs, extent_fs;
+ int imagic_fs, extent_fs, inlinedata_fs;
int busted_fs_time = 0;
int inode_size;
int failed_csum = 0;
@@ -626,6 +626,8 @@ void e2fsck_pass1(e2fsck_t ctx)
imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
extent_fs = (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS);
+ inlinedata_fs = (sb->s_feature_incompat &
+ EXT4_FEATURE_INCOMPAT_INLINE_DATA);
/*
* Allocate bitmaps structures
@@ -757,6 +759,20 @@ void e2fsck_pass1(e2fsck_t ctx)
ext2fs_mark_block_bitmap2(ctx->block_found_map,
fs->super->s_mmp_block);
+ /*
+ * If INLINE_DATA feature is set and EXT_ATTR feature missing,
+ * EXT_ATTR needs to be set because INLINE_DATA depends on it and
+ * this feature is enabled on default.
+ */
+ if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
+ inlinedata_fs) {
+ if (fix_problem(ctx, PR_1_INLINE_DATA_AND_EXT_ATTR, &pctx)) {
+ fs->super->s_feature_compat |=
+ EXT2_FEATURE_COMPAT_EXT_ATTR;
+ ext2fs_mark_super_dirty(fs);
+ }
+ }
+
/* Set up ctx->lost_and_found if possible */
(void) e2fsck_get_lost_and_found(ctx, 0);
@@ -808,6 +824,21 @@ void e2fsck_pass1(e2fsck_t ctx)
}
}
+ /* Test for incrrect inline_data flags settings. */
+ if ((inode->i_flags & EXT4_INLINE_DATA_FL) && !inlinedata_fs &&
+ (ino >= EXT2_FIRST_INODE(fs->super))) {
+ if (ext2fs_inline_data_header_check(fs, ino) &&
+ !fix_problem(ctx, PR_1_INLINE_DATA_FEATURE, &pctx)) {
+ sb->s_feature_incompat |=
+ EXT4_FEATURE_INCOMPAT_INLINE_DATA;
+ ext2fs_mark_super_dirty(fs);
+ inlinedata_fs = 1;
+ } else if (!fix_problem(ctx, PR_1_INLINE_DATA_SET, &pctx)) {
+ e2fsck_clear_inode(ctx, ino, inode, 0, "pass1");
+ continue;
+ }
+ }
+
/*
* Test for incorrect extent flag settings.
*
diff --git a/e2fsck/problem.c b/e2fsck/problem.c
index 76bc1d5..d79115a 100644
--- a/e2fsck/problem.c
+++ b/e2fsck/problem.c
@@ -1008,6 +1008,21 @@ static struct e2fsck_problem problem_table[] = {
"Logical start %b does not match logical start %c at next level. "),
PROMPT_FIX, 0 },
+ /* INLINE_DATA feature is set, but EXT_ATTR missing */
+ { PR_1_INLINE_DATA_AND_EXT_ATTR,
+ N_("INLINE_DATA feature is set in @S, but EXT_ATTR feature missing\n"),
+ PROMPT_FIX, 0 },
+
+ /* Inode has inline data, but superblock is missing INLINE_DATA feature. */
+ { PR_1_INLINE_DATA_FEATURE,
+ N_("@i %i has inline data, but @S is missing INLINE_DATA feature\n"),
+ PROMPT_CLEAR, PR_PREEN_OK },
+
+ /* INLINE_DATA feature is set in a non-inline-data filesystem */
+ { PR_1_INLINE_DATA_SET,
+ N_("@i %i has INLINE_DATA_FL flag on @f without inline data support.\n"),
+ PROMPT_CLEAR, 0 },
+
/* Pass 1b errors */
/* Pass 1B: Rescan for duplicate/bad blocks */
diff --git a/e2fsck/problem.h b/e2fsck/problem.h
index d2b6df4..83257ae 100644
--- a/e2fsck/problem.h
+++ b/e2fsck/problem.h
@@ -589,6 +589,15 @@ struct problem_context {
/* Index start doesn't match start of next extent down */
#define PR_1_EXTENT_INDEX_START_INVALID 0x01006D
+/* INLINE_DATA feature is set, but EXT_ATTR missing */
+#define PR_1_INLINE_DATA_AND_EXT_ATTR 0x01006E
+
+/* Inode has inline data, but superblock is missing INLINE_DATA feature. */
+#define PR_1_INLINE_DATA_FEATURE 0x01006F
+
+/* INLINE_DATA feature is set in a non-inline-data filesystem */
+#define PR_1_INLINE_DATA_SET 0x010070
+
/*
* Pass 1b errors
*/
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index b069a6a..96177c9 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -1359,6 +1359,7 @@ extern int ext2fs_inline_data_iterate(ext2_filsys fs,
struct ext2_inode_large *inode,
void *priv_data),
void *priv_data);
+extern int ext2fs_inline_data_header_check(ext2_filsys fs, ext2_ino_t ino);
extern errcode_t ext2fs_inline_data_mkdir(ext2_filsys fs, ext2_ino_t parent,
ext2_ino_t ino);
extern errcode_t ext2fs_convert_inline_data(ext2_filsys fs, ext2_ino_t ino,
diff --git a/lib/ext2fs/inline_data.c b/lib/ext2fs/inline_data.c
index 7706747..04e2a06 100644
--- a/lib/ext2fs/inline_data.c
+++ b/lib/ext2fs/inline_data.c
@@ -557,6 +557,34 @@ out:
return retval;
}
+int ext2fs_inline_data_header_check(ext2_filsys fs, ext2_ino_t ino)
+{
+ struct ext2_inode_large *inode;
+ struct inline_data data;
+ errcode_t retval = 0;
+ int pass = 0;
+
+ retval = ext2fs_get_mem(EXT2_INODE_SIZE(fs->super), &inode);
+ if (retval)
+ return pass;
+
+ retval = ext2fs_read_inode_full(fs, ino, (void *)inode,
+ EXT2_INODE_SIZE(fs->super));
+ if (retval)
+ goto err;
+
+ retval = ext2fs_iget_extra_inode(fs, inode, &data);
+ if (retval)
+ goto err;
+
+ if (data.inline_off != 0)
+ pass = 1;
+
+err:
+ ext2fs_free_mem(&inode);
+ return pass;
+}
+
errcode_t ext2fs_convert_inline_data(ext2_filsys fs,
ext2_ino_t ino,
void *priv_data)
--
1.7.12.rc0.22.gcdd159b