diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-04-09 16:28:12 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2008-04-09 16:28:12 -0400 |
commit | fd2d0af0bf80c127fbb3b84817a420fbc490da5d (patch) | |
tree | eb9145973922aed41e23bba86d6fb01cc0fbb8ec /volumes.c | |
parent | 1b74adf90b95af77a2826dc82cf5c5f38af90e52 (diff) |
Retry metadata reads in the face of checksum failures
Diffstat (limited to 'volumes.c')
-rw-r--r-- | volumes.c | 26 |
1 files changed, 25 insertions, 1 deletions
@@ -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 |