aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
authorStefan Behrens <sbehrens@giantdisaster.de>2012-11-05 12:51:52 -0500
committerJosef Bacik <jbacik@fusionio.com>2012-12-12 17:15:40 -0500
commit618919236ba54361e93106f4951d233a7ade63cd (patch)
tree4ab4c62432550e7ed32aa19a07609fbca0b9de52 /fs/btrfs/volumes.c
parent63a212abc2315972b245f93cb11ae3acf3c0b513 (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/volumes.c')
-rw-r--r--fs/btrfs/volumes.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 31f7af878d96..415862885b67 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -4435,7 +4435,7 @@ int btrfs_map_bio(struct btrfs_root *root, int rw, struct bio *bio,
4435 4435
4436 ret = btrfs_map_block(root->fs_info, rw, logical, &map_length, &bbio, 4436 ret = btrfs_map_block(root->fs_info, rw, logical, &map_length, &bbio,
4437 mirror_num); 4437 mirror_num);
4438 if (ret) /* -ENOMEM */ 4438 if (ret)
4439 return ret; 4439 return ret;
4440 4440
4441 total_devs = bbio->num_stripes; 4441 total_devs = bbio->num_stripes;