summaryrefslogtreecommitdiff
path: root/volumes.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-04-09 16:28:12 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2008-04-09 16:28:12 -0400
commitfd2d0af0bf80c127fbb3b84817a420fbc490da5d (patch)
treeeb9145973922aed41e23bba86d6fb01cc0fbb8ec /volumes.c
parent1b74adf90b95af77a2826dc82cf5c5f38af90e52 (diff)
Retry metadata reads in the face of checksum failures
Diffstat (limited to 'volumes.c')
-rw-r--r--volumes.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/volumes.c b/volumes.c
index ef2f59ca..44e67291 100644
--- a/volumes.c
+++ b/volumes.c
@@ -732,9 +732,29 @@ void btrfs_mapping_init(struct btrfs_mapping_tree *tree)
cache_tree_init(&tree->cache_tree);
}
+int btrfs_num_copies(struct btrfs_mapping_tree *map_tree, u64 logical, u64 len)
+{
+ struct cache_extent *ce;
+ struct map_lookup *map;
+ int ret;
+ u64 offset;
+
+ ce = find_first_cache_extent(&map_tree->cache_tree, logical);
+ BUG_ON(!ce);
+ BUG_ON(ce->start > logical || ce->start + ce->size < logical);
+ map = container_of(ce, struct map_lookup, ce);
+
+ offset = logical - ce->start;
+ if (map->type & (BTRFS_BLOCK_GROUP_DUP | BTRFS_BLOCK_GROUP_RAID1))
+ ret = map->num_stripes;
+ else
+ ret = 1;
+ return ret;
+}
+
int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
u64 logical, u64 *length,
- struct btrfs_multi_bio **multi_ret)
+ struct btrfs_multi_bio **multi_ret, int mirror_num)
{
struct cache_extent *ce;
struct map_lookup *map;
@@ -802,11 +822,15 @@ again:
if (map->type & BTRFS_BLOCK_GROUP_RAID1) {
if (rw == WRITE)
multi->num_stripes = map->num_stripes;
+ else if (mirror_num)
+ stripe_index = mirror_num - 1;
else
stripe_index = stripe_nr % map->num_stripes;
} else if (map->type & BTRFS_BLOCK_GROUP_DUP) {
if (rw == WRITE)
multi->num_stripes = map->num_stripes;
+ else if (mirror_num)
+ stripe_index = mirror_num - 1;
} else {
/*
* after this do_div call, stripe_nr is the number of stripes