.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