Эх сурвалжийг харах

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.
Linus Torvalds 13 жил өмнө
parent
commit
fd53f7d8ee

+ 1 - 1
drivers/md/linear.h

@@ -10,9 +10,9 @@ typedef struct dev_info dev_info_t;
 
 
 struct linear_private_data
 struct linear_private_data
 {
 {
+	struct rcu_head		rcu;
 	sector_t		array_sectors;
 	sector_t		array_sectors;
 	dev_info_t		disks[0];
 	dev_info_t		disks[0];
-	struct rcu_head		rcu;
 };
 };
 
 
 
 

+ 13 - 3
drivers/md/md.c

@@ -848,7 +848,7 @@ void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
 	bio->bi_end_io = super_written;
 	bio->bi_end_io = super_written;
 
 
 	atomic_inc(&mddev->pending_writes);
 	atomic_inc(&mddev->pending_writes);
-	submit_bio(REQ_WRITE | REQ_SYNC | REQ_FLUSH | REQ_FUA, bio);
+	submit_bio(WRITE_FLUSH_FUA, bio);
 }
 }
 
 
 void md_super_wait(mddev_t *mddev)
 void md_super_wait(mddev_t *mddev)
@@ -1738,6 +1738,11 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
 	sb->level = cpu_to_le32(mddev->level);
 	sb->level = cpu_to_le32(mddev->level);
 	sb->layout = cpu_to_le32(mddev->layout);
 	sb->layout = cpu_to_le32(mddev->layout);
 
 
+	if (test_bit(WriteMostly, &rdev->flags))
+		sb->devflags |= WriteMostly1;
+	else
+		sb->devflags &= ~WriteMostly1;
+
 	if (mddev->bitmap && mddev->bitmap_info.file == NULL) {
 	if (mddev->bitmap && mddev->bitmap_info.file == NULL) {
 		sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_info.offset);
 		sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_info.offset);
 		sb->feature_map = cpu_to_le32(MD_FEATURE_BITMAP_OFFSET);
 		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)
 	int err = -EINVAL;
 	int err = -EINVAL;
 	if (cmd_match(buf, "faulty") && rdev->mddev->pers) {
 	if (cmd_match(buf, "faulty") && rdev->mddev->pers) {
 		md_error(rdev->mddev, rdev);
 		md_error(rdev->mddev, rdev);
-		err = 0;
+		if (test_bit(Faulty, &rdev->flags))
+			err = 0;
+		else
+			err = -EBUSY;
 	} else if (cmd_match(buf, "remove")) {
 	} else if (cmd_match(buf, "remove")) {
 		if (rdev->raid_disk >= 0)
 		if (rdev->raid_disk >= 0)
 			err = -EBUSY;
 			err = -EBUSY;
@@ -2584,7 +2592,7 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len)
 		err = 0;
 		err = 0;
 	} else if (cmd_match(buf, "-blocked")) {
 	} else if (cmd_match(buf, "-blocked")) {
 		if (!test_bit(Faulty, &rdev->flags) &&
 		if (!test_bit(Faulty, &rdev->flags) &&
-		    test_bit(BlockedBadBlocks, &rdev->flags)) {
+		    rdev->badblocks.unacked_exist) {
 			/* metadata handler doesn't understand badblocks,
 			/* metadata handler doesn't understand badblocks,
 			 * so we need to fail the device
 			 * so we need to fail the device
 			 */
 			 */
@@ -5983,6 +5991,8 @@ static int set_disk_faulty(mddev_t *mddev, dev_t dev)
 		return -ENODEV;
 		return -ENODEV;
 
 
 	md_error(mddev, rdev);
 	md_error(mddev, rdev);
+	if (!test_bit(Faulty, &rdev->flags))
+		return -EBUSY;
 	return 0;
 	return 0;
 }
 }
 
 

+ 1 - 1
drivers/md/raid5.c

@@ -3336,7 +3336,7 @@ static void handle_stripe(struct stripe_head *sh)
 
 
 finish:
 finish:
 	/* wait for this device to become unblocked */
 	/* wait for this device to become unblocked */
-	if (unlikely(s.blocked_rdev))
+	if (conf->mddev->external && unlikely(s.blocked_rdev))
 		md_wait_for_blocked_rdev(s.blocked_rdev, conf->mddev);
 		md_wait_for_blocked_rdev(s.blocked_rdev, conf->mddev);
 
 
 	if (s.handle_bad_blocks)
 	if (s.handle_bad_blocks)