Re: [md PATCH] md: handle read-only member devices better.

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

 



On Thu, Apr 13, 2017 at 08:53:48AM +1000, Neil Brown wrote:
> 
> 1/ If an array has any read-only devices when it is started,
>    the array itself must be read-only
> 2/ A read-only device cannot be added to an array after it is
>    started.
> 3/ Setting an array to read-write should not succeed
>    if any member devices are read-only

Didn't get these. We call md_import_device() first to open under layer disk. We
always use FMOD_READ|FMOD_WRITE to open the disk. So if the disk is ro,
md_import_device should fail, we don't add the disk to the array. Why would we
have such issues?

Thanks,
Shaohua
 
> Reported-and-Tested-by: Nanda Kishore Chinnaram <Nanda_Kishore_Chinna@xxxxxxxx>
> Signed-off-by: NeilBrown <neilb@xxxxxxxx>
> ---
>  drivers/md/md.c | 41 ++++++++++++++++++++++++++---------------
>  1 file changed, 26 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/md/md.c b/drivers/md/md.c
> index 22894303d335..9fe930109012 100644
> --- a/drivers/md/md.c
> +++ b/drivers/md/md.c
> @@ -2093,6 +2093,10 @@ static int bind_rdev_to_array(struct md_rdev *rdev, struct mddev *mddev)
>  	if (find_rdev(mddev, rdev->bdev->bd_dev))
>  		return -EEXIST;
>  
> +	if ((bdev_read_only(rdev->bdev) || bdev_read_only(rdev->meta_bdev)) &&
> +	    mddev->pers)
> +		return -EROFS;
> +
>  	/* make sure rdev->sectors exceeds mddev->dev_sectors */
>  	if (!test_bit(Journal, &rdev->flags) &&
>  	    rdev->sectors &&
> @@ -5345,6 +5349,13 @@ int md_run(struct mddev *mddev)
>  			continue;
>  		sync_blockdev(rdev->bdev);
>  		invalidate_bdev(rdev->bdev);
> +		if (mddev->ro != 1 &&
> +		    (bdev_read_only(rdev->bdev) ||
> +		     bdev_read_only(rdev->meta_bdev))) {
> +			mddev->ro = 1;
> +			if (mddev->gendisk)
> +				set_disk_ro(mddev->gendisk, 1);
> +		}
>  
>  		/* perform some consistency tests on the device.
>  		 * We don't want the data to overlap the metadata,
> @@ -5569,6 +5580,9 @@ static int do_md_run(struct mddev *mddev)
>  static int restart_array(struct mddev *mddev)
>  {
>  	struct gendisk *disk = mddev->gendisk;
> +	struct md_rdev *rdev;
> +	bool has_journal = false;
> +	bool has_readonly = false;
>  
>  	/* Complain if it has no devices */
>  	if (list_empty(&mddev->disks))
> @@ -5577,24 +5591,21 @@ static int restart_array(struct mddev *mddev)
>  		return -EINVAL;
>  	if (!mddev->ro)
>  		return -EBUSY;
> -	if (test_bit(MD_HAS_JOURNAL, &mddev->flags)) {
> -		struct md_rdev *rdev;
> -		bool has_journal = false;
> -
> -		rcu_read_lock();
> -		rdev_for_each_rcu(rdev, mddev) {
> -			if (test_bit(Journal, &rdev->flags) &&
> -			    !test_bit(Faulty, &rdev->flags)) {
> -				has_journal = true;
> -				break;
> -			}
> -		}
> -		rcu_read_unlock();
>  
> +	rcu_read_lock();
> +	rdev_for_each_rcu(rdev, mddev) {
> +		if (test_bit(Journal, &rdev->flags) &&
> +		    !test_bit(Faulty, &rdev->flags))
> +			has_journal = true;
> +		if (bdev_read_only(rdev->bdev))
> +			has_readonly = true;
> +	}
> +	rcu_read_unlock();
> +	if (test_bit(MD_HAS_JOURNAL, &mddev->flags) && !has_journal)
>  		/* Don't restart rw with journal missing/faulty */
> -		if (!has_journal)
>  			return -EINVAL;
> -	}
> +	if (has_readonly)
> +		return -EROFS;
>  
>  	mddev->safemode = 0;
>  	mddev->ro = 0;
> -- 
> 2.12.2
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[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