aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid10.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2011-07-27 21:39:24 -0400
committerNeilBrown <neilb@suse.de>2011-07-27 21:39:24 -0400
commit40c356ce5ad1a6be817825e1da1bc7494349cc6d (patch)
tree6843d537ecdfda6c03860455c187b775bc6dec97 /drivers/md/raid10.c
parent8dbed5cebdf6796bf2618457b3653cf820934366 (diff)
md/raid10: avoid reading known bad blocks during resync/recovery.
During resync/recovery limit the size of the request to avoid reading into a bad block that does not start at-or-before the current read address. Similarly if there is a bad block at this address, don't allow the current request to extend beyond the end of that bad block. Now that we don't ever read from known bad blocks, it is safe to allow devices with those blocks into the array. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/raid10.c')
-rw-r--r--drivers/md/raid10.c44
1 files changed, 35 insertions, 9 deletions
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index a5ecea2672b5..5f0355832b46 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1203,9 +1203,6 @@ static int raid10_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
1203 int first = 0; 1203 int first = 0;
1204 int last = conf->raid_disks - 1; 1204 int last = conf->raid_disks - 1;
1205 1205
1206 if (rdev->badblocks.count)
1207 return -EINVAL;
1208
1209 if (mddev->recovery_cp < MaxSector) 1206 if (mddev->recovery_cp < MaxSector)
1210 /* only hot-add to in-sync arrays, as recovery is 1207 /* only hot-add to in-sync arrays, as recovery is
1211 * very different from resync 1208 * very different from resync
@@ -1927,7 +1924,6 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr,
1927 int i; 1924 int i;
1928 int max_sync; 1925 int max_sync;
1929 sector_t sync_blocks; 1926 sector_t sync_blocks;
1930
1931 sector_t sectors_skipped = 0; 1927 sector_t sectors_skipped = 0;
1932 int chunks_skipped = 0; 1928 int chunks_skipped = 0;
1933 1929
@@ -2070,10 +2066,28 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr,
2070 2066
2071 for (j=0; j<conf->copies;j++) { 2067 for (j=0; j<conf->copies;j++) {
2072 int d = r10_bio->devs[j].devnum; 2068 int d = r10_bio->devs[j].devnum;
2069 mdk_rdev_t *rdev;
2070 sector_t sector, first_bad;
2071 int bad_sectors;
2073 if (!conf->mirrors[d].rdev || 2072 if (!conf->mirrors[d].rdev ||
2074 !test_bit(In_sync, &conf->mirrors[d].rdev->flags)) 2073 !test_bit(In_sync, &conf->mirrors[d].rdev->flags))
2075 continue; 2074 continue;
2076 /* This is where we read from */ 2075 /* This is where we read from */
2076 rdev = conf->mirrors[d].rdev;
2077 sector = r10_bio->devs[j].addr;
2078
2079 if (is_badblock(rdev, sector, max_sync,
2080 &first_bad, &bad_sectors)) {
2081 if (first_bad > sector)
2082 max_sync = first_bad - sector;
2083 else {
2084 bad_sectors -= (sector
2085 - first_bad);
2086 if (max_sync > bad_sectors)
2087 max_sync = bad_sectors;
2088 continue;
2089 }
2090 }
2077 bio = r10_bio->devs[0].bio; 2091 bio = r10_bio->devs[0].bio;
2078 bio->bi_next = biolist; 2092 bio->bi_next = biolist;
2079 biolist = bio; 2093 biolist = bio;
@@ -2160,12 +2174,28 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr,
2160 2174
2161 for (i=0; i<conf->copies; i++) { 2175 for (i=0; i<conf->copies; i++) {
2162 int d = r10_bio->devs[i].devnum; 2176 int d = r10_bio->devs[i].devnum;
2177 sector_t first_bad, sector;
2178 int bad_sectors;
2179
2163 bio = r10_bio->devs[i].bio; 2180 bio = r10_bio->devs[i].bio;
2164 bio->bi_end_io = NULL; 2181 bio->bi_end_io = NULL;
2165 clear_bit(BIO_UPTODATE, &bio->bi_flags); 2182 clear_bit(BIO_UPTODATE, &bio->bi_flags);
2166 if (conf->mirrors[d].rdev == NULL || 2183 if (conf->mirrors[d].rdev == NULL ||
2167 test_bit(Faulty, &conf->mirrors[d].rdev->flags)) 2184 test_bit(Faulty, &conf->mirrors[d].rdev->flags))
2168 continue; 2185 continue;
2186 sector = r10_bio->devs[i].addr;
2187 if (is_badblock(conf->mirrors[d].rdev,
2188 sector, max_sync,
2189 &first_bad, &bad_sectors)) {
2190 if (first_bad > sector)
2191 max_sync = first_bad - sector;
2192 else {
2193 bad_sectors -= (sector - first_bad);
2194 if (max_sync > bad_sectors)
2195 max_sync = max_sync;
2196 continue;
2197 }
2198 }
2169 atomic_inc(&conf->mirrors[d].rdev->nr_pending); 2199 atomic_inc(&conf->mirrors[d].rdev->nr_pending);
2170 atomic_inc(&r10_bio->remaining); 2200 atomic_inc(&r10_bio->remaining);
2171 bio->bi_next = biolist; 2201 bio->bi_next = biolist;
@@ -2173,7 +2203,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr,
2173 bio->bi_private = r10_bio; 2203 bio->bi_private = r10_bio;
2174 bio->bi_end_io = end_sync_read; 2204 bio->bi_end_io = end_sync_read;
2175 bio->bi_rw = READ; 2205 bio->bi_rw = READ;
2176 bio->bi_sector = r10_bio->devs[i].addr + 2206 bio->bi_sector = sector +
2177 conf->mirrors[d].rdev->data_offset; 2207 conf->mirrors[d].rdev->data_offset;
2178 bio->bi_bdev = conf->mirrors[d].rdev->bdev; 2208 bio->bi_bdev = conf->mirrors[d].rdev->bdev;
2179 count++; 2209 count++;
@@ -2431,10 +2461,6 @@ static int run(mddev_t *mddev)
2431 2461
2432 list_for_each_entry(rdev, &mddev->disks, same_set) { 2462 list_for_each_entry(rdev, &mddev->disks, same_set) {
2433 2463
2434 if (rdev->badblocks.count) {
2435 printk(KERN_ERR "md/raid10: cannot handle bad blocks yet\n");
2436 goto out_free_conf;
2437 }
2438 disk_idx = rdev->raid_disk; 2464 disk_idx = rdev->raid_disk;
2439 if (disk_idx >= conf->raid_disks 2465 if (disk_idx >= conf->raid_disks
2440 || disk_idx < 0) 2466 || disk_idx < 0)