[PATCH v3 1/2] md: add a new entry .disk_is_spare in super_types

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



.disk_is_spare would read superblock info and check disk state.
If the disk is in 'spare', return 1. Otherwise, return 0.
If superblock read fail or sb info is invalid , return error code.

Signed-off-by: Yufen Yu <yuyufen@xxxxxxxxxx>
---
 drivers/md/md.c | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 24638ccedce4..b890678f225c 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1065,6 +1065,8 @@ struct super_type  {
 						sector_t num_sectors);
 	int		    (*allow_new_offset)(struct md_rdev *rdev,
 						unsigned long long new_offset);
+	int			(*disk_is_spare) (struct mddev *mddev,
+						struct md_rdev *rdev);
 };
 
 /*
@@ -1484,6 +1486,24 @@ super_90_allow_new_offset(struct md_rdev *rdev, unsigned long long new_offset)
 	return new_offset == 0;
 }
 
+static int super_90_disk_is_spare(struct mddev *mddev, struct md_rdev *rdev)
+{
+	int ret;
+	mdp_super_t *sb;
+
+	ret = super_90_load(rdev, NULL, mddev->minor_version);
+	if (ret < 0)
+		return ret;
+
+	sb = page_address(rdev->sb_page);
+
+	if (sb->disks[rdev->desc_nr].state &
+		((1<<MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE)))
+		return 0;
+
+	return 1;
+}
+
 /*
  * version 1 superblock
  */
@@ -2084,6 +2104,26 @@ super_1_allow_new_offset(struct md_rdev *rdev,
 	return 1;
 }
 
+static int super_1_disk_is_spare(struct mddev *mddev, struct md_rdev *rdev)
+{
+	int ret;
+	struct mdp_superblock_1 *sb;
+
+	ret = super_1_load(rdev, NULL, mddev->minor_version);
+	if (ret < 0)
+		return ret;
+
+	sb = page_address(rdev->sb_page);
+
+	if (rdev->desc_nr >= 0 &&
+		rdev->desc_nr < le32_to_cpu(sb->max_dev) &&
+		(le16_to_cpu(sb->dev_roles[rdev->desc_nr]) < MD_DISK_ROLE_MAX ||
+		le16_to_cpu(sb->dev_roles[rdev->desc_nr]) == MD_DISK_ROLE_JOURNAL))
+		return 0;
+
+	return 1;
+}
+
 static struct super_type super_types[] = {
 	[0] = {
 		.name	= "0.90.0",
@@ -2093,6 +2133,7 @@ static struct super_type super_types[] = {
 		.sync_super	    = super_90_sync,
 		.rdev_size_change   = super_90_rdev_size_change,
 		.allow_new_offset   = super_90_allow_new_offset,
+		.disk_is_spare		= super_90_disk_is_spare,
 	},
 	[1] = {
 		.name	= "md-1",
@@ -2102,6 +2143,7 @@ static struct super_type super_types[] = {
 		.sync_super	    = super_1_sync,
 		.rdev_size_change   = super_1_rdev_size_change,
 		.allow_new_offset   = super_1_allow_new_offset,
+		.disk_is_spare		= super_1_disk_is_spare,
 	},
 };
 
-- 
2.17.2




[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux