diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-09-10 13:19:15 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-09-10 13:19:15 -0400 |
commit | 290a1cc4f725a53076e0fda804cd4fea84ee4564 (patch) | |
tree | ca7c8f8d78dd7afda036ea1e7a1362093b1578e8 /drivers | |
parent | ed2888e906b56769b4ffabb9c577190438aa68b8 (diff) | |
parent | 27a7b260f71439c40546b43588448faac01adb93 (diff) |
Merge branch 'for-linus' of git://neil.brown.name/md
* 'for-linus' of git://neil.brown.name/md:
md: Fix handling for devices from 2TB to 4TB in 0.90 metadata.
md/raid1,10: Remove use-after-free bug in make_request.
md/raid10: unify handling of write completion.
Avoid dereferencing a 'request_queue' after last close.
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/md/md.c | 12 | ||||
-rw-r--r-- | drivers/md/raid1.c | 14 | ||||
-rw-r--r-- | drivers/md/raid10.c | 47 |
3 files changed, 43 insertions, 30 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 3742ce8b0acf..5404b2295820 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1138,8 +1138,11 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version | |||
1138 | ret = 0; | 1138 | ret = 0; |
1139 | } | 1139 | } |
1140 | rdev->sectors = rdev->sb_start; | 1140 | rdev->sectors = rdev->sb_start; |
1141 | /* Limit to 4TB as metadata cannot record more than that */ | ||
1142 | if (rdev->sectors >= (2ULL << 32)) | ||
1143 | rdev->sectors = (2ULL << 32) - 2; | ||
1141 | 1144 | ||
1142 | if (rdev->sectors < sb->size * 2 && sb->level > 1) | 1145 | if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1) |
1143 | /* "this cannot possibly happen" ... */ | 1146 | /* "this cannot possibly happen" ... */ |
1144 | ret = -EINVAL; | 1147 | ret = -EINVAL; |
1145 | 1148 | ||
@@ -1173,7 +1176,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1173 | mddev->clevel[0] = 0; | 1176 | mddev->clevel[0] = 0; |
1174 | mddev->layout = sb->layout; | 1177 | mddev->layout = sb->layout; |
1175 | mddev->raid_disks = sb->raid_disks; | 1178 | mddev->raid_disks = sb->raid_disks; |
1176 | mddev->dev_sectors = sb->size * 2; | 1179 | mddev->dev_sectors = ((sector_t)sb->size) * 2; |
1177 | mddev->events = ev1; | 1180 | mddev->events = ev1; |
1178 | mddev->bitmap_info.offset = 0; | 1181 | mddev->bitmap_info.offset = 0; |
1179 | mddev->bitmap_info.default_offset = MD_SB_BYTES >> 9; | 1182 | mddev->bitmap_info.default_offset = MD_SB_BYTES >> 9; |
@@ -1415,6 +1418,11 @@ super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors) | |||
1415 | rdev->sb_start = calc_dev_sboffset(rdev); | 1418 | rdev->sb_start = calc_dev_sboffset(rdev); |
1416 | if (!num_sectors || num_sectors > rdev->sb_start) | 1419 | if (!num_sectors || num_sectors > rdev->sb_start) |
1417 | num_sectors = rdev->sb_start; | 1420 | num_sectors = rdev->sb_start; |
1421 | /* Limit to 4TB as metadata cannot record more than that. | ||
1422 | * 4TB == 2^32 KB, or 2*2^32 sectors. | ||
1423 | */ | ||
1424 | if (num_sectors >= (2ULL << 32)) | ||
1425 | num_sectors = (2ULL << 32) - 2; | ||
1418 | md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, | 1426 | md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, |
1419 | rdev->sb_page); | 1427 | rdev->sb_page); |
1420 | md_super_wait(rdev->mddev); | 1428 | md_super_wait(rdev->mddev); |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 32323f0afd89..f4622dd8fc59 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -1099,12 +1099,11 @@ read_again: | |||
1099 | bio_list_add(&conf->pending_bio_list, mbio); | 1099 | bio_list_add(&conf->pending_bio_list, mbio); |
1100 | spin_unlock_irqrestore(&conf->device_lock, flags); | 1100 | spin_unlock_irqrestore(&conf->device_lock, flags); |
1101 | } | 1101 | } |
1102 | r1_bio_write_done(r1_bio); | 1102 | /* Mustn't call r1_bio_write_done before this next test, |
1103 | 1103 | * as it could result in the bio being freed. | |
1104 | /* In case raid1d snuck in to freeze_array */ | 1104 | */ |
1105 | wake_up(&conf->wait_barrier); | ||
1106 | |||
1107 | if (sectors_handled < (bio->bi_size >> 9)) { | 1105 | if (sectors_handled < (bio->bi_size >> 9)) { |
1106 | r1_bio_write_done(r1_bio); | ||
1108 | /* We need another r1_bio. It has already been counted | 1107 | /* We need another r1_bio. It has already been counted |
1109 | * in bio->bi_phys_segments | 1108 | * in bio->bi_phys_segments |
1110 | */ | 1109 | */ |
@@ -1117,6 +1116,11 @@ read_again: | |||
1117 | goto retry_write; | 1116 | goto retry_write; |
1118 | } | 1117 | } |
1119 | 1118 | ||
1119 | r1_bio_write_done(r1_bio); | ||
1120 | |||
1121 | /* In case raid1d snuck in to freeze_array */ | ||
1122 | wake_up(&conf->wait_barrier); | ||
1123 | |||
1120 | if (do_sync || !bitmap || !plugged) | 1124 | if (do_sync || !bitmap || !plugged) |
1121 | md_wakeup_thread(mddev->thread); | 1125 | md_wakeup_thread(mddev->thread); |
1122 | 1126 | ||
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 8b29cd4f01c8..d7a8468ddeab 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -337,6 +337,21 @@ static void close_write(r10bio_t *r10_bio) | |||
337 | md_write_end(r10_bio->mddev); | 337 | md_write_end(r10_bio->mddev); |
338 | } | 338 | } |
339 | 339 | ||
340 | static void one_write_done(r10bio_t *r10_bio) | ||
341 | { | ||
342 | if (atomic_dec_and_test(&r10_bio->remaining)) { | ||
343 | if (test_bit(R10BIO_WriteError, &r10_bio->state)) | ||
344 | reschedule_retry(r10_bio); | ||
345 | else { | ||
346 | close_write(r10_bio); | ||
347 | if (test_bit(R10BIO_MadeGood, &r10_bio->state)) | ||
348 | reschedule_retry(r10_bio); | ||
349 | else | ||
350 | raid_end_bio_io(r10_bio); | ||
351 | } | ||
352 | } | ||
353 | } | ||
354 | |||
340 | static void raid10_end_write_request(struct bio *bio, int error) | 355 | static void raid10_end_write_request(struct bio *bio, int error) |
341 | { | 356 | { |
342 | int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); | 357 | int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); |
@@ -387,17 +402,7 @@ static void raid10_end_write_request(struct bio *bio, int error) | |||
387 | * Let's see if all mirrored write operations have finished | 402 | * Let's see if all mirrored write operations have finished |
388 | * already. | 403 | * already. |
389 | */ | 404 | */ |
390 | if (atomic_dec_and_test(&r10_bio->remaining)) { | 405 | one_write_done(r10_bio); |
391 | if (test_bit(R10BIO_WriteError, &r10_bio->state)) | ||
392 | reschedule_retry(r10_bio); | ||
393 | else { | ||
394 | close_write(r10_bio); | ||
395 | if (test_bit(R10BIO_MadeGood, &r10_bio->state)) | ||
396 | reschedule_retry(r10_bio); | ||
397 | else | ||
398 | raid_end_bio_io(r10_bio); | ||
399 | } | ||
400 | } | ||
401 | if (dec_rdev) | 406 | if (dec_rdev) |
402 | rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev); | 407 | rdev_dec_pending(conf->mirrors[dev].rdev, conf->mddev); |
403 | } | 408 | } |
@@ -1127,20 +1132,12 @@ retry_write: | |||
1127 | spin_unlock_irqrestore(&conf->device_lock, flags); | 1132 | spin_unlock_irqrestore(&conf->device_lock, flags); |
1128 | } | 1133 | } |
1129 | 1134 | ||
1130 | if (atomic_dec_and_test(&r10_bio->remaining)) { | 1135 | /* Don't remove the bias on 'remaining' (one_write_done) until |
1131 | /* This matches the end of raid10_end_write_request() */ | 1136 | * after checking if we need to go around again. |
1132 | bitmap_endwrite(r10_bio->mddev->bitmap, r10_bio->sector, | 1137 | */ |
1133 | r10_bio->sectors, | ||
1134 | !test_bit(R10BIO_Degraded, &r10_bio->state), | ||
1135 | 0); | ||
1136 | md_write_end(mddev); | ||
1137 | raid_end_bio_io(r10_bio); | ||
1138 | } | ||
1139 | |||
1140 | /* In case raid10d snuck in to freeze_array */ | ||
1141 | wake_up(&conf->wait_barrier); | ||
1142 | 1138 | ||
1143 | if (sectors_handled < (bio->bi_size >> 9)) { | 1139 | if (sectors_handled < (bio->bi_size >> 9)) { |
1140 | one_write_done(r10_bio); | ||
1144 | /* We need another r10_bio. It has already been counted | 1141 | /* We need another r10_bio. It has already been counted |
1145 | * in bio->bi_phys_segments. | 1142 | * in bio->bi_phys_segments. |
1146 | */ | 1143 | */ |
@@ -1154,6 +1151,10 @@ retry_write: | |||
1154 | r10_bio->state = 0; | 1151 | r10_bio->state = 0; |
1155 | goto retry_write; | 1152 | goto retry_write; |
1156 | } | 1153 | } |
1154 | one_write_done(r10_bio); | ||
1155 | |||
1156 | /* In case raid10d snuck in to freeze_array */ | ||
1157 | wake_up(&conf->wait_barrier); | ||
1157 | 1158 | ||
1158 | if (do_sync || !mddev->bitmap || !plugged) | 1159 | if (do_sync || !mddev->bitmap || !plugged) |
1159 | md_wakeup_thread(mddev->thread); | 1160 | md_wakeup_thread(mddev->thread); |