From: Qu Wenruo <quwenruo@cn.fujitsu.com>
To: <linux-btrfs@vger.kernel.org>
Subject: [PATCH 2/2] btrfs-progs: Cleanup logic of btrfs_read_tree_block().
Date: Mon, 11 May 2015 08:45:48 +0800 [thread overview]
Message-ID: <1431305148-18953-2-git-send-email-quwenruo@cn.fujitsu.com> (raw)
In-Reply-To: <1431305148-18953-1-git-send-email-quwenruo@cn.fujitsu.com>
Make the logic of btrfs_read_tree_block() more clean.
Now it will do as the following flow:
1) Iterate all copies of the tree block
If one can pass all tests(csum, check tree block, transid), then
return it.
2) If all above failed, use the copy with highest transid
If that copy can pass checksum and tree block check, then ignore its
transid error
3) If none passed above, print out error.
This provides the basis for later all tree block copies check.
Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
---
disk-io.c | 73 +++++++++++++++++++++++++++++++++------------------------------
1 file changed, 38 insertions(+), 35 deletions(-)
diff --git a/disk-io.c b/disk-io.c
index c1cf146..c8302a8 100644
--- a/disk-io.c
+++ b/disk-io.c
@@ -280,9 +280,8 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
struct extent_buffer *eb;
u64 best_transid = 0;
int mirror_num = 0;
- int good_mirror = 0;
+ int best_mirror = -1;
int num_copies;
- int ignore = 0;
eb = btrfs_find_create_tree_block(root, bytenr, blocksize);
if (!eb)
@@ -291,50 +290,54 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
if (btrfs_buffer_uptodate(eb, parent_transid))
return eb;
- while (1) {
+ num_copies = btrfs_num_copies(&root->fs_info->mapping_tree, eb->start,
+ eb->len);
+
+ /* Iterate all copies with restrict check */
+ for (mirror_num = 0; mirror_num < num_copies; mirror_num++) {
ret = read_whole_eb(root->fs_info, eb, mirror_num);
if (ret == 0 && csum_tree_block(root, eb, 1) == 0 &&
check_tree_block(root, eb) == 0 &&
- verify_parent_transid(eb->tree, eb, parent_transid, ignore)
+ verify_parent_transid(eb->tree, eb, parent_transid, 0)
== 0) {
- if (eb->flags & EXTENT_BAD_TRANSID &&
- list_empty(&eb->recow)) {
- list_add_tail(&eb->recow,
- &root->fs_info->recow_ebs);
- eb->refs++;
- }
btrfs_set_buffer_uptodate(eb);
return eb;
}
- if (ignore) {
- if (check_tree_block(root, eb)) {
- if (!root->fs_info->suppress_check_block_errors)
- print_tree_block_error(root, eb,
- check_tree_block(root, eb));
- } else {
- if (!root->fs_info->suppress_check_block_errors)
- fprintf(stderr, "Csum didn't match\n");
- }
- ret = -EIO;
- break;
- }
- num_copies = btrfs_num_copies(&root->fs_info->mapping_tree,
- eb->start, eb->len);
- if (num_copies == 1) {
- ignore = 1;
- continue;
- }
- if (btrfs_header_generation(eb) > best_transid && mirror_num) {
+ if (btrfs_header_generation(eb) > best_transid) {
best_transid = btrfs_header_generation(eb);
- good_mirror = mirror_num;
+ best_mirror = mirror_num;
}
- mirror_num++;
- if (mirror_num > num_copies) {
- mirror_num = good_mirror;
- ignore = 1;
- continue;
+ }
+ /* No valid eb found, use one with best transid or the last mirror */
+ if (best_mirror != -1)
+ mirror_num = best_mirror;
+ ret = read_whole_eb(root->fs_info, eb, mirror_num);
+ if (ret < 0)
+ goto out;
+
+ /* ignore transid error */
+ if (csum_tree_block(root, eb, 1) == 0 &&
+ check_tree_block(root, eb) ==0 &&
+ verify_parent_transid(eb->tree, eb, parent_transid, 1) == 0) {
+ if (eb->flags & EXTENT_BAD_TRANSID && list_empty(&eb->recow)) {
+ list_add_tail(&eb->recow, &root->fs_info->recow_ebs);
+ eb->refs++;
}
+ btrfs_set_buffer_uptodate(eb);
+ return eb;
+ }
+
+ /* print other errors */
+ if (check_tree_block(root, eb)) {
+ if (!root->fs_info->suppress_check_block_errors)
+ print_tree_block_error(root, eb,
+ check_tree_block(root, eb));
+ } else {
+ if (!root->fs_info->suppress_check_block_errors)
+ fprintf(stderr, "Csum didn't match\n");
}
+ ret = -EIO;
+out:
free_extent_buffer(eb);
return ERR_PTR(ret);
}
--
2.4.0
next prev parent reply other threads:[~2015-05-11 0:47 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-11 0:45 [PATCH 1/2] btrfs-progs: Fix a bug in __btrfs_map_block() always maps wrong stripe for DUP/RAID1 Qu Wenruo
2015-05-11 0:45 ` Qu Wenruo [this message]
2015-05-21 16:06 ` David Sterba
2015-05-22 2:53 ` Qu Wenruo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1431305148-18953-2-git-send-email-quwenruo@cn.fujitsu.com \
--to=quwenruo@cn.fujitsu.com \
--cc=linux-btrfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).