diff options
author | Stefan Behrens <sbehrens@giantdisaster.de> | 2012-11-05 12:51:52 -0500 |
---|---|---|
committer | Josef Bacik <jbacik@fusionio.com> | 2012-12-12 17:15:40 -0500 |
commit | 618919236ba54361e93106f4951d233a7ade63cd (patch) | |
tree | 4ab4c62432550e7ed32aa19a07609fbca0b9de52 /fs/btrfs/extent_io.c | |
parent | 63a212abc2315972b245f93cb11ae3acf3c0b513 (diff) |
Btrfs: handle errors from btrfs_map_bio() everywhere
With the addition of the device replace procedure, it is possible
for btrfs_map_bio(READ) to report an error. This happens when the
specific mirror is requested which is located on the target disk,
and the copy operation has not yet copied this block. Hence the
block cannot be read and this error state is indicated by
returning EIO.
Some background information follows now. A new mirror is added
while the device replace procedure is running.
btrfs_get_num_copies() returns one more, and
btrfs_map_bio(GET_READ_MIRROR) adds one more mirror if a disk
location is involved that was already handled by the device
replace copy operation. The assigned mirror num is the highest
mirror number, e.g. the value 3 in case of RAID1.
If btrfs_map_bio() is invoked with mirror_num == 0 (i.e., select
any mirror), the copy on the target drive is never selected
because that disk shall be able to perform the write requests as
quickly as possible. The parallel execution of read requests would
only slow down the disk copy procedure. Second case is that
btrfs_map_bio() is called with mirror_num > 0. This is done from
the repair code only. In this case, the highest mirror num is
assigned to the target disk, since it is used last. And when this
mirror is not available because the copy procedure has not yet
handled this area, an error is returned. Everywhere in the code
the handling of such errors is added now.
Signed-off-by: Stefan Behrens <sbehrens@giantdisaster.de>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs/extent_io.c')
-rw-r--r-- | fs/btrfs/extent_io.c | 4 |
1 files changed, 0 insertions, 4 deletions
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 62ec6e45f705..1b319df29eee 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -2462,10 +2462,6 @@ btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs, | |||
2462 | return bio; | 2462 | return bio; |
2463 | } | 2463 | } |
2464 | 2464 | ||
2465 | /* | ||
2466 | * Since writes are async, they will only return -ENOMEM. | ||
2467 | * Reads can return the full range of I/O error conditions. | ||
2468 | */ | ||
2469 | static int __must_check submit_one_bio(int rw, struct bio *bio, | 2465 | static int __must_check submit_one_bio(int rw, struct bio *bio, |
2470 | int mirror_num, unsigned long bio_flags) | 2466 | int mirror_num, unsigned long bio_flags) |
2471 | { | 2467 | { |