diff options
author | Qu Wenruo <quwenruo@cn.fujitsu.com> | 2014-06-18 22:42:51 -0400 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2014-06-19 17:20:54 -0400 |
commit | ced96edc48ba455b0982c3aa64d3cc3bf2d0816a (patch) | |
tree | 44967160e52bb4b5cd82d1ad6308702ce77e24af /fs | |
parent | e570fd27f2c5d7eac3876bccf99e9838d7f911a3 (diff) |
btrfs: Skip scrubbing removed chunks to avoid -ENOENT.
When run scrub with balance, sometimes -ENOENT will be returned, since
in scrub_enumerate_chunks() will search dev_extent in *COMMIT_ROOT*, but
btrfs_lookup_block_group() will search block group in *MEMORY*, so if a
chunk is removed but not committed, -ENOENT will be returned.
However, there is no need to stop scrubbing since other chunks may be
scrubbed without problem.
So this patch changes the behavior to skip removed chunks and continue
to scrub the rest.
Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
Signed-off-by: Miao Xie <miaox@cn.fujitsu.com>
Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/scrub.c | 19 |
1 files changed, 9 insertions, 10 deletions
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index ac80188eec88..b6d198f5181e 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
@@ -2725,11 +2725,8 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, | |||
2725 | dev_extent = btrfs_item_ptr(l, slot, struct btrfs_dev_extent); | 2725 | dev_extent = btrfs_item_ptr(l, slot, struct btrfs_dev_extent); |
2726 | length = btrfs_dev_extent_length(l, dev_extent); | 2726 | length = btrfs_dev_extent_length(l, dev_extent); |
2727 | 2727 | ||
2728 | if (found_key.offset + length <= start) { | 2728 | if (found_key.offset + length <= start) |
2729 | key.offset = found_key.offset + length; | 2729 | goto skip; |
2730 | btrfs_release_path(path); | ||
2731 | continue; | ||
2732 | } | ||
2733 | 2730 | ||
2734 | chunk_tree = btrfs_dev_extent_chunk_tree(l, dev_extent); | 2731 | chunk_tree = btrfs_dev_extent_chunk_tree(l, dev_extent); |
2735 | chunk_objectid = btrfs_dev_extent_chunk_objectid(l, dev_extent); | 2732 | chunk_objectid = btrfs_dev_extent_chunk_objectid(l, dev_extent); |
@@ -2740,10 +2737,12 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, | |||
2740 | * the chunk from going away while we scrub it | 2737 | * the chunk from going away while we scrub it |
2741 | */ | 2738 | */ |
2742 | cache = btrfs_lookup_block_group(fs_info, chunk_offset); | 2739 | cache = btrfs_lookup_block_group(fs_info, chunk_offset); |
2743 | if (!cache) { | 2740 | |
2744 | ret = -ENOENT; | 2741 | /* some chunks are removed but not committed to disk yet, |
2745 | break; | 2742 | * continue scrubbing */ |
2746 | } | 2743 | if (!cache) |
2744 | goto skip; | ||
2745 | |||
2747 | dev_replace->cursor_right = found_key.offset + length; | 2746 | dev_replace->cursor_right = found_key.offset + length; |
2748 | dev_replace->cursor_left = found_key.offset; | 2747 | dev_replace->cursor_left = found_key.offset; |
2749 | dev_replace->item_needs_writeback = 1; | 2748 | dev_replace->item_needs_writeback = 1; |
@@ -2802,7 +2801,7 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx, | |||
2802 | 2801 | ||
2803 | dev_replace->cursor_left = dev_replace->cursor_right; | 2802 | dev_replace->cursor_left = dev_replace->cursor_right; |
2804 | dev_replace->item_needs_writeback = 1; | 2803 | dev_replace->item_needs_writeback = 1; |
2805 | 2804 | skip: | |
2806 | key.offset = found_key.offset + length; | 2805 | key.offset = found_key.offset + length; |
2807 | btrfs_release_path(path); | 2806 | btrfs_release_path(path); |
2808 | } | 2807 | } |