diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-08-31 12:02:06 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-08-31 12:02:06 -0400 |
| commit | fd53f7d8eea9cd43c5fb6d316ea1ed128c9b8e45 (patch) | |
| tree | 5280fc457427b915506a7bfd838fe9790ed05023 | |
| parent | e9208a4eec8acbde7ede6516c39dea05f3b700dc (diff) | |
| parent | 43220aa0f22cd3ce5b30246d50ccd696d119edea (diff) | |
Merge branch 'for-linus' of git://neil.brown.name/md
* 'for-linus' of git://neil.brown.name/md:
md/raid5: fix a hang on device failure.
md: fix clearing of 'blocked' flag in the presence of bad blocks.
md/linear: avoid corrupting structure while waiting for rcu_free to complete.
md: use REQ_NOIDLE flag in md_super_write()
md: ensure changes to 'write-mostly' are reflected in metadata.
md: report failure if a 'set faulty' request doesn't.
| -rw-r--r-- | drivers/md/linear.h | 2 | ||||
| -rw-r--r-- | drivers/md/md.c | 16 | ||||
| -rw-r--r-- | drivers/md/raid5.c | 2 |
3 files changed, 15 insertions, 5 deletions
diff --git a/drivers/md/linear.h b/drivers/md/linear.h index 0ce29b61605a..2f2da05b2ce9 100644 --- a/drivers/md/linear.h +++ b/drivers/md/linear.h | |||
| @@ -10,9 +10,9 @@ typedef struct dev_info dev_info_t; | |||
| 10 | 10 | ||
| 11 | struct linear_private_data | 11 | struct linear_private_data |
| 12 | { | 12 | { |
| 13 | struct rcu_head rcu; | ||
| 13 | sector_t array_sectors; | 14 | sector_t array_sectors; |
| 14 | dev_info_t disks[0]; | 15 | dev_info_t disks[0]; |
| 15 | struct rcu_head rcu; | ||
| 16 | }; | 16 | }; |
| 17 | 17 | ||
| 18 | 18 | ||
diff --git a/drivers/md/md.c b/drivers/md/md.c index 8e221a20f5d9..3742ce8b0acf 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -848,7 +848,7 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev, | |||
| 848 | bio->bi_end_io = super_written; | 848 | bio->bi_end_io = super_written; |
| 849 | 849 | ||
| 850 | atomic_inc(&mddev->pending_writes); | 850 | atomic_inc(&mddev->pending_writes); |
| 851 | submit_bio(REQ_WRITE | REQ_SYNC | REQ_FLUSH | REQ_FUA, bio); | 851 | submit_bio(WRITE_FLUSH_FUA, bio); |
| 852 | } | 852 | } |
| 853 | 853 | ||
| 854 | void md_super_wait(mddev_t *mddev) | 854 | void md_super_wait(mddev_t *mddev) |
| @@ -1738,6 +1738,11 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
| 1738 | sb->level = cpu_to_le32(mddev->level); | 1738 | sb->level = cpu_to_le32(mddev->level); |
| 1739 | sb->layout = cpu_to_le32(mddev->layout); | 1739 | sb->layout = cpu_to_le32(mddev->layout); |
| 1740 | 1740 | ||
| 1741 | if (test_bit(WriteMostly, &rdev->flags)) | ||
| 1742 | sb->devflags |= WriteMostly1; | ||
| 1743 | else | ||
| 1744 | sb->devflags &= ~WriteMostly1; | ||
| 1745 | |||
| 1741 | if (mddev->bitmap && mddev->bitmap_info.file == NULL) { | 1746 | if (mddev->bitmap && mddev->bitmap_info.file == NULL) { |
| 1742 | sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_info.offset); | 1747 | sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_info.offset); |
| 1743 | sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); | 1748 | sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET); |
| @@ -2561,7 +2566,10 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
| 2561 | int err = -EINVAL; | 2566 | int err = -EINVAL; |
| 2562 | if (cmd_match(buf, "faulty") && rdev->mddev->pers) { | 2567 | if (cmd_match(buf, "faulty") && rdev->mddev->pers) { |
| 2563 | md_error(rdev->mddev, rdev); | 2568 | md_error(rdev->mddev, rdev); |
| 2564 | err = 0; | 2569 | if (test_bit(Faulty, &rdev->flags)) |
| 2570 | err = 0; | ||
| 2571 | else | ||
| 2572 | err = -EBUSY; | ||
| 2565 | } else if (cmd_match(buf, "remove")) { | 2573 | } else if (cmd_match(buf, "remove")) { |
| 2566 | if (rdev->raid_disk >= 0) | 2574 | if (rdev->raid_disk >= 0) |
| 2567 | err = -EBUSY; | 2575 | err = -EBUSY; |
| @@ -2584,7 +2592,7 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
| 2584 | err = 0; | 2592 | err = 0; |
| 2585 | } else if (cmd_match(buf, "-blocked")) { | 2593 | } else if (cmd_match(buf, "-blocked")) { |
| 2586 | if (!test_bit(Faulty, &rdev->flags) && | 2594 | if (!test_bit(Faulty, &rdev->flags) && |
| 2587 | test_bit(BlockedBadBlocks, &rdev->flags)) { | 2595 | rdev->badblocks.unacked_exist) { |
| 2588 | /* metadata handler doesn't understand badblocks, | 2596 | /* metadata handler doesn't understand badblocks, |
| 2589 | * so we need to fail the device | 2597 | * so we need to fail the device |
| 2590 | */ | 2598 | */ |
| @@ -5983,6 +5991,8 @@ static int set_disk_faulty(mddev_t *mddev, dev_t dev) | |||
| 5983 | return -ENODEV; | 5991 | return -ENODEV; |
| 5984 | 5992 | ||
| 5985 | md_error(mddev, rdev); | 5993 | md_error(mddev, rdev); |
| 5994 | if (!test_bit(Faulty, &rdev->flags)) | ||
| 5995 | return -EBUSY; | ||
| 5986 | return 0; | 5996 | return 0; |
| 5987 | } | 5997 | } |
| 5988 | 5998 | ||
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index dbae459fb02d..43709fa6b6df 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
| @@ -3336,7 +3336,7 @@ static void handle_stripe(struct stripe_head *sh) | |||
| 3336 | 3336 | ||
| 3337 | finish: | 3337 | finish: |
| 3338 | /* wait for this device to become unblocked */ | 3338 | /* wait for this device to become unblocked */ |
| 3339 | if (unlikely(s.blocked_rdev)) | 3339 | if (conf->mddev->external && unlikely(s.blocked_rdev)) |
| 3340 | md_wait_for_blocked_rdev(s.blocked_rdev, conf->mddev); | 3340 | md_wait_for_blocked_rdev(s.blocked_rdev, conf->mddev); |
| 3341 | 3341 | ||
| 3342 | if (s.handle_bad_blocks) | 3342 | if (s.handle_bad_blocks) |
