Commit a1d3c478 authored by Jan Schmidt's avatar Jan Schmidt

btrfs: btrfs_multi_bio replaced with btrfs_bio

btrfs_bio is a bio abstraction able to split and not complete after the last
bio has returned (like the old btrfs_multi_bio). Additionally, btrfs_bio
tracks the mirror_num used to read data which can be used for error
correction purposes.
Signed-off-by: default avatarJan Schmidt <list.btrfs@jan-o-sch.net>
parent d7728c96
...@@ -1770,18 +1770,18 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, ...@@ -1770,18 +1770,18 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
{ {
int ret; int ret;
u64 discarded_bytes = 0; u64 discarded_bytes = 0;
struct btrfs_multi_bio *multi = NULL; struct btrfs_bio *bbio = NULL;
/* Tell the block device(s) that the sectors can be discarded */ /* Tell the block device(s) that the sectors can be discarded */
ret = btrfs_map_block(&root->fs_info->mapping_tree, REQ_DISCARD, ret = btrfs_map_block(&root->fs_info->mapping_tree, REQ_DISCARD,
bytenr, &num_bytes, &multi, 0); bytenr, &num_bytes, &bbio, 0);
if (!ret) { if (!ret) {
struct btrfs_bio_stripe *stripe = multi->stripes; struct btrfs_bio_stripe *stripe = bbio->stripes;
int i; int i;
for (i = 0; i < multi->num_stripes; i++, stripe++) { for (i = 0; i < bbio->num_stripes; i++, stripe++) {
if (!stripe->dev->can_discard) if (!stripe->dev->can_discard)
continue; continue;
...@@ -1800,7 +1800,7 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, ...@@ -1800,7 +1800,7 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
*/ */
ret = 0; ret = 0;
} }
kfree(multi); kfree(bbio);
} }
if (actual_bytes) if (actual_bytes)
......
...@@ -572,7 +572,7 @@ static void scrub_fixup(struct scrub_bio *sbio, int ix) ...@@ -572,7 +572,7 @@ static void scrub_fixup(struct scrub_bio *sbio, int ix)
struct scrub_dev *sdev = sbio->sdev; struct scrub_dev *sdev = sbio->sdev;
struct btrfs_fs_info *fs_info = sdev->dev->dev_root->fs_info; struct btrfs_fs_info *fs_info = sdev->dev->dev_root->fs_info;
struct btrfs_mapping_tree *map_tree = &fs_info->mapping_tree; struct btrfs_mapping_tree *map_tree = &fs_info->mapping_tree;
struct btrfs_multi_bio *multi = NULL; struct btrfs_bio *bbio = NULL;
struct scrub_fixup_nodatasum *fixup; struct scrub_fixup_nodatasum *fixup;
u64 logical = sbio->logical + ix * PAGE_SIZE; u64 logical = sbio->logical + ix * PAGE_SIZE;
u64 length; u64 length;
...@@ -610,8 +610,8 @@ static void scrub_fixup(struct scrub_bio *sbio, int ix) ...@@ -610,8 +610,8 @@ static void scrub_fixup(struct scrub_bio *sbio, int ix)
length = PAGE_SIZE; length = PAGE_SIZE;
ret = btrfs_map_block(map_tree, REQ_WRITE, logical, &length, ret = btrfs_map_block(map_tree, REQ_WRITE, logical, &length,
&multi, 0); &bbio, 0);
if (ret || !multi || length < PAGE_SIZE) { if (ret || !bbio || length < PAGE_SIZE) {
printk(KERN_ERR printk(KERN_ERR
"scrub_fixup: btrfs_map_block failed us for %llu\n", "scrub_fixup: btrfs_map_block failed us for %llu\n",
(unsigned long long)logical); (unsigned long long)logical);
...@@ -619,19 +619,19 @@ static void scrub_fixup(struct scrub_bio *sbio, int ix) ...@@ -619,19 +619,19 @@ static void scrub_fixup(struct scrub_bio *sbio, int ix)
return; return;
} }
if (multi->num_stripes == 1) if (bbio->num_stripes == 1)
/* there aren't any replicas */ /* there aren't any replicas */
goto uncorrectable; goto uncorrectable;
/* /*
* first find a good copy * first find a good copy
*/ */
for (i = 0; i < multi->num_stripes; ++i) { for (i = 0; i < bbio->num_stripes; ++i) {
if (i + 1 == sbio->spag[ix].mirror_num) if (i + 1 == sbio->spag[ix].mirror_num)
continue; continue;
if (scrub_fixup_io(READ, multi->stripes[i].dev->bdev, if (scrub_fixup_io(READ, bbio->stripes[i].dev->bdev,
multi->stripes[i].physical >> 9, bbio->stripes[i].physical >> 9,
sbio->bio->bi_io_vec[ix].bv_page)) { sbio->bio->bi_io_vec[ix].bv_page)) {
/* I/O-error, this is not a good copy */ /* I/O-error, this is not a good copy */
continue; continue;
...@@ -640,7 +640,7 @@ static void scrub_fixup(struct scrub_bio *sbio, int ix) ...@@ -640,7 +640,7 @@ static void scrub_fixup(struct scrub_bio *sbio, int ix)
if (scrub_fixup_check(sbio, ix) == 0) if (scrub_fixup_check(sbio, ix) == 0)
break; break;
} }
if (i == multi->num_stripes) if (i == bbio->num_stripes)
goto uncorrectable; goto uncorrectable;
if (!sdev->readonly) { if (!sdev->readonly) {
...@@ -655,7 +655,7 @@ static void scrub_fixup(struct scrub_bio *sbio, int ix) ...@@ -655,7 +655,7 @@ static void scrub_fixup(struct scrub_bio *sbio, int ix)
} }
} }
kfree(multi); kfree(bbio);
spin_lock(&sdev->stat_lock); spin_lock(&sdev->stat_lock);
++sdev->stat.corrected_errors; ++sdev->stat.corrected_errors;
spin_unlock(&sdev->stat_lock); spin_unlock(&sdev->stat_lock);
...@@ -665,7 +665,7 @@ static void scrub_fixup(struct scrub_bio *sbio, int ix) ...@@ -665,7 +665,7 @@ static void scrub_fixup(struct scrub_bio *sbio, int ix)
return; return;
uncorrectable: uncorrectable:
kfree(multi); kfree(bbio);
spin_lock(&sdev->stat_lock); spin_lock(&sdev->stat_lock);
++sdev->stat.uncorrectable_errors; ++sdev->stat.uncorrectable_errors;
spin_unlock(&sdev->stat_lock); spin_unlock(&sdev->stat_lock);
......
This diff is collapsed.
...@@ -136,7 +136,10 @@ struct btrfs_bio_stripe { ...@@ -136,7 +136,10 @@ struct btrfs_bio_stripe {
u64 length; /* only used for discard mappings */ u64 length; /* only used for discard mappings */
}; };
struct btrfs_multi_bio { struct btrfs_bio;
typedef void (btrfs_bio_end_io_t) (struct btrfs_bio *bio, int err);
struct btrfs_bio {
atomic_t stripes_pending; atomic_t stripes_pending;
bio_end_io_t *end_io; bio_end_io_t *end_io;
struct bio *orig_bio; struct bio *orig_bio;
...@@ -144,6 +147,7 @@ struct btrfs_multi_bio { ...@@ -144,6 +147,7 @@ struct btrfs_multi_bio {
atomic_t error; atomic_t error;
int max_errors; int max_errors;
int num_stripes; int num_stripes;
int mirror_num;
struct btrfs_bio_stripe stripes[]; struct btrfs_bio_stripe stripes[];
}; };
...@@ -171,7 +175,7 @@ struct map_lookup { ...@@ -171,7 +175,7 @@ struct map_lookup {
int btrfs_account_dev_extents_size(struct btrfs_device *device, u64 start, int btrfs_account_dev_extents_size(struct btrfs_device *device, u64 start,
u64 end, u64 *length); u64 end, u64 *length);
#define btrfs_multi_bio_size(n) (sizeof(struct btrfs_multi_bio) + \ #define btrfs_bio_size(n) (sizeof(struct btrfs_bio) + \
(sizeof(struct btrfs_bio_stripe) * (n))) (sizeof(struct btrfs_bio_stripe) * (n)))
int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans, int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans,
...@@ -180,7 +184,7 @@ int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans, ...@@ -180,7 +184,7 @@ int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans,
u64 chunk_offset, u64 start, u64 num_bytes); u64 chunk_offset, u64 start, u64 num_bytes);
int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
u64 logical, u64 *length, u64 logical, u64 *length,
struct btrfs_multi_bio **multi_ret, int mirror_num); struct btrfs_bio **bbio_ret, int mirror_num);
int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree,
u64 chunk_start, u64 physical, u64 devid, u64 chunk_start, u64 physical, u64 devid,
u64 **logical, int *naddrs, int *stripe_len); u64 **logical, int *naddrs, int *stripe_len);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment