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) |