diff options
Diffstat (limited to 'drivers/md')
-rw-r--r-- | drivers/md/md.c | 42 | ||||
-rw-r--r-- | drivers/md/raid0.c | 5 | ||||
-rw-r--r-- | drivers/md/raid1.c | 29 | ||||
-rw-r--r-- | drivers/md/raid10.c | 46 |
4 files changed, 78 insertions, 44 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 1ed5152db450..f19b874753a9 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -163,9 +163,19 @@ void md_new_event(mddev_t *mddev) | |||
163 | { | 163 | { |
164 | atomic_inc(&md_event_count); | 164 | atomic_inc(&md_event_count); |
165 | wake_up(&md_event_waiters); | 165 | wake_up(&md_event_waiters); |
166 | sysfs_notify(&mddev->kobj, NULL, "sync_action"); | ||
166 | } | 167 | } |
167 | EXPORT_SYMBOL_GPL(md_new_event); | 168 | EXPORT_SYMBOL_GPL(md_new_event); |
168 | 169 | ||
170 | /* Alternate version that can be called from interrupts | ||
171 | * when calling sysfs_notify isn't needed. | ||
172 | */ | ||
173 | void md_new_event_inintr(mddev_t *mddev) | ||
174 | { | ||
175 | atomic_inc(&md_event_count); | ||
176 | wake_up(&md_event_waiters); | ||
177 | } | ||
178 | |||
169 | /* | 179 | /* |
170 | * Enables to iterate over all existing md arrays | 180 | * Enables to iterate over all existing md arrays |
171 | * all_mddevs_lock protects this list. | 181 | * all_mddevs_lock protects this list. |
@@ -278,11 +288,6 @@ static inline int mddev_lock(mddev_t * mddev) | |||
278 | return mutex_lock_interruptible(&mddev->reconfig_mutex); | 288 | return mutex_lock_interruptible(&mddev->reconfig_mutex); |
279 | } | 289 | } |
280 | 290 | ||
281 | static inline void mddev_lock_uninterruptible(mddev_t * mddev) | ||
282 | { | ||
283 | mutex_lock(&mddev->reconfig_mutex); | ||
284 | } | ||
285 | |||
286 | static inline int mddev_trylock(mddev_t * mddev) | 291 | static inline int mddev_trylock(mddev_t * mddev) |
287 | { | 292 | { |
288 | return mutex_trylock(&mddev->reconfig_mutex); | 293 | return mutex_trylock(&mddev->reconfig_mutex); |
@@ -2256,7 +2261,7 @@ action_store(mddev_t *mddev, const char *page, size_t len) | |||
2256 | } else { | 2261 | } else { |
2257 | if (cmd_match(page, "check")) | 2262 | if (cmd_match(page, "check")) |
2258 | set_bit(MD_RECOVERY_CHECK, &mddev->recovery); | 2263 | set_bit(MD_RECOVERY_CHECK, &mddev->recovery); |
2259 | else if (cmd_match(page, "repair")) | 2264 | else if (!cmd_match(page, "repair")) |
2260 | return -EINVAL; | 2265 | return -EINVAL; |
2261 | set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery); | 2266 | set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery); |
2262 | set_bit(MD_RECOVERY_SYNC, &mddev->recovery); | 2267 | set_bit(MD_RECOVERY_SYNC, &mddev->recovery); |
@@ -2457,9 +2462,11 @@ md_attr_show(struct kobject *kobj, struct attribute *attr, char *page) | |||
2457 | 2462 | ||
2458 | if (!entry->show) | 2463 | if (!entry->show) |
2459 | return -EIO; | 2464 | return -EIO; |
2460 | mddev_lock(mddev); | 2465 | rv = mddev_lock(mddev); |
2461 | rv = entry->show(mddev, page); | 2466 | if (!rv) { |
2462 | mddev_unlock(mddev); | 2467 | rv = entry->show(mddev, page); |
2468 | mddev_unlock(mddev); | ||
2469 | } | ||
2463 | return rv; | 2470 | return rv; |
2464 | } | 2471 | } |
2465 | 2472 | ||
@@ -2473,9 +2480,11 @@ md_attr_store(struct kobject *kobj, struct attribute *attr, | |||
2473 | 2480 | ||
2474 | if (!entry->store) | 2481 | if (!entry->store) |
2475 | return -EIO; | 2482 | return -EIO; |
2476 | mddev_lock(mddev); | 2483 | rv = mddev_lock(mddev); |
2477 | rv = entry->store(mddev, page, length); | 2484 | if (!rv) { |
2478 | mddev_unlock(mddev); | 2485 | rv = entry->store(mddev, page, length); |
2486 | mddev_unlock(mddev); | ||
2487 | } | ||
2479 | return rv; | 2488 | return rv; |
2480 | } | 2489 | } |
2481 | 2490 | ||
@@ -4149,7 +4158,7 @@ void md_error(mddev_t *mddev, mdk_rdev_t *rdev) | |||
4149 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); | 4158 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
4150 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 4159 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
4151 | md_wakeup_thread(mddev->thread); | 4160 | md_wakeup_thread(mddev->thread); |
4152 | md_new_event(mddev); | 4161 | md_new_event_inintr(mddev); |
4153 | } | 4162 | } |
4154 | 4163 | ||
4155 | /* seq_file implementation /proc/mdstat */ | 4164 | /* seq_file implementation /proc/mdstat */ |
@@ -4340,8 +4349,9 @@ static int md_seq_show(struct seq_file *seq, void *v) | |||
4340 | return 0; | 4349 | return 0; |
4341 | } | 4350 | } |
4342 | 4351 | ||
4343 | if (mddev_lock(mddev)!=0) | 4352 | if (mddev_lock(mddev) < 0) |
4344 | return -EINTR; | 4353 | return -EINTR; |
4354 | |||
4345 | if (mddev->pers || mddev->raid_disks || !list_empty(&mddev->disks)) { | 4355 | if (mddev->pers || mddev->raid_disks || !list_empty(&mddev->disks)) { |
4346 | seq_printf(seq, "%s : %sactive", mdname(mddev), | 4356 | seq_printf(seq, "%s : %sactive", mdname(mddev), |
4347 | mddev->pers ? "" : "in"); | 4357 | mddev->pers ? "" : "in"); |
@@ -5027,8 +5037,10 @@ static int md_notify_reboot(struct notifier_block *this, | |||
5027 | printk(KERN_INFO "md: stopping all md devices.\n"); | 5037 | printk(KERN_INFO "md: stopping all md devices.\n"); |
5028 | 5038 | ||
5029 | ITERATE_MDDEV(mddev,tmp) | 5039 | ITERATE_MDDEV(mddev,tmp) |
5030 | if (mddev_trylock(mddev)) | 5040 | if (mddev_trylock(mddev)) { |
5031 | do_md_stop (mddev, 1); | 5041 | do_md_stop (mddev, 1); |
5042 | mddev_unlock(mddev); | ||
5043 | } | ||
5032 | /* | 5044 | /* |
5033 | * certain more exotic SCSI devices are known to be | 5045 | * certain more exotic SCSI devices are known to be |
5034 | * volatile wrt too early system reboots. While the | 5046 | * volatile wrt too early system reboots. While the |
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 678f4dbbea1d..cb8c6317e4e5 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c | |||
@@ -331,13 +331,14 @@ static int raid0_run (mddev_t *mddev) | |||
331 | goto out_free_conf; | 331 | goto out_free_conf; |
332 | size = conf->strip_zone[cur].size; | 332 | size = conf->strip_zone[cur].size; |
333 | 333 | ||
334 | for (i=0; i< nb_zone; i++) { | 334 | conf->hash_table[0] = conf->strip_zone + cur; |
335 | conf->hash_table[i] = conf->strip_zone + cur; | 335 | for (i=1; i< nb_zone; i++) { |
336 | while (size <= conf->hash_spacing) { | 336 | while (size <= conf->hash_spacing) { |
337 | cur++; | 337 | cur++; |
338 | size += conf->strip_zone[cur].size; | 338 | size += conf->strip_zone[cur].size; |
339 | } | 339 | } |
340 | size -= conf->hash_spacing; | 340 | size -= conf->hash_spacing; |
341 | conf->hash_table[i] = conf->strip_zone + cur; | ||
341 | } | 342 | } |
342 | if (conf->preshift) { | 343 | if (conf->preshift) { |
343 | conf->hash_spacing >>= conf->preshift; | 344 | conf->hash_spacing >>= conf->preshift; |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 6081941de1b3..4070eff6f0f8 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -315,10 +315,11 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int | |||
315 | if (r1_bio->bios[mirror] == bio) | 315 | if (r1_bio->bios[mirror] == bio) |
316 | break; | 316 | break; |
317 | 317 | ||
318 | if (error == -ENOTSUPP && test_bit(R1BIO_Barrier, &r1_bio->state)) { | 318 | if (error == -EOPNOTSUPP && test_bit(R1BIO_Barrier, &r1_bio->state)) { |
319 | set_bit(BarriersNotsupp, &conf->mirrors[mirror].rdev->flags); | 319 | set_bit(BarriersNotsupp, &conf->mirrors[mirror].rdev->flags); |
320 | set_bit(R1BIO_BarrierRetry, &r1_bio->state); | 320 | set_bit(R1BIO_BarrierRetry, &r1_bio->state); |
321 | r1_bio->mddev->barriers_work = 0; | 321 | r1_bio->mddev->barriers_work = 0; |
322 | /* Don't rdev_dec_pending in this branch - keep it for the retry */ | ||
322 | } else { | 323 | } else { |
323 | /* | 324 | /* |
324 | * this branch is our 'one mirror IO has finished' event handler: | 325 | * this branch is our 'one mirror IO has finished' event handler: |
@@ -365,6 +366,7 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int | |||
365 | } | 366 | } |
366 | } | 367 | } |
367 | } | 368 | } |
369 | rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev); | ||
368 | } | 370 | } |
369 | /* | 371 | /* |
370 | * | 372 | * |
@@ -374,11 +376,9 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int | |||
374 | if (atomic_dec_and_test(&r1_bio->remaining)) { | 376 | if (atomic_dec_and_test(&r1_bio->remaining)) { |
375 | if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) { | 377 | if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) { |
376 | reschedule_retry(r1_bio); | 378 | reschedule_retry(r1_bio); |
377 | /* Don't dec_pending yet, we want to hold | ||
378 | * the reference over the retry | ||
379 | */ | ||
380 | goto out; | 379 | goto out; |
381 | } | 380 | } |
381 | /* it really is the end of this request */ | ||
382 | if (test_bit(R1BIO_BehindIO, &r1_bio->state)) { | 382 | if (test_bit(R1BIO_BehindIO, &r1_bio->state)) { |
383 | /* free extra copy of the data pages */ | 383 | /* free extra copy of the data pages */ |
384 | int i = bio->bi_vcnt; | 384 | int i = bio->bi_vcnt; |
@@ -393,8 +393,6 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int | |||
393 | md_write_end(r1_bio->mddev); | 393 | md_write_end(r1_bio->mddev); |
394 | raid_end_bio_io(r1_bio); | 394 | raid_end_bio_io(r1_bio); |
395 | } | 395 | } |
396 | |||
397 | rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev); | ||
398 | out: | 396 | out: |
399 | if (to_put) | 397 | if (to_put) |
400 | bio_put(to_put); | 398 | bio_put(to_put); |
@@ -753,18 +751,24 @@ static int make_request(request_queue_t *q, struct bio * bio) | |||
753 | const int rw = bio_data_dir(bio); | 751 | const int rw = bio_data_dir(bio); |
754 | int do_barriers; | 752 | int do_barriers; |
755 | 753 | ||
756 | if (unlikely(!mddev->barriers_work && bio_barrier(bio))) { | ||
757 | bio_endio(bio, bio->bi_size, -EOPNOTSUPP); | ||
758 | return 0; | ||
759 | } | ||
760 | |||
761 | /* | 754 | /* |
762 | * Register the new request and wait if the reconstruction | 755 | * Register the new request and wait if the reconstruction |
763 | * thread has put up a bar for new requests. | 756 | * thread has put up a bar for new requests. |
764 | * Continue immediately if no resync is active currently. | 757 | * Continue immediately if no resync is active currently. |
758 | * We test barriers_work *after* md_write_start as md_write_start | ||
759 | * may cause the first superblock write, and that will check out | ||
760 | * if barriers work. | ||
765 | */ | 761 | */ |
762 | |||
766 | md_write_start(mddev, bio); /* wait on superblock update early */ | 763 | md_write_start(mddev, bio); /* wait on superblock update early */ |
767 | 764 | ||
765 | if (unlikely(!mddev->barriers_work && bio_barrier(bio))) { | ||
766 | if (rw == WRITE) | ||
767 | md_write_end(mddev); | ||
768 | bio_endio(bio, bio->bi_size, -EOPNOTSUPP); | ||
769 | return 0; | ||
770 | } | ||
771 | |||
768 | wait_barrier(conf); | 772 | wait_barrier(conf); |
769 | 773 | ||
770 | disk_stat_inc(mddev->gendisk, ios[rw]); | 774 | disk_stat_inc(mddev->gendisk, ios[rw]); |
@@ -1404,10 +1408,11 @@ static void raid1d(mddev_t *mddev) | |||
1404 | unplug = 1; | 1408 | unplug = 1; |
1405 | } else if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) { | 1409 | } else if (test_bit(R1BIO_BarrierRetry, &r1_bio->state)) { |
1406 | /* some requests in the r1bio were BIO_RW_BARRIER | 1410 | /* some requests in the r1bio were BIO_RW_BARRIER |
1407 | * requests which failed with -ENOTSUPP. Hohumm.. | 1411 | * requests which failed with -EOPNOTSUPP. Hohumm.. |
1408 | * Better resubmit without the barrier. | 1412 | * Better resubmit without the barrier. |
1409 | * We know which devices to resubmit for, because | 1413 | * We know which devices to resubmit for, because |
1410 | * all others have had their bios[] entry cleared. | 1414 | * all others have had their bios[] entry cleared. |
1415 | * We already have a nr_pending reference on these rdevs. | ||
1411 | */ | 1416 | */ |
1412 | int i; | 1417 | int i; |
1413 | clear_bit(R1BIO_BarrierRetry, &r1_bio->state); | 1418 | clear_bit(R1BIO_BarrierRetry, &r1_bio->state); |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 617012bc107a..1440935414e6 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -1407,43 +1407,54 @@ static void raid10d(mddev_t *mddev) | |||
1407 | if (s > (PAGE_SIZE>>9)) | 1407 | if (s > (PAGE_SIZE>>9)) |
1408 | s = PAGE_SIZE >> 9; | 1408 | s = PAGE_SIZE >> 9; |
1409 | 1409 | ||
1410 | rcu_read_lock(); | ||
1410 | do { | 1411 | do { |
1411 | int d = r10_bio->devs[sl].devnum; | 1412 | int d = r10_bio->devs[sl].devnum; |
1412 | rdev = conf->mirrors[d].rdev; | 1413 | rdev = rcu_dereference(conf->mirrors[d].rdev); |
1413 | if (rdev && | 1414 | if (rdev && |
1414 | test_bit(In_sync, &rdev->flags) && | 1415 | test_bit(In_sync, &rdev->flags)) { |
1415 | sync_page_io(rdev->bdev, | 1416 | atomic_inc(&rdev->nr_pending); |
1416 | r10_bio->devs[sl].addr + | 1417 | rcu_read_unlock(); |
1417 | sect + rdev->data_offset, | 1418 | success = sync_page_io(rdev->bdev, |
1418 | s<<9, | 1419 | r10_bio->devs[sl].addr + |
1419 | conf->tmppage, READ)) | 1420 | sect + rdev->data_offset, |
1420 | success = 1; | 1421 | s<<9, |
1421 | else { | 1422 | conf->tmppage, READ); |
1422 | sl++; | 1423 | rdev_dec_pending(rdev, mddev); |
1423 | if (sl == conf->copies) | 1424 | rcu_read_lock(); |
1424 | sl = 0; | 1425 | if (success) |
1426 | break; | ||
1425 | } | 1427 | } |
1428 | sl++; | ||
1429 | if (sl == conf->copies) | ||
1430 | sl = 0; | ||
1426 | } while (!success && sl != r10_bio->read_slot); | 1431 | } while (!success && sl != r10_bio->read_slot); |
1432 | rcu_read_unlock(); | ||
1427 | 1433 | ||
1428 | if (success) { | 1434 | if (success) { |
1429 | int start = sl; | 1435 | int start = sl; |
1430 | /* write it back and re-read */ | 1436 | /* write it back and re-read */ |
1437 | rcu_read_lock(); | ||
1431 | while (sl != r10_bio->read_slot) { | 1438 | while (sl != r10_bio->read_slot) { |
1432 | int d; | 1439 | int d; |
1433 | if (sl==0) | 1440 | if (sl==0) |
1434 | sl = conf->copies; | 1441 | sl = conf->copies; |
1435 | sl--; | 1442 | sl--; |
1436 | d = r10_bio->devs[sl].devnum; | 1443 | d = r10_bio->devs[sl].devnum; |
1437 | rdev = conf->mirrors[d].rdev; | 1444 | rdev = rcu_dereference(conf->mirrors[d].rdev); |
1438 | atomic_add(s, &rdev->corrected_errors); | ||
1439 | if (rdev && | 1445 | if (rdev && |
1440 | test_bit(In_sync, &rdev->flags)) { | 1446 | test_bit(In_sync, &rdev->flags)) { |
1447 | atomic_inc(&rdev->nr_pending); | ||
1448 | rcu_read_unlock(); | ||
1449 | atomic_add(s, &rdev->corrected_errors); | ||
1441 | if (sync_page_io(rdev->bdev, | 1450 | if (sync_page_io(rdev->bdev, |
1442 | r10_bio->devs[sl].addr + | 1451 | r10_bio->devs[sl].addr + |
1443 | sect + rdev->data_offset, | 1452 | sect + rdev->data_offset, |
1444 | s<<9, conf->tmppage, WRITE) == 0) | 1453 | s<<9, conf->tmppage, WRITE) == 0) |
1445 | /* Well, this device is dead */ | 1454 | /* Well, this device is dead */ |
1446 | md_error(mddev, rdev); | 1455 | md_error(mddev, rdev); |
1456 | rdev_dec_pending(rdev, mddev); | ||
1457 | rcu_read_lock(); | ||
1447 | } | 1458 | } |
1448 | } | 1459 | } |
1449 | sl = start; | 1460 | sl = start; |
@@ -1453,17 +1464,22 @@ static void raid10d(mddev_t *mddev) | |||
1453 | sl = conf->copies; | 1464 | sl = conf->copies; |
1454 | sl--; | 1465 | sl--; |
1455 | d = r10_bio->devs[sl].devnum; | 1466 | d = r10_bio->devs[sl].devnum; |
1456 | rdev = conf->mirrors[d].rdev; | 1467 | rdev = rcu_dereference(conf->mirrors[d].rdev); |
1457 | if (rdev && | 1468 | if (rdev && |
1458 | test_bit(In_sync, &rdev->flags)) { | 1469 | test_bit(In_sync, &rdev->flags)) { |
1470 | atomic_inc(&rdev->nr_pending); | ||
1471 | rcu_read_unlock(); | ||
1459 | if (sync_page_io(rdev->bdev, | 1472 | if (sync_page_io(rdev->bdev, |
1460 | r10_bio->devs[sl].addr + | 1473 | r10_bio->devs[sl].addr + |
1461 | sect + rdev->data_offset, | 1474 | sect + rdev->data_offset, |
1462 | s<<9, conf->tmppage, READ) == 0) | 1475 | s<<9, conf->tmppage, READ) == 0) |
1463 | /* Well, this device is dead */ | 1476 | /* Well, this device is dead */ |
1464 | md_error(mddev, rdev); | 1477 | md_error(mddev, rdev); |
1478 | rdev_dec_pending(rdev, mddev); | ||
1479 | rcu_read_lock(); | ||
1465 | } | 1480 | } |
1466 | } | 1481 | } |
1482 | rcu_read_unlock(); | ||
1467 | } else { | 1483 | } else { |
1468 | /* Cannot read from anywhere -- bye bye array */ | 1484 | /* Cannot read from anywhere -- bye bye array */ |
1469 | md_error(mddev, conf->mirrors[r10_bio->devs[r10_bio->read_slot].devnum].rdev); | 1485 | md_error(mddev, conf->mirrors[r10_bio->devs[r10_bio->read_slot].devnum].rdev); |