aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/md/md.c4
-rw-r--r--drivers/md/md.h9
-rw-r--r--drivers/md/raid1.c7
-rw-r--r--drivers/md/raid1.h6
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