diff options
author | Qu Wenruo <wqu@suse.com> | 2018-01-25 01:56:18 -0500 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2018-03-26 09:09:38 -0400 |
commit | 2f659546c9048931c2b8e146824a892b74a8e33c (patch) | |
tree | 887a2d812915a1c0156c0bb7efc327212de1db69 /fs/btrfs/tree-checker.c | |
parent | 393da91819e35af538ef97c7c6a04899e2fbfe0e (diff) |
btrfs: tree-checker: Replace root parameter with fs_info
When inspecting the error message with real corruption, the "root=%llu"
always shows "1" (root tree), instead of the correct owner.
The problem is that we are getting @root from page->mapping->host, which
points the same btree inode, so we will always get the same root.
This makes the root owner output meaningless, and harder to port
tree-checker to btrfs-progs.
So get rid of the false and meaningless @root parameter and replace it
with @fs_info.
To get the owner, we can only rely on btrfs_header_owner() now.
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/tree-checker.c')
-rw-r--r-- | fs/btrfs/tree-checker.c | 147 |
1 files changed, 75 insertions, 72 deletions
diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c index c3c8d48f6618..a5244f98f3b4 100644 --- a/fs/btrfs/tree-checker.c +++ b/fs/btrfs/tree-checker.c | |||
@@ -53,7 +53,7 @@ | |||
53 | * Allows callers to customize the output. | 53 | * Allows callers to customize the output. |
54 | */ | 54 | */ |
55 | __printf(4, 5) | 55 | __printf(4, 5) |
56 | static void generic_err(const struct btrfs_root *root, | 56 | static void generic_err(const struct btrfs_fs_info *fs_info, |
57 | const struct extent_buffer *eb, int slot, | 57 | const struct extent_buffer *eb, int slot, |
58 | const char *fmt, ...) | 58 | const char *fmt, ...) |
59 | { | 59 | { |
@@ -65,10 +65,10 @@ static void generic_err(const struct btrfs_root *root, | |||
65 | vaf.fmt = fmt; | 65 | vaf.fmt = fmt; |
66 | vaf.va = &args; | 66 | vaf.va = &args; |
67 | 67 | ||
68 | btrfs_crit(root->fs_info, | 68 | btrfs_crit(fs_info, |
69 | "corrupt %s: root=%llu block=%llu slot=%d, %pV", | 69 | "corrupt %s: root=%llu block=%llu slot=%d, %pV", |
70 | btrfs_header_level(eb) == 0 ? "leaf" : "node", | 70 | btrfs_header_level(eb) == 0 ? "leaf" : "node", |
71 | root->objectid, btrfs_header_bytenr(eb), slot, &vaf); | 71 | btrfs_header_owner(eb), btrfs_header_bytenr(eb), slot, &vaf); |
72 | va_end(args); | 72 | va_end(args); |
73 | } | 73 | } |
74 | 74 | ||
@@ -77,7 +77,7 @@ static void generic_err(const struct btrfs_root *root, | |||
77 | * offset has its own meaning. | 77 | * offset has its own meaning. |
78 | */ | 78 | */ |
79 | __printf(4, 5) | 79 | __printf(4, 5) |
80 | static void file_extent_err(const struct btrfs_root *root, | 80 | static void file_extent_err(const struct btrfs_fs_info *fs_info, |
81 | const struct extent_buffer *eb, int slot, | 81 | const struct extent_buffer *eb, int slot, |
82 | const char *fmt, ...) | 82 | const char *fmt, ...) |
83 | { | 83 | { |
@@ -91,10 +91,11 @@ static void file_extent_err(const struct btrfs_root *root, | |||
91 | vaf.fmt = fmt; | 91 | vaf.fmt = fmt; |
92 | vaf.va = &args; | 92 | vaf.va = &args; |
93 | 93 | ||
94 | btrfs_crit(root->fs_info, | 94 | btrfs_crit(fs_info, |
95 | "corrupt %s: root=%llu block=%llu slot=%d ino=%llu file_offset=%llu, %pV", | 95 | "corrupt %s: root=%llu block=%llu slot=%d ino=%llu file_offset=%llu, %pV", |
96 | btrfs_header_level(eb) == 0 ? "leaf" : "node", root->objectid, | 96 | btrfs_header_level(eb) == 0 ? "leaf" : "node", |
97 | btrfs_header_bytenr(eb), slot, key.objectid, key.offset, &vaf); | 97 | btrfs_header_owner(eb), btrfs_header_bytenr(eb), slot, |
98 | key.objectid, key.offset, &vaf); | ||
98 | va_end(args); | 99 | va_end(args); |
99 | } | 100 | } |
100 | 101 | ||
@@ -102,26 +103,26 @@ static void file_extent_err(const struct btrfs_root *root, | |||
102 | * Return 0 if the btrfs_file_extent_##name is aligned to @alignment | 103 | * Return 0 if the btrfs_file_extent_##name is aligned to @alignment |
103 | * Else return 1 | 104 | * Else return 1 |
104 | */ | 105 | */ |
105 | #define CHECK_FE_ALIGNED(root, leaf, slot, fi, name, alignment) \ | 106 | #define CHECK_FE_ALIGNED(fs_info, leaf, slot, fi, name, alignment) \ |
106 | ({ \ | 107 | ({ \ |
107 | if (!IS_ALIGNED(btrfs_file_extent_##name((leaf), (fi)), (alignment))) \ | 108 | if (!IS_ALIGNED(btrfs_file_extent_##name((leaf), (fi)), (alignment))) \ |
108 | file_extent_err((root), (leaf), (slot), \ | 109 | file_extent_err((fs_info), (leaf), (slot), \ |
109 | "invalid %s for file extent, have %llu, should be aligned to %u", \ | 110 | "invalid %s for file extent, have %llu, should be aligned to %u", \ |
110 | (#name), btrfs_file_extent_##name((leaf), (fi)), \ | 111 | (#name), btrfs_file_extent_##name((leaf), (fi)), \ |
111 | (alignment)); \ | 112 | (alignment)); \ |
112 | (!IS_ALIGNED(btrfs_file_extent_##name((leaf), (fi)), (alignment))); \ | 113 | (!IS_ALIGNED(btrfs_file_extent_##name((leaf), (fi)), (alignment))); \ |
113 | }) | 114 | }) |
114 | 115 | ||
115 | static int check_extent_data_item(struct btrfs_root *root, | 116 | static int check_extent_data_item(struct btrfs_fs_info *fs_info, |
116 | struct extent_buffer *leaf, | 117 | struct extent_buffer *leaf, |
117 | struct btrfs_key *key, int slot) | 118 | struct btrfs_key *key, int slot) |
118 | { | 119 | { |
119 | struct btrfs_file_extent_item *fi; | 120 | struct btrfs_file_extent_item *fi; |
120 | u32 sectorsize = root->fs_info->sectorsize; | 121 | u32 sectorsize = fs_info->sectorsize; |
121 | u32 item_size = btrfs_item_size_nr(leaf, slot); | 122 | u32 item_size = btrfs_item_size_nr(leaf, slot); |
122 | 123 | ||
123 | if (!IS_ALIGNED(key->offset, sectorsize)) { | 124 | if (!IS_ALIGNED(key->offset, sectorsize)) { |
124 | file_extent_err(root, leaf, slot, | 125 | file_extent_err(fs_info, leaf, slot, |
125 | "unaligned file_offset for file extent, have %llu should be aligned to %u", | 126 | "unaligned file_offset for file extent, have %llu should be aligned to %u", |
126 | key->offset, sectorsize); | 127 | key->offset, sectorsize); |
127 | return -EUCLEAN; | 128 | return -EUCLEAN; |
@@ -130,7 +131,7 @@ static int check_extent_data_item(struct btrfs_root *root, | |||
130 | fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); | 131 | fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); |
131 | 132 | ||
132 | if (btrfs_file_extent_type(leaf, fi) > BTRFS_FILE_EXTENT_TYPES) { | 133 | if (btrfs_file_extent_type(leaf, fi) > BTRFS_FILE_EXTENT_TYPES) { |
133 | file_extent_err(root, leaf, slot, | 134 | file_extent_err(fs_info, leaf, slot, |
134 | "invalid type for file extent, have %u expect range [0, %u]", | 135 | "invalid type for file extent, have %u expect range [0, %u]", |
135 | btrfs_file_extent_type(leaf, fi), | 136 | btrfs_file_extent_type(leaf, fi), |
136 | BTRFS_FILE_EXTENT_TYPES); | 137 | BTRFS_FILE_EXTENT_TYPES); |
@@ -142,14 +143,14 @@ static int check_extent_data_item(struct btrfs_root *root, | |||
142 | * and must be caught in open_ctree(). | 143 | * and must be caught in open_ctree(). |
143 | */ | 144 | */ |
144 | if (btrfs_file_extent_compression(leaf, fi) > BTRFS_COMPRESS_TYPES) { | 145 | if (btrfs_file_extent_compression(leaf, fi) > BTRFS_COMPRESS_TYPES) { |
145 | file_extent_err(root, leaf, slot, | 146 | file_extent_err(fs_info, leaf, slot, |
146 | "invalid compression for file extent, have %u expect range [0, %u]", | 147 | "invalid compression for file extent, have %u expect range [0, %u]", |
147 | btrfs_file_extent_compression(leaf, fi), | 148 | btrfs_file_extent_compression(leaf, fi), |
148 | BTRFS_COMPRESS_TYPES); | 149 | BTRFS_COMPRESS_TYPES); |
149 | return -EUCLEAN; | 150 | return -EUCLEAN; |
150 | } | 151 | } |
151 | if (btrfs_file_extent_encryption(leaf, fi)) { | 152 | if (btrfs_file_extent_encryption(leaf, fi)) { |
152 | file_extent_err(root, leaf, slot, | 153 | file_extent_err(fs_info, leaf, slot, |
153 | "invalid encryption for file extent, have %u expect 0", | 154 | "invalid encryption for file extent, have %u expect 0", |
154 | btrfs_file_extent_encryption(leaf, fi)); | 155 | btrfs_file_extent_encryption(leaf, fi)); |
155 | return -EUCLEAN; | 156 | return -EUCLEAN; |
@@ -157,7 +158,7 @@ static int check_extent_data_item(struct btrfs_root *root, | |||
157 | if (btrfs_file_extent_type(leaf, fi) == BTRFS_FILE_EXTENT_INLINE) { | 158 | if (btrfs_file_extent_type(leaf, fi) == BTRFS_FILE_EXTENT_INLINE) { |
158 | /* Inline extent must have 0 as key offset */ | 159 | /* Inline extent must have 0 as key offset */ |
159 | if (key->offset) { | 160 | if (key->offset) { |
160 | file_extent_err(root, leaf, slot, | 161 | file_extent_err(fs_info, leaf, slot, |
161 | "invalid file_offset for inline file extent, have %llu expect 0", | 162 | "invalid file_offset for inline file extent, have %llu expect 0", |
162 | key->offset); | 163 | key->offset); |
163 | return -EUCLEAN; | 164 | return -EUCLEAN; |
@@ -171,7 +172,7 @@ static int check_extent_data_item(struct btrfs_root *root, | |||
171 | /* Uncompressed inline extent size must match item size */ | 172 | /* Uncompressed inline extent size must match item size */ |
172 | if (item_size != BTRFS_FILE_EXTENT_INLINE_DATA_START + | 173 | if (item_size != BTRFS_FILE_EXTENT_INLINE_DATA_START + |
173 | btrfs_file_extent_ram_bytes(leaf, fi)) { | 174 | btrfs_file_extent_ram_bytes(leaf, fi)) { |
174 | file_extent_err(root, leaf, slot, | 175 | file_extent_err(fs_info, leaf, slot, |
175 | "invalid ram_bytes for uncompressed inline extent, have %u expect %llu", | 176 | "invalid ram_bytes for uncompressed inline extent, have %u expect %llu", |
176 | item_size, BTRFS_FILE_EXTENT_INLINE_DATA_START + | 177 | item_size, BTRFS_FILE_EXTENT_INLINE_DATA_START + |
177 | btrfs_file_extent_ram_bytes(leaf, fi)); | 178 | btrfs_file_extent_ram_bytes(leaf, fi)); |
@@ -182,40 +183,41 @@ static int check_extent_data_item(struct btrfs_root *root, | |||
182 | 183 | ||
183 | /* Regular or preallocated extent has fixed item size */ | 184 | /* Regular or preallocated extent has fixed item size */ |
184 | if (item_size != sizeof(*fi)) { | 185 | if (item_size != sizeof(*fi)) { |
185 | file_extent_err(root, leaf, slot, | 186 | file_extent_err(fs_info, leaf, slot, |
186 | "invalid item size for reg/prealloc file extent, have %u expect %zu", | 187 | "invalid item size for reg/prealloc file extent, have %u expect %zu", |
187 | item_size, sizeof(*fi)); | 188 | item_size, sizeof(*fi)); |
188 | return -EUCLEAN; | 189 | return -EUCLEAN; |
189 | } | 190 | } |
190 | if (CHECK_FE_ALIGNED(root, leaf, slot, fi, ram_bytes, sectorsize) || | 191 | if (CHECK_FE_ALIGNED(fs_info, leaf, slot, fi, ram_bytes, sectorsize) || |
191 | CHECK_FE_ALIGNED(root, leaf, slot, fi, disk_bytenr, sectorsize) || | 192 | CHECK_FE_ALIGNED(fs_info, leaf, slot, fi, disk_bytenr, sectorsize) || |
192 | CHECK_FE_ALIGNED(root, leaf, slot, fi, disk_num_bytes, sectorsize) || | 193 | CHECK_FE_ALIGNED(fs_info, leaf, slot, fi, disk_num_bytes, sectorsize) || |
193 | CHECK_FE_ALIGNED(root, leaf, slot, fi, offset, sectorsize) || | 194 | CHECK_FE_ALIGNED(fs_info, leaf, slot, fi, offset, sectorsize) || |
194 | CHECK_FE_ALIGNED(root, leaf, slot, fi, num_bytes, sectorsize)) | 195 | CHECK_FE_ALIGNED(fs_info, leaf, slot, fi, num_bytes, sectorsize)) |
195 | return -EUCLEAN; | 196 | return -EUCLEAN; |
196 | return 0; | 197 | return 0; |
197 | } | 198 | } |
198 | 199 | ||
199 | static int check_csum_item(struct btrfs_root *root, struct extent_buffer *leaf, | 200 | static int check_csum_item(struct btrfs_fs_info *fs_info, |
200 | struct btrfs_key *key, int slot) | 201 | struct extent_buffer *leaf, struct btrfs_key *key, |
202 | int slot) | ||
201 | { | 203 | { |
202 | u32 sectorsize = root->fs_info->sectorsize; | 204 | u32 sectorsize = fs_info->sectorsize; |
203 | u32 csumsize = btrfs_super_csum_size(root->fs_info->super_copy); | 205 | u32 csumsize = btrfs_super_csum_size(fs_info->super_copy); |
204 | 206 | ||
205 | if (key->objectid != BTRFS_EXTENT_CSUM_OBJECTID) { | 207 | if (key->objectid != BTRFS_EXTENT_CSUM_OBJECTID) { |
206 | generic_err(root, leaf, slot, | 208 | generic_err(fs_info, leaf, slot, |
207 | "invalid key objectid for csum item, have %llu expect %llu", | 209 | "invalid key objectid for csum item, have %llu expect %llu", |
208 | key->objectid, BTRFS_EXTENT_CSUM_OBJECTID); | 210 | key->objectid, BTRFS_EXTENT_CSUM_OBJECTID); |
209 | return -EUCLEAN; | 211 | return -EUCLEAN; |
210 | } | 212 | } |
211 | if (!IS_ALIGNED(key->offset, sectorsize)) { | 213 | if (!IS_ALIGNED(key->offset, sectorsize)) { |
212 | generic_err(root, leaf, slot, | 214 | generic_err(fs_info, leaf, slot, |
213 | "unaligned key offset for csum item, have %llu should be aligned to %u", | 215 | "unaligned key offset for csum item, have %llu should be aligned to %u", |
214 | key->offset, sectorsize); | 216 | key->offset, sectorsize); |
215 | return -EUCLEAN; | 217 | return -EUCLEAN; |
216 | } | 218 | } |
217 | if (!IS_ALIGNED(btrfs_item_size_nr(leaf, slot), csumsize)) { | 219 | if (!IS_ALIGNED(btrfs_item_size_nr(leaf, slot), csumsize)) { |
218 | generic_err(root, leaf, slot, | 220 | generic_err(fs_info, leaf, slot, |
219 | "unaligned item size for csum item, have %u should be aligned to %u", | 221 | "unaligned item size for csum item, have %u should be aligned to %u", |
220 | btrfs_item_size_nr(leaf, slot), csumsize); | 222 | btrfs_item_size_nr(leaf, slot), csumsize); |
221 | return -EUCLEAN; | 223 | return -EUCLEAN; |
@@ -228,7 +230,7 @@ static int check_csum_item(struct btrfs_root *root, struct extent_buffer *leaf, | |||
228 | * which represents inode number | 230 | * which represents inode number |
229 | */ | 231 | */ |
230 | __printf(4, 5) | 232 | __printf(4, 5) |
231 | static void dir_item_err(const struct btrfs_root *root, | 233 | static void dir_item_err(const struct btrfs_fs_info *fs_info, |
232 | const struct extent_buffer *eb, int slot, | 234 | const struct extent_buffer *eb, int slot, |
233 | const char *fmt, ...) | 235 | const char *fmt, ...) |
234 | { | 236 | { |
@@ -242,14 +244,15 @@ static void dir_item_err(const struct btrfs_root *root, | |||
242 | vaf.fmt = fmt; | 244 | vaf.fmt = fmt; |
243 | vaf.va = &args; | 245 | vaf.va = &args; |
244 | 246 | ||
245 | btrfs_crit(root->fs_info, | 247 | btrfs_crit(fs_info, |
246 | "corrupt %s: root=%llu block=%llu slot=%d ino=%llu, %pV", | 248 | "corrupt %s: root=%llu block=%llu slot=%d ino=%llu, %pV", |
247 | btrfs_header_level(eb) == 0 ? "leaf" : "node", root->objectid, | 249 | btrfs_header_level(eb) == 0 ? "leaf" : "node", |
248 | btrfs_header_bytenr(eb), slot, key.objectid, &vaf); | 250 | btrfs_header_owner(eb), btrfs_header_bytenr(eb), slot, |
251 | key.objectid, &vaf); | ||
249 | va_end(args); | 252 | va_end(args); |
250 | } | 253 | } |
251 | 254 | ||
252 | static int check_dir_item(struct btrfs_root *root, | 255 | static int check_dir_item(struct btrfs_fs_info *fs_info, |
253 | struct extent_buffer *leaf, | 256 | struct extent_buffer *leaf, |
254 | struct btrfs_key *key, int slot) | 257 | struct btrfs_key *key, int slot) |
255 | { | 258 | { |
@@ -268,7 +271,7 @@ static int check_dir_item(struct btrfs_root *root, | |||
268 | 271 | ||
269 | /* header itself should not cross item boundary */ | 272 | /* header itself should not cross item boundary */ |
270 | if (cur + sizeof(*di) > item_size) { | 273 | if (cur + sizeof(*di) > item_size) { |
271 | dir_item_err(root, leaf, slot, | 274 | dir_item_err(fs_info, leaf, slot, |
272 | "dir item header crosses item boundary, have %zu boundary %u", | 275 | "dir item header crosses item boundary, have %zu boundary %u", |
273 | cur + sizeof(*di), item_size); | 276 | cur + sizeof(*di), item_size); |
274 | return -EUCLEAN; | 277 | return -EUCLEAN; |
@@ -277,7 +280,7 @@ static int check_dir_item(struct btrfs_root *root, | |||
277 | /* dir type check */ | 280 | /* dir type check */ |
278 | dir_type = btrfs_dir_type(leaf, di); | 281 | dir_type = btrfs_dir_type(leaf, di); |
279 | if (dir_type >= BTRFS_FT_MAX) { | 282 | if (dir_type >= BTRFS_FT_MAX) { |
280 | dir_item_err(root, leaf, slot, | 283 | dir_item_err(fs_info, leaf, slot, |
281 | "invalid dir item type, have %u expect [0, %u)", | 284 | "invalid dir item type, have %u expect [0, %u)", |
282 | dir_type, BTRFS_FT_MAX); | 285 | dir_type, BTRFS_FT_MAX); |
283 | return -EUCLEAN; | 286 | return -EUCLEAN; |
@@ -285,14 +288,14 @@ static int check_dir_item(struct btrfs_root *root, | |||
285 | 288 | ||
286 | if (key->type == BTRFS_XATTR_ITEM_KEY && | 289 | if (key->type == BTRFS_XATTR_ITEM_KEY && |
287 | dir_type != BTRFS_FT_XATTR) { | 290 | dir_type != BTRFS_FT_XATTR) { |
288 | dir_item_err(root, leaf, slot, | 291 | dir_item_err(fs_info, leaf, slot, |
289 | "invalid dir item type for XATTR key, have %u expect %u", | 292 | "invalid dir item type for XATTR key, have %u expect %u", |
290 | dir_type, BTRFS_FT_XATTR); | 293 | dir_type, BTRFS_FT_XATTR); |
291 | return -EUCLEAN; | 294 | return -EUCLEAN; |
292 | } | 295 | } |
293 | if (dir_type == BTRFS_FT_XATTR && | 296 | if (dir_type == BTRFS_FT_XATTR && |
294 | key->type != BTRFS_XATTR_ITEM_KEY) { | 297 | key->type != BTRFS_XATTR_ITEM_KEY) { |
295 | dir_item_err(root, leaf, slot, | 298 | dir_item_err(fs_info, leaf, slot, |
296 | "xattr dir type found for non-XATTR key"); | 299 | "xattr dir type found for non-XATTR key"); |
297 | return -EUCLEAN; | 300 | return -EUCLEAN; |
298 | } | 301 | } |
@@ -305,21 +308,21 @@ static int check_dir_item(struct btrfs_root *root, | |||
305 | name_len = btrfs_dir_name_len(leaf, di); | 308 | name_len = btrfs_dir_name_len(leaf, di); |
306 | data_len = btrfs_dir_data_len(leaf, di); | 309 | data_len = btrfs_dir_data_len(leaf, di); |
307 | if (name_len > max_name_len) { | 310 | if (name_len > max_name_len) { |
308 | dir_item_err(root, leaf, slot, | 311 | dir_item_err(fs_info, leaf, slot, |
309 | "dir item name len too long, have %u max %u", | 312 | "dir item name len too long, have %u max %u", |
310 | name_len, max_name_len); | 313 | name_len, max_name_len); |
311 | return -EUCLEAN; | 314 | return -EUCLEAN; |
312 | } | 315 | } |
313 | if (name_len + data_len > BTRFS_MAX_XATTR_SIZE(root->fs_info)) { | 316 | if (name_len + data_len > BTRFS_MAX_XATTR_SIZE(fs_info)) { |
314 | dir_item_err(root, leaf, slot, | 317 | dir_item_err(fs_info, leaf, slot, |
315 | "dir item name and data len too long, have %u max %u", | 318 | "dir item name and data len too long, have %u max %u", |
316 | name_len + data_len, | 319 | name_len + data_len, |
317 | BTRFS_MAX_XATTR_SIZE(root->fs_info)); | 320 | BTRFS_MAX_XATTR_SIZE(fs_info)); |
318 | return -EUCLEAN; | 321 | return -EUCLEAN; |
319 | } | 322 | } |
320 | 323 | ||
321 | if (data_len && dir_type != BTRFS_FT_XATTR) { | 324 | if (data_len && dir_type != BTRFS_FT_XATTR) { |
322 | dir_item_err(root, leaf, slot, | 325 | dir_item_err(fs_info, leaf, slot, |
323 | "dir item with invalid data len, have %u expect 0", | 326 | "dir item with invalid data len, have %u expect 0", |
324 | data_len); | 327 | data_len); |
325 | return -EUCLEAN; | 328 | return -EUCLEAN; |
@@ -329,7 +332,7 @@ static int check_dir_item(struct btrfs_root *root, | |||
329 | 332 | ||
330 | /* header and name/data should not cross item boundary */ | 333 | /* header and name/data should not cross item boundary */ |
331 | if (cur + total_size > item_size) { | 334 | if (cur + total_size > item_size) { |
332 | dir_item_err(root, leaf, slot, | 335 | dir_item_err(fs_info, leaf, slot, |
333 | "dir item data crosses item boundary, have %u boundary %u", | 336 | "dir item data crosses item boundary, have %u boundary %u", |
334 | cur + total_size, item_size); | 337 | cur + total_size, item_size); |
335 | return -EUCLEAN; | 338 | return -EUCLEAN; |
@@ -347,7 +350,7 @@ static int check_dir_item(struct btrfs_root *root, | |||
347 | (unsigned long)(di + 1), name_len); | 350 | (unsigned long)(di + 1), name_len); |
348 | name_hash = btrfs_name_hash(namebuf, name_len); | 351 | name_hash = btrfs_name_hash(namebuf, name_len); |
349 | if (key->offset != name_hash) { | 352 | if (key->offset != name_hash) { |
350 | dir_item_err(root, leaf, slot, | 353 | dir_item_err(fs_info, leaf, slot, |
351 | "name hash mismatch with key, have 0x%016x expect 0x%016llx", | 354 | "name hash mismatch with key, have 0x%016x expect 0x%016llx", |
352 | name_hash, key->offset); | 355 | name_hash, key->offset); |
353 | return -EUCLEAN; | 356 | return -EUCLEAN; |
@@ -362,7 +365,7 @@ static int check_dir_item(struct btrfs_root *root, | |||
362 | /* | 365 | /* |
363 | * Common point to switch the item-specific validation. | 366 | * Common point to switch the item-specific validation. |
364 | */ | 367 | */ |
365 | static int check_leaf_item(struct btrfs_root *root, | 368 | static int check_leaf_item(struct btrfs_fs_info *fs_info, |
366 | struct extent_buffer *leaf, | 369 | struct extent_buffer *leaf, |
367 | struct btrfs_key *key, int slot) | 370 | struct btrfs_key *key, int slot) |
368 | { | 371 | { |
@@ -370,24 +373,23 @@ static int check_leaf_item(struct btrfs_root *root, | |||
370 | 373 | ||
371 | switch (key->type) { | 374 | switch (key->type) { |
372 | case BTRFS_EXTENT_DATA_KEY: | 375 | case BTRFS_EXTENT_DATA_KEY: |
373 | ret = check_extent_data_item(root, leaf, key, slot); | 376 | ret = check_extent_data_item(fs_info, leaf, key, slot); |
374 | break; | 377 | break; |
375 | case BTRFS_EXTENT_CSUM_KEY: | 378 | case BTRFS_EXTENT_CSUM_KEY: |
376 | ret = check_csum_item(root, leaf, key, slot); | 379 | ret = check_csum_item(fs_info, leaf, key, slot); |
377 | break; | 380 | break; |
378 | case BTRFS_DIR_ITEM_KEY: | 381 | case BTRFS_DIR_ITEM_KEY: |
379 | case BTRFS_DIR_INDEX_KEY: | 382 | case BTRFS_DIR_INDEX_KEY: |
380 | case BTRFS_XATTR_ITEM_KEY: | 383 | case BTRFS_XATTR_ITEM_KEY: |
381 | ret = check_dir_item(root, leaf, key, slot); | 384 | ret = check_dir_item(fs_info, leaf, key, slot); |
382 | break; | 385 | break; |
383 | } | 386 | } |
384 | return ret; | 387 | return ret; |
385 | } | 388 | } |
386 | 389 | ||
387 | static int check_leaf(struct btrfs_root *root, struct extent_buffer *leaf, | 390 | static int check_leaf(struct btrfs_fs_info *fs_info, struct extent_buffer *leaf, |
388 | bool check_item_data) | 391 | bool check_item_data) |
389 | { | 392 | { |
390 | struct btrfs_fs_info *fs_info = root->fs_info; | ||
391 | /* No valid key type is 0, so all key should be larger than this key */ | 393 | /* No valid key type is 0, so all key should be larger than this key */ |
392 | struct btrfs_key prev_key = {0, 0, 0}; | 394 | struct btrfs_key prev_key = {0, 0, 0}; |
393 | struct btrfs_key key; | 395 | struct btrfs_key key; |
@@ -420,7 +422,7 @@ static int check_leaf(struct btrfs_root *root, struct extent_buffer *leaf, | |||
420 | eb = btrfs_root_node(check_root); | 422 | eb = btrfs_root_node(check_root); |
421 | /* if leaf is the root, then it's fine */ | 423 | /* if leaf is the root, then it's fine */ |
422 | if (leaf != eb) { | 424 | if (leaf != eb) { |
423 | generic_err(check_root, leaf, 0, | 425 | generic_err(fs_info, leaf, 0, |
424 | "invalid nritems, have %u should not be 0 for non-root leaf", | 426 | "invalid nritems, have %u should not be 0 for non-root leaf", |
425 | nritems); | 427 | nritems); |
426 | free_extent_buffer(eb); | 428 | free_extent_buffer(eb); |
@@ -453,7 +455,7 @@ static int check_leaf(struct btrfs_root *root, struct extent_buffer *leaf, | |||
453 | 455 | ||
454 | /* Make sure the keys are in the right order */ | 456 | /* Make sure the keys are in the right order */ |
455 | if (btrfs_comp_cpu_keys(&prev_key, &key) >= 0) { | 457 | if (btrfs_comp_cpu_keys(&prev_key, &key) >= 0) { |
456 | generic_err(root, leaf, slot, | 458 | generic_err(fs_info, leaf, slot, |
457 | "bad key order, prev (%llu %u %llu) current (%llu %u %llu)", | 459 | "bad key order, prev (%llu %u %llu) current (%llu %u %llu)", |
458 | prev_key.objectid, prev_key.type, | 460 | prev_key.objectid, prev_key.type, |
459 | prev_key.offset, key.objectid, key.type, | 461 | prev_key.offset, key.objectid, key.type, |
@@ -472,7 +474,7 @@ static int check_leaf(struct btrfs_root *root, struct extent_buffer *leaf, | |||
472 | item_end_expected = btrfs_item_offset_nr(leaf, | 474 | item_end_expected = btrfs_item_offset_nr(leaf, |
473 | slot - 1); | 475 | slot - 1); |
474 | if (btrfs_item_end_nr(leaf, slot) != item_end_expected) { | 476 | if (btrfs_item_end_nr(leaf, slot) != item_end_expected) { |
475 | generic_err(root, leaf, slot, | 477 | generic_err(fs_info, leaf, slot, |
476 | "unexpected item end, have %u expect %u", | 478 | "unexpected item end, have %u expect %u", |
477 | btrfs_item_end_nr(leaf, slot), | 479 | btrfs_item_end_nr(leaf, slot), |
478 | item_end_expected); | 480 | item_end_expected); |
@@ -486,7 +488,7 @@ static int check_leaf(struct btrfs_root *root, struct extent_buffer *leaf, | |||
486 | */ | 488 | */ |
487 | if (btrfs_item_end_nr(leaf, slot) > | 489 | if (btrfs_item_end_nr(leaf, slot) > |
488 | BTRFS_LEAF_DATA_SIZE(fs_info)) { | 490 | BTRFS_LEAF_DATA_SIZE(fs_info)) { |
489 | generic_err(root, leaf, slot, | 491 | generic_err(fs_info, leaf, slot, |
490 | "slot end outside of leaf, have %u expect range [0, %u]", | 492 | "slot end outside of leaf, have %u expect range [0, %u]", |
491 | btrfs_item_end_nr(leaf, slot), | 493 | btrfs_item_end_nr(leaf, slot), |
492 | BTRFS_LEAF_DATA_SIZE(fs_info)); | 494 | BTRFS_LEAF_DATA_SIZE(fs_info)); |
@@ -496,7 +498,7 @@ static int check_leaf(struct btrfs_root *root, struct extent_buffer *leaf, | |||
496 | /* Also check if the item pointer overlaps with btrfs item. */ | 498 | /* Also check if the item pointer overlaps with btrfs item. */ |
497 | if (btrfs_item_nr_offset(slot) + sizeof(struct btrfs_item) > | 499 | if (btrfs_item_nr_offset(slot) + sizeof(struct btrfs_item) > |
498 | btrfs_item_ptr_offset(leaf, slot)) { | 500 | btrfs_item_ptr_offset(leaf, slot)) { |
499 | generic_err(root, leaf, slot, | 501 | generic_err(fs_info, leaf, slot, |
500 | "slot overlaps with its data, item end %lu data start %lu", | 502 | "slot overlaps with its data, item end %lu data start %lu", |
501 | btrfs_item_nr_offset(slot) + | 503 | btrfs_item_nr_offset(slot) + |
502 | sizeof(struct btrfs_item), | 504 | sizeof(struct btrfs_item), |
@@ -509,7 +511,7 @@ static int check_leaf(struct btrfs_root *root, struct extent_buffer *leaf, | |||
509 | * Check if the item size and content meet other | 511 | * Check if the item size and content meet other |
510 | * criteria | 512 | * criteria |
511 | */ | 513 | */ |
512 | ret = check_leaf_item(root, leaf, &key, slot); | 514 | ret = check_leaf_item(fs_info, leaf, &key, slot); |
513 | if (ret < 0) | 515 | if (ret < 0) |
514 | return ret; | 516 | return ret; |
515 | } | 517 | } |
@@ -522,18 +524,19 @@ static int check_leaf(struct btrfs_root *root, struct extent_buffer *leaf, | |||
522 | return 0; | 524 | return 0; |
523 | } | 525 | } |
524 | 526 | ||
525 | int btrfs_check_leaf_full(struct btrfs_root *root, struct extent_buffer *leaf) | 527 | int btrfs_check_leaf_full(struct btrfs_fs_info *fs_info, |
528 | struct extent_buffer *leaf) | ||
526 | { | 529 | { |
527 | return check_leaf(root, leaf, true); | 530 | return check_leaf(fs_info, leaf, true); |
528 | } | 531 | } |
529 | 532 | ||
530 | int btrfs_check_leaf_relaxed(struct btrfs_root *root, | 533 | int btrfs_check_leaf_relaxed(struct btrfs_fs_info *fs_info, |
531 | struct extent_buffer *leaf) | 534 | struct extent_buffer *leaf) |
532 | { | 535 | { |
533 | return check_leaf(root, leaf, false); | 536 | return check_leaf(fs_info, leaf, false); |
534 | } | 537 | } |
535 | 538 | ||
536 | int btrfs_check_node(struct btrfs_root *root, struct extent_buffer *node) | 539 | int btrfs_check_node(struct btrfs_fs_info *fs_info, struct extent_buffer *node) |
537 | { | 540 | { |
538 | unsigned long nr = btrfs_header_nritems(node); | 541 | unsigned long nr = btrfs_header_nritems(node); |
539 | struct btrfs_key key, next_key; | 542 | struct btrfs_key key, next_key; |
@@ -541,12 +544,12 @@ int btrfs_check_node(struct btrfs_root *root, struct extent_buffer *node) | |||
541 | u64 bytenr; | 544 | u64 bytenr; |
542 | int ret = 0; | 545 | int ret = 0; |
543 | 546 | ||
544 | if (nr == 0 || nr > BTRFS_NODEPTRS_PER_BLOCK(root->fs_info)) { | 547 | if (nr == 0 || nr > BTRFS_NODEPTRS_PER_BLOCK(fs_info)) { |
545 | btrfs_crit(root->fs_info, | 548 | btrfs_crit(fs_info, |
546 | "corrupt node: root=%llu block=%llu, nritems too %s, have %lu expect range [1,%u]", | 549 | "corrupt node: root=%llu block=%llu, nritems too %s, have %lu expect range [1,%u]", |
547 | root->objectid, node->start, | 550 | btrfs_header_owner(node), node->start, |
548 | nr == 0 ? "small" : "large", nr, | 551 | nr == 0 ? "small" : "large", nr, |
549 | BTRFS_NODEPTRS_PER_BLOCK(root->fs_info)); | 552 | BTRFS_NODEPTRS_PER_BLOCK(fs_info)); |
550 | return -EUCLEAN; | 553 | return -EUCLEAN; |
551 | } | 554 | } |
552 | 555 | ||
@@ -556,21 +559,21 @@ int btrfs_check_node(struct btrfs_root *root, struct extent_buffer *node) | |||
556 | btrfs_node_key_to_cpu(node, &next_key, slot + 1); | 559 | btrfs_node_key_to_cpu(node, &next_key, slot + 1); |
557 | 560 | ||
558 | if (!bytenr) { | 561 | if (!bytenr) { |
559 | generic_err(root, node, slot, | 562 | generic_err(fs_info, node, slot, |
560 | "invalid NULL node pointer"); | 563 | "invalid NULL node pointer"); |
561 | ret = -EUCLEAN; | 564 | ret = -EUCLEAN; |
562 | goto out; | 565 | goto out; |
563 | } | 566 | } |
564 | if (!IS_ALIGNED(bytenr, root->fs_info->sectorsize)) { | 567 | if (!IS_ALIGNED(bytenr, fs_info->sectorsize)) { |
565 | generic_err(root, node, slot, | 568 | generic_err(fs_info, node, slot, |
566 | "unaligned pointer, have %llu should be aligned to %u", | 569 | "unaligned pointer, have %llu should be aligned to %u", |
567 | bytenr, root->fs_info->sectorsize); | 570 | bytenr, fs_info->sectorsize); |
568 | ret = -EUCLEAN; | 571 | ret = -EUCLEAN; |
569 | goto out; | 572 | goto out; |
570 | } | 573 | } |
571 | 574 | ||
572 | if (btrfs_comp_cpu_keys(&key, &next_key) >= 0) { | 575 | if (btrfs_comp_cpu_keys(&key, &next_key) >= 0) { |
573 | generic_err(root, node, slot, | 576 | generic_err(fs_info, node, slot, |
574 | "bad key order, current (%llu %u %llu) next (%llu %u %llu)", | 577 | "bad key order, current (%llu %u %llu) next (%llu %u %llu)", |
575 | key.objectid, key.type, key.offset, | 578 | key.objectid, key.type, key.offset, |
576 | next_key.objectid, next_key.type, | 579 | next_key.objectid, next_key.type, |