aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-08-31 12:02:06 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-08-31 12:02:06 -0400
commitfd53f7d8eea9cd43c5fb6d316ea1ed128c9b8e45 (patch)
tree5280fc457427b915506a7bfd838fe9790ed05023
parente9208a4eec8acbde7ede6516c39dea05f3b700dc (diff)
parent43220aa0f22cd3ce5b30246d50ccd696d119edea (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.h2
-rw-r--r--drivers/md/md.c16
-rw-r--r--drivers/md/raid5.c2
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
11struct linear_private_data 11struct 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
854void md_super_wait(mddev_t *mddev) 854void 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
3337finish: 3337finish:
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)