int stripe_index;
int i;
int num_stripes;
+ int max_errors = 0;
struct btrfs_multi_bio *multi = NULL;
if (multi_ret && !(rw & (1 << BIO_RW))) {
GFP_NOFS);
if (!multi)
return -ENOMEM;
+
+ atomic_set(&multi->error, 0);
}
spin_lock(&em_tree->lock);
if (map->type & (BTRFS_BLOCK_GROUP_RAID1 |
BTRFS_BLOCK_GROUP_DUP)) {
stripes_required = map->num_stripes;
+ max_errors = 1;
} else if (map->type & BTRFS_BLOCK_GROUP_RAID10) {
stripes_required = map->sub_stripes;
+ max_errors = 1;
}
}
if (multi_ret && rw == WRITE &&
if (map->type & BTRFS_BLOCK_GROUP_RAID1) {
if (unplug_page || (rw & (1 << BIO_RW)))
num_stripes = map->num_stripes;
- else if (mirror_num) {
+ else if (mirror_num)
stripe_index = mirror_num - 1;
- } else {
- u64 orig_stripe_nr = stripe_nr;
- stripe_index = do_div(orig_stripe_nr, num_stripes);
- }
+ else
+ stripe_index = current->pid % map->num_stripes;
+
} else if (map->type & BTRFS_BLOCK_GROUP_DUP) {
if (rw & (1 << BIO_RW))
num_stripes = map->num_stripes;
else if (mirror_num)
stripe_index = mirror_num - 1;
+
} else if (map->type & BTRFS_BLOCK_GROUP_RAID10) {
int factor = map->num_stripes / map->sub_stripes;
num_stripes = map->sub_stripes;
else if (mirror_num)
stripe_index += mirror_num - 1;
- else {
- u64 orig_stripe_nr = stripe_nr;
- stripe_index += do_div(orig_stripe_nr,
- map->sub_stripes);
- }
+ else
+ stripe_index += current->pid % map->sub_stripes;
} else {
/*
* after this do_div call, stripe_nr is the number of stripes
if (multi_ret) {
*multi_ret = multi;
multi->num_stripes = num_stripes;
+ multi->max_errors = max_errors;
}
out:
free_extent_map(em);
return 1;
#endif
if (err)
- multi->error = err;
+ atomic_inc(&multi->error);
if (atomic_dec_and_test(&multi->stripes_pending)) {
bio->bi_private = multi->private;
bio->bi_end_io = multi->end_io;
- if (!err && multi->error)
- err = multi->error;
+ /* only send an error to the higher layers if it is
+ * beyond the tolerance of the multi-bio
+ */
+ if (atomic_read(&multi->error) > multi->max_errors)
+ err = -EIO;
+ else
+ err = 0;
kfree(multi);
#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,23)