If a device is not in_sync, avoid reading data from it as data on it
might be stale.
Although checksum can detect stale data so we won't return stale data
to users , this helps us read the good copy directly.
Signed-off-by: Liu Bo <bo.li.liu@xxxxxxxxxx>
---
fs/btrfs/volumes.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 7b29b1a..b83b7c8 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -5175,6 +5175,7 @@ static int find_live_mirror(struct btrfs_fs_info *fs_info,
int i;
int tolerance;
struct btrfs_device *srcdev;
+ struct btrfs_device *curr;
if (dev_replace_is_ongoing &&
fs_info->dev_replace.cont_reading_from_srcdev_mode ==
@@ -5184,17 +5185,25 @@ static int find_live_mirror(struct btrfs_fs_info *fs_info,
srcdev = NULL;
/*
- * try to avoid the drive that is the source drive for a
- * dev-replace procedure, only choose it if no other non-missing
- * mirror is available
+ * try to avoid the drive that is
+ *
+ * a) the source drive for a dev-replace procedure,
+ * b) not in_sync
+ *
+ * only choose it if no other non-missing mirror is available.
*/
for (tolerance = 0; tolerance < 2; tolerance++) {
- if (map->stripes[optimal].dev->bdev &&
- (tolerance || map->stripes[optimal].dev != srcdev))
+ curr = map->stripes[optimal].dev;
+ if (curr->bdev &&
+ test_bit(In_sync, &curr->flags) &&
+ (tolerance || curr != srcdev))
return optimal;
+
for (i = first; i < first + num; i++) {
- if (map->stripes[i].dev->bdev &&
- (tolerance || map->stripes[i].dev != srcdev))
+ curr = map->stripes[i].dev;
+ if (curr->bdev &&
+ test_bit(In_sync, &curr->flags) &&
+ (tolerance || curr != srcdev))
return i;
}
}
--
2.9.4
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html