diff options
-rw-r--r-- | drivers/md/md.c | 4 | ||||
-rw-r--r-- | drivers/md/md.h | 9 | ||||
-rw-r--r-- | drivers/md/raid1.c | 7 | ||||
-rw-r--r-- | drivers/md/raid1.h | 6 |
4 files changed, 19 insertions, 7 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 77bd8d8708e4..c7d9c6af4634 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1922,7 +1922,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) | |||
1922 | bd_link_disk_holder(rdev->bdev, mddev->gendisk); | 1922 | bd_link_disk_holder(rdev->bdev, mddev->gendisk); |
1923 | 1923 | ||
1924 | /* May as well allow recovery to be retried once */ | 1924 | /* May as well allow recovery to be retried once */ |
1925 | mddev->recovery_disabled = 0; | 1925 | mddev->recovery_disabled++; |
1926 | 1926 | ||
1927 | return 0; | 1927 | return 0; |
1928 | 1928 | ||
@@ -7070,7 +7070,7 @@ static int remove_and_add_spares(mddev_t *mddev) | |||
7070 | } | 7070 | } |
7071 | } | 7071 | } |
7072 | 7072 | ||
7073 | if (mddev->degraded && !mddev->recovery_disabled) { | 7073 | if (mddev->degraded) { |
7074 | list_for_each_entry(rdev, &mddev->disks, same_set) { | 7074 | list_for_each_entry(rdev, &mddev->disks, same_set) { |
7075 | if (rdev->raid_disk >= 0 && | 7075 | if (rdev->raid_disk >= 0 && |
7076 | !test_bit(In_sync, &rdev->flags) && | 7076 | !test_bit(In_sync, &rdev->flags) && |
diff --git a/drivers/md/md.h b/drivers/md/md.h index 6863f722cd2a..de5455d30d41 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h | |||
@@ -239,9 +239,12 @@ struct mddev_s | |||
239 | #define MD_RECOVERY_FROZEN 9 | 239 | #define MD_RECOVERY_FROZEN 9 |
240 | 240 | ||
241 | unsigned long recovery; | 241 | unsigned long recovery; |
242 | int recovery_disabled; /* if we detect that recovery | 242 | /* If a RAID personality determines that recovery (of a particular |
243 | * will always fail, set this | 243 | * device) will fail due to a read error on the source device, it |
244 | * so we don't loop trying */ | 244 | * takes a copy of this number and does not attempt recovery again |
245 | * until this number changes. | ||
246 | */ | ||
247 | int recovery_disabled; | ||
245 | 248 | ||
246 | int in_sync; /* know to not need resync */ | 249 | int in_sync; /* know to not need resync */ |
247 | /* 'open_mutex' avoids races between 'md_open' and 'do_md_stop', so | 250 | /* 'open_mutex' avoids races between 'md_open' and 'do_md_stop', so |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 1d79a041db09..44069b38d6dd 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -956,7 +956,7 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
956 | * However don't try a recovery from this drive as | 956 | * However don't try a recovery from this drive as |
957 | * it is very likely to fail. | 957 | * it is very likely to fail. |
958 | */ | 958 | */ |
959 | mddev->recovery_disabled = 1; | 959 | conf->recovery_disabled = mddev->recovery_disabled; |
960 | return; | 960 | return; |
961 | } | 961 | } |
962 | if (test_and_clear_bit(In_sync, &rdev->flags)) { | 962 | if (test_and_clear_bit(In_sync, &rdev->flags)) { |
@@ -1052,6 +1052,9 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1052 | int first = 0; | 1052 | int first = 0; |
1053 | int last = mddev->raid_disks - 1; | 1053 | int last = mddev->raid_disks - 1; |
1054 | 1054 | ||
1055 | if (mddev->recovery_disabled == conf->recovery_disabled) | ||
1056 | return -EBUSY; | ||
1057 | |||
1055 | if (rdev->raid_disk >= 0) | 1058 | if (rdev->raid_disk >= 0) |
1056 | first = last = rdev->raid_disk; | 1059 | first = last = rdev->raid_disk; |
1057 | 1060 | ||
@@ -1107,7 +1110,7 @@ static int raid1_remove_disk(mddev_t *mddev, int number) | |||
1107 | * is not possible. | 1110 | * is not possible. |
1108 | */ | 1111 | */ |
1109 | if (!test_bit(Faulty, &rdev->flags) && | 1112 | if (!test_bit(Faulty, &rdev->flags) && |
1110 | !mddev->recovery_disabled && | 1113 | mddev->recovery_disabled != conf->recovery_disabled && |
1111 | mddev->degraded < conf->raid_disks) { | 1114 | mddev->degraded < conf->raid_disks) { |
1112 | err = -EBUSY; | 1115 | err = -EBUSY; |
1113 | goto abort; | 1116 | goto abort; |
diff --git a/drivers/md/raid1.h b/drivers/md/raid1.h index e743a64fac4f..3cd18cfda2ad 100644 --- a/drivers/md/raid1.h +++ b/drivers/md/raid1.h | |||
@@ -48,6 +48,12 @@ struct r1_private_data_s { | |||
48 | * (fresh device added). | 48 | * (fresh device added). |
49 | * Cleared when a sync completes. | 49 | * Cleared when a sync completes. |
50 | */ | 50 | */ |
51 | int recovery_disabled; /* when the same as | ||
52 | * mddev->recovery_disabled | ||
53 | * we don't allow recovery | ||
54 | * to be attempted as we | ||
55 | * expect a read error | ||
56 | */ | ||
51 | 57 | ||
52 | wait_queue_head_t wait_barrier; | 58 | wait_queue_head_t wait_barrier; |
53 | 59 | ||