diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-12-19 19:46:46 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-12-19 19:46:46 -0500 |
commit | 3a87711e5842f2e7046f550b2414320f9240ff2e (patch) | |
tree | 9b475f1cfb50916faa1c73de8fd6abd13423d34f | |
parent | 35b3154efbba334166a2a8e610ca9a8a0d11e8e6 (diff) | |
parent | cb01c5496d2d9c0c862443561df16ff122db348f (diff) |
Merge tag 'md/4.4-rc5-fixes' of git://neil.brown.name/md
Pull md fixes from Neil Brown:
"Four fixes for md:
- two recently introduced regressions fixed.
- one older bug in RAID10 - tagged for -stable since 4.2
- one minor sysfs api improvement"
* tag 'md/4.4-rc5-fixes' of git://neil.brown.name/md:
Fix remove_and_add_spares removes drive added as spare in slot_store
md: fix bug due to nested suspend
MD: change journal disk role to disk 0
md/raid10: fix data corruption and crash during resync
-rw-r--r-- | drivers/md/md.c | 22 | ||||
-rw-r--r-- | drivers/md/md.h | 8 | ||||
-rw-r--r-- | drivers/md/raid10.c | 4 |
3 files changed, 24 insertions, 10 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 807095f4c793..dbedc58d8c00 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -314,8 +314,8 @@ static blk_qc_t md_make_request(struct request_queue *q, struct bio *bio) | |||
314 | */ | 314 | */ |
315 | void mddev_suspend(struct mddev *mddev) | 315 | void mddev_suspend(struct mddev *mddev) |
316 | { | 316 | { |
317 | BUG_ON(mddev->suspended); | 317 | if (mddev->suspended++) |
318 | mddev->suspended = 1; | 318 | return; |
319 | synchronize_rcu(); | 319 | synchronize_rcu(); |
320 | wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0); | 320 | wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0); |
321 | mddev->pers->quiesce(mddev, 1); | 321 | mddev->pers->quiesce(mddev, 1); |
@@ -326,7 +326,8 @@ EXPORT_SYMBOL_GPL(mddev_suspend); | |||
326 | 326 | ||
327 | void mddev_resume(struct mddev *mddev) | 327 | void mddev_resume(struct mddev *mddev) |
328 | { | 328 | { |
329 | mddev->suspended = 0; | 329 | if (--mddev->suspended) |
330 | return; | ||
330 | wake_up(&mddev->sb_wait); | 331 | wake_up(&mddev->sb_wait); |
331 | mddev->pers->quiesce(mddev, 0); | 332 | mddev->pers->quiesce(mddev, 0); |
332 | 333 | ||
@@ -1652,7 +1653,7 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev) | |||
1652 | rdev->journal_tail = le64_to_cpu(sb->journal_tail); | 1653 | rdev->journal_tail = le64_to_cpu(sb->journal_tail); |
1653 | if (mddev->recovery_cp == MaxSector) | 1654 | if (mddev->recovery_cp == MaxSector) |
1654 | set_bit(MD_JOURNAL_CLEAN, &mddev->flags); | 1655 | set_bit(MD_JOURNAL_CLEAN, &mddev->flags); |
1655 | rdev->raid_disk = mddev->raid_disks; | 1656 | rdev->raid_disk = 0; |
1656 | break; | 1657 | break; |
1657 | default: | 1658 | default: |
1658 | rdev->saved_raid_disk = role; | 1659 | rdev->saved_raid_disk = role; |
@@ -2773,6 +2774,7 @@ slot_store(struct md_rdev *rdev, const char *buf, size_t len) | |||
2773 | /* Activating a spare .. or possibly reactivating | 2774 | /* Activating a spare .. or possibly reactivating |
2774 | * if we ever get bitmaps working here. | 2775 | * if we ever get bitmaps working here. |
2775 | */ | 2776 | */ |
2777 | int err; | ||
2776 | 2778 | ||
2777 | if (rdev->raid_disk != -1) | 2779 | if (rdev->raid_disk != -1) |
2778 | return -EBUSY; | 2780 | return -EBUSY; |
@@ -2794,9 +2796,15 @@ slot_store(struct md_rdev *rdev, const char *buf, size_t len) | |||
2794 | rdev->saved_raid_disk = -1; | 2796 | rdev->saved_raid_disk = -1; |
2795 | clear_bit(In_sync, &rdev->flags); | 2797 | clear_bit(In_sync, &rdev->flags); |
2796 | clear_bit(Bitmap_sync, &rdev->flags); | 2798 | clear_bit(Bitmap_sync, &rdev->flags); |
2797 | remove_and_add_spares(rdev->mddev, rdev); | 2799 | err = rdev->mddev->pers-> |
2798 | if (rdev->raid_disk == -1) | 2800 | hot_add_disk(rdev->mddev, rdev); |
2799 | return -EBUSY; | 2801 | if (err) { |
2802 | rdev->raid_disk = -1; | ||
2803 | return err; | ||
2804 | } else | ||
2805 | sysfs_notify_dirent_safe(rdev->sysfs_state); | ||
2806 | if (sysfs_link_rdev(rdev->mddev, rdev)) | ||
2807 | /* failure here is OK */; | ||
2800 | /* don't wakeup anyone, leave that to userspace. */ | 2808 | /* don't wakeup anyone, leave that to userspace. */ |
2801 | } else { | 2809 | } else { |
2802 | if (slot >= rdev->mddev->raid_disks && | 2810 | if (slot >= rdev->mddev->raid_disks && |
diff --git a/drivers/md/md.h b/drivers/md/md.h index 2bea51edfab7..ca0b643fe3c1 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h | |||
@@ -566,7 +566,9 @@ static inline char * mdname (struct mddev * mddev) | |||
566 | static inline int sysfs_link_rdev(struct mddev *mddev, struct md_rdev *rdev) | 566 | static inline int sysfs_link_rdev(struct mddev *mddev, struct md_rdev *rdev) |
567 | { | 567 | { |
568 | char nm[20]; | 568 | char nm[20]; |
569 | if (!test_bit(Replacement, &rdev->flags) && mddev->kobj.sd) { | 569 | if (!test_bit(Replacement, &rdev->flags) && |
570 | !test_bit(Journal, &rdev->flags) && | ||
571 | mddev->kobj.sd) { | ||
570 | sprintf(nm, "rd%d", rdev->raid_disk); | 572 | sprintf(nm, "rd%d", rdev->raid_disk); |
571 | return sysfs_create_link(&mddev->kobj, &rdev->kobj, nm); | 573 | return sysfs_create_link(&mddev->kobj, &rdev->kobj, nm); |
572 | } else | 574 | } else |
@@ -576,7 +578,9 @@ static inline int sysfs_link_rdev(struct mddev *mddev, struct md_rdev *rdev) | |||
576 | static inline void sysfs_unlink_rdev(struct mddev *mddev, struct md_rdev *rdev) | 578 | static inline void sysfs_unlink_rdev(struct mddev *mddev, struct md_rdev *rdev) |
577 | { | 579 | { |
578 | char nm[20]; | 580 | char nm[20]; |
579 | if (!test_bit(Replacement, &rdev->flags) && mddev->kobj.sd) { | 581 | if (!test_bit(Replacement, &rdev->flags) && |
582 | !test_bit(Journal, &rdev->flags) && | ||
583 | mddev->kobj.sd) { | ||
580 | sprintf(nm, "rd%d", rdev->raid_disk); | 584 | sprintf(nm, "rd%d", rdev->raid_disk); |
581 | sysfs_remove_link(&mddev->kobj, nm); | 585 | sysfs_remove_link(&mddev->kobj, nm); |
582 | } | 586 | } |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 41d70bc9ba2f..84e597e1c489 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -1946,6 +1946,8 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio) | |||
1946 | 1946 | ||
1947 | first = i; | 1947 | first = i; |
1948 | fbio = r10_bio->devs[i].bio; | 1948 | fbio = r10_bio->devs[i].bio; |
1949 | fbio->bi_iter.bi_size = r10_bio->sectors << 9; | ||
1950 | fbio->bi_iter.bi_idx = 0; | ||
1949 | 1951 | ||
1950 | vcnt = (r10_bio->sectors + (PAGE_SIZE >> 9) - 1) >> (PAGE_SHIFT - 9); | 1952 | vcnt = (r10_bio->sectors + (PAGE_SIZE >> 9) - 1) >> (PAGE_SHIFT - 9); |
1951 | /* now find blocks with errors */ | 1953 | /* now find blocks with errors */ |
@@ -1989,7 +1991,7 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio) | |||
1989 | bio_reset(tbio); | 1991 | bio_reset(tbio); |
1990 | 1992 | ||
1991 | tbio->bi_vcnt = vcnt; | 1993 | tbio->bi_vcnt = vcnt; |
1992 | tbio->bi_iter.bi_size = r10_bio->sectors << 9; | 1994 | tbio->bi_iter.bi_size = fbio->bi_iter.bi_size; |
1993 | tbio->bi_rw = WRITE; | 1995 | tbio->bi_rw = WRITE; |
1994 | tbio->bi_private = r10_bio; | 1996 | tbio->bi_private = r10_bio; |
1995 | tbio->bi_iter.bi_sector = r10_bio->devs[i].addr; | 1997 | tbio->bi_iter.bi_sector = r10_bio->devs[i].addr; |