aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-09-10 13:19:15 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-09-10 13:19:15 -0400
commit290a1cc4f725a53076e0fda804cd4fea84ee4564 (patch)
treeca7c8f8d78dd7afda036ea1e7a1362093b1578e8 /drivers
parented2888e906b56769b4ffabb9c577190438aa68b8 (diff)
parent27a7b260f71439c40546b43588448faac01adb93 (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.c12
-rw-r--r--drivers/md/raid1.c14
-rw-r--r--drivers/md/raid10.c47
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
340static 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
340static void raid10_end_write_request(struct bio *bio, int error) 355static 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);