aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJan Schmidt <list.btrfs@jan-o-sch.net>2011-06-13 13:59:12 -0400
committerJan Schmidt <list.btrfs@jan-o-sch.net>2011-09-29 06:54:28 -0400
commit558540c17771eaf89b1a3be39aa2c8bc837da1a6 (patch)
treecd456e32dea87a93f324b63e02ecd3add96e0e77 /fs
parent13db62b7a1e8c64763a93c155091620f85ff8920 (diff)
btrfs scrub: print paths of corrupted files
While scrubbing, we may encounter various errors. Previously, a logical address was printed to the log only. Now, all paths belonging to that address are resolved and printed separately. That should work for hardlinks as well as reflinks. Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
Diffstat (limited to 'fs')
-rw-r--r--fs/btrfs/scrub.c169
1 files changed, 163 insertions, 6 deletions
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 35099fa97d56..221fd5c48736 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -17,10 +17,12 @@
17 */ 17 */
18 18
19#include <linux/blkdev.h> 19#include <linux/blkdev.h>
20#include <linux/ratelimit.h>
20#include "ctree.h" 21#include "ctree.h"
21#include "volumes.h" 22#include "volumes.h"
22#include "disk-io.h" 23#include "disk-io.h"
23#include "ordered-data.h" 24#include "ordered-data.h"
25#include "backref.h"
24 26
25/* 27/*
26 * This is only the first step towards a full-features scrub. It reads all 28 * This is only the first step towards a full-features scrub. It reads all
@@ -100,6 +102,19 @@ struct scrub_dev {
100 spinlock_t stat_lock; 102 spinlock_t stat_lock;
101}; 103};
102 104
105struct scrub_warning {
106 struct btrfs_path *path;
107 u64 extent_item_size;
108 char *scratch_buf;
109 char *msg_buf;
110 const char *errstr;
111 sector_t sector;
112 u64 logical;
113 struct btrfs_device *dev;
114 int msg_bufsize;
115 int scratch_bufsize;
116};
117
103static void scrub_free_csums(struct scrub_dev *sdev) 118static void scrub_free_csums(struct scrub_dev *sdev)
104{ 119{
105 while (!list_empty(&sdev->csum_list)) { 120 while (!list_empty(&sdev->csum_list)) {
@@ -195,6 +210,143 @@ nomem:
195 return ERR_PTR(-ENOMEM); 210 return ERR_PTR(-ENOMEM);
196} 211}
197 212
213static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root, void *ctx)
214{
215 u64 isize;
216 u32 nlink;
217 int ret;
218 int i;
219 struct extent_buffer *eb;
220 struct btrfs_inode_item *inode_item;
221 struct scrub_warning *swarn = ctx;
222 struct btrfs_fs_info *fs_info = swarn->dev->dev_root->fs_info;
223 struct inode_fs_paths *ipath = NULL;
224 struct btrfs_root *local_root;
225 struct btrfs_key root_key;
226
227 root_key.objectid = root;
228 root_key.type = BTRFS_ROOT_ITEM_KEY;
229 root_key.offset = (u64)-1;
230 local_root = btrfs_read_fs_root_no_name(fs_info, &root_key);
231 if (IS_ERR(local_root)) {
232 ret = PTR_ERR(local_root);
233 goto err;
234 }
235
236 ret = inode_item_info(inum, 0, local_root, swarn->path);
237 if (ret) {
238 btrfs_release_path(swarn->path);
239 goto err;
240 }
241
242 eb = swarn->path->nodes[0];
243 inode_item = btrfs_item_ptr(eb, swarn->path->slots[0],
244 struct btrfs_inode_item);
245 isize = btrfs_inode_size(eb, inode_item);
246 nlink = btrfs_inode_nlink(eb, inode_item);
247 btrfs_release_path(swarn->path);
248
249 ipath = init_ipath(4096, local_root, swarn->path);
250 ret = paths_from_inode(inum, ipath);
251
252 if (ret < 0)
253 goto err;
254
255 /*
256 * we deliberately ignore the bit ipath might have been too small to
257 * hold all of the paths here
258 */
259 for (i = 0; i < ipath->fspath->elem_cnt; ++i)
260 printk(KERN_WARNING "btrfs: %s at logical %llu on dev "
261 "%s, sector %llu, root %llu, inode %llu, offset %llu, "
262 "length %llu, links %u (path: %s)\n", swarn->errstr,
263 swarn->logical, swarn->dev->name,
264 (unsigned long long)swarn->sector, root, inum, offset,
265 min(isize - offset, (u64)PAGE_SIZE), nlink,
266 ipath->fspath->str[i]);
267
268 free_ipath(ipath);
269 return 0;
270
271err:
272 printk(KERN_WARNING "btrfs: %s at logical %llu on dev "
273 "%s, sector %llu, root %llu, inode %llu, offset %llu: path "
274 "resolving failed with ret=%d\n", swarn->errstr,
275 swarn->logical, swarn->dev->name,
276 (unsigned long long)swarn->sector, root, inum, offset, ret);
277
278 free_ipath(ipath);
279 return 0;
280}
281
282static void scrub_print_warning(const char *errstr, struct scrub_bio *sbio,
283 int ix)
284{
285 struct btrfs_device *dev = sbio->sdev->dev;
286 struct btrfs_fs_info *fs_info = dev->dev_root->fs_info;
287 struct btrfs_path *path;
288 struct btrfs_key found_key;
289 struct extent_buffer *eb;
290 struct btrfs_extent_item *ei;
291 struct scrub_warning swarn;
292 u32 item_size;
293 int ret;
294 u64 ref_root;
295 u8 ref_level;
296 unsigned long ptr = 0;
297 const int bufsize = 4096;
298 u64 extent_offset;
299
300 path = btrfs_alloc_path();
301
302 swarn.scratch_buf = kmalloc(bufsize, GFP_NOFS);
303 swarn.msg_buf = kmalloc(bufsize, GFP_NOFS);
304 swarn.sector = (sbio->physical + ix * PAGE_SIZE) >> 9;
305 swarn.logical = sbio->logical + ix * PAGE_SIZE;
306 swarn.errstr = errstr;
307 swarn.dev = dev;
308 swarn.msg_bufsize = bufsize;
309 swarn.scratch_bufsize = bufsize;
310
311 if (!path || !swarn.scratch_buf || !swarn.msg_buf)
312 goto out;
313
314 ret = extent_from_logical(fs_info, swarn.logical, path, &found_key);
315 if (ret < 0)
316 goto out;
317
318 extent_offset = swarn.logical - found_key.objectid;
319 swarn.extent_item_size = found_key.offset;
320
321 eb = path->nodes[0];
322 ei = btrfs_item_ptr(eb, path->slots[0], struct btrfs_extent_item);
323 item_size = btrfs_item_size_nr(eb, path->slots[0]);
324
325 if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
326 do {
327 ret = tree_backref_for_extent(&ptr, eb, ei, item_size,
328 &ref_root, &ref_level);
329 printk(KERN_WARNING "%s at logical %llu on dev %s, "
330 "sector %llu: metadata %s (level %d) in tree "
331 "%llu\n", errstr, swarn.logical, dev->name,
332 (unsigned long long)swarn.sector,
333 ref_level ? "node" : "leaf",
334 ret < 0 ? -1 : ref_level,
335 ret < 0 ? -1 : ref_root);
336 } while (ret != 1);
337 } else {
338 swarn.path = path;
339 iterate_extent_inodes(fs_info, path, found_key.objectid,
340 extent_offset,
341 scrub_print_warning_inode, &swarn);
342 }
343
344out:
345 btrfs_free_path(path);
346 kfree(swarn.scratch_buf);
347 kfree(swarn.msg_buf);
348}
349
198/* 350/*
199 * scrub_recheck_error gets called when either verification of the page 351 * scrub_recheck_error gets called when either verification of the page
200 * failed or the bio failed to read, e.g. with EIO. In the latter case, 352 * failed or the bio failed to read, e.g. with EIO. In the latter case,
@@ -205,6 +357,8 @@ static int scrub_recheck_error(struct scrub_bio *sbio, int ix)
205{ 357{
206 struct scrub_dev *sdev = sbio->sdev; 358 struct scrub_dev *sdev = sbio->sdev;
207 u64 sector = (sbio->physical + ix * PAGE_SIZE) >> 9; 359 u64 sector = (sbio->physical + ix * PAGE_SIZE) >> 9;
360 static DEFINE_RATELIMIT_STATE(_rs, DEFAULT_RATELIMIT_INTERVAL,
361 DEFAULT_RATELIMIT_BURST);
208 362
209 if (sbio->err) { 363 if (sbio->err) {
210 if (scrub_fixup_io(READ, sbio->sdev->dev->bdev, sector, 364 if (scrub_fixup_io(READ, sbio->sdev->dev->bdev, sector,
@@ -212,6 +366,11 @@ static int scrub_recheck_error(struct scrub_bio *sbio, int ix)
212 if (scrub_fixup_check(sbio, ix) == 0) 366 if (scrub_fixup_check(sbio, ix) == 0)
213 return 0; 367 return 0;
214 } 368 }
369 if (__ratelimit(&_rs))
370 scrub_print_warning("i/o error", sbio, ix);
371 } else {
372 if (__ratelimit(&_rs))
373 scrub_print_warning("checksum error", sbio, ix);
215 } 374 }
216 375
217 spin_lock(&sdev->stat_lock); 376 spin_lock(&sdev->stat_lock);
@@ -326,9 +485,8 @@ static void scrub_fixup(struct scrub_bio *sbio, int ix)
326 ++sdev->stat.corrected_errors; 485 ++sdev->stat.corrected_errors;
327 spin_unlock(&sdev->stat_lock); 486 spin_unlock(&sdev->stat_lock);
328 487
329 if (printk_ratelimit()) 488 printk_ratelimited(KERN_ERR "btrfs: fixed up error at logical %llu\n",
330 printk(KERN_ERR "btrfs: fixed up at %llu\n", 489 (unsigned long long)logical);
331 (unsigned long long)logical);
332 return; 490 return;
333 491
334uncorrectable: 492uncorrectable:
@@ -337,9 +495,8 @@ uncorrectable:
337 ++sdev->stat.uncorrectable_errors; 495 ++sdev->stat.uncorrectable_errors;
338 spin_unlock(&sdev->stat_lock); 496 spin_unlock(&sdev->stat_lock);
339 497
340 if (printk_ratelimit()) 498 printk_ratelimited(KERN_ERR "btrfs: unable to fixup (regular) error at "
341 printk(KERN_ERR "btrfs: unable to fixup at %llu\n", 499 "logical %llu\n", (unsigned long long)logical);
342 (unsigned long long)logical);
343} 500}
344 501
345static int scrub_fixup_io(int rw, struct block_device *bdev, sector_t sector, 502static int scrub_fixup_io(int rw, struct block_device *bdev, sector_t sector,