Re: [RFC PATCH 1/5] md: add helpers for requested sync action

Li Nan <[email protected]>
Newsgroups gmane.linux.raid,gmane.linux.kernel
Message-ID <[email protected]>

在 2025/12/31 15:09, Zheng Qixing 写道:
> From: Zheng Qixing <[email protected]>
> 
> Add helpers for handling requested sync action.
> 
> In handle_requested_sync_action(), add mutual exclusivity checks between
> check/repair operations. This prevents the scenario where one operation
> is requested, but before MD_RECOVERY_RUNNING is set, another operation is
> requested, resulting in neither an EBUSY return nor proper execution of
> the second operation.
> 
> Signed-off-by: Zheng Qixing <[email protected]>
> ---
>   drivers/md/md.c | 87 +++++++++++++++++++++++++++++++++++++------------
>   1 file changed, 66 insertions(+), 21 deletions(-)
> 
> diff --git a/drivers/md/md.c b/drivers/md/md.c
> index 5df2220b1bd1..ccaa2e6fe079 100644
> --- a/drivers/md/md.c
> +++ b/drivers/md/md.c
> @@ -665,6 +665,59 @@ void mddev_put(struct mddev *mddev)
>   	spin_unlock(&all_mddevs_lock);
>   }
>   
> +static int __handle_requested_sync_action(struct mddev *mddev,
> +					  enum sync_action action)
> +{
> +	switch (action) {
> +	case ACTION_CHECK:
> +		set_bit(MD_RECOVERY_CHECK, &mddev->recovery);
> +		fallthrough;
> +	case ACTION_REPAIR:
> +		set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
> +		set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
> +		return 0;
> +	default:
> +		return -EINVAL;
> +	} > +}
> +
> +static int handle_requested_sync_action(struct mddev *mddev,
> +					enum sync_action action)
> +{
> +	if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
> +		return -EBUSY;

This return change origin logic; split factor out and fix into two patches.

> +	return __handle_requested_sync_action(mddev, action);
> +}
> +

__handle_requested_sync_action does not need to be split.

> +static enum sync_action __get_recovery_sync_action(struct mddev *mddev)
> +{
> +	if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery))
> +		return ACTION_CHECK;
> +	if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
> +		return ACTION_REPAIR;
> +	return ACTION_RESYNC;
> +}
> +
> +static enum sync_action get_recovery_sync_action(struct mddev *mddev)
> +{
> +	return __get_recovery_sync_action(mddev);
> +}
> +

__get_recovery_sync_action also does not need to be split.


> +static void init_recovery_position(struct mddev *mddev)
> +{
> +	mddev->resync_min = 0;
> +}
> +
> +static void set_requested_position(struct mddev *mddev, sector_t value)
> +{
> +	mddev->resync_min = value;
> +}
> +
> +static sector_t get_requested_position(struct mddev *mddev)
> +{
> +	return mddev->resync_min;
> +}
> +

There is no need to factor the operations of resync_min;
'rectify_min' that follows can re-use 'resync_min' directly.

>   static void md_safemode_timeout(struct timer_list *t);
>   static void md_start_sync(struct work_struct *ws);
>   
> @@ -781,7 +834,7 @@ int mddev_init(struct mddev *mddev)
>   	mddev->reshape_position = MaxSector;
>   	mddev->reshape_backwards = 0;
>   	mddev->last_sync_action = ACTION_IDLE;
> -	mddev->resync_min = 0;
> +	init_recovery_position(mddev);
>   	mddev->resync_max = MaxSector;
>   	mddev->level = LEVEL_NONE;
>   
> @@ -5101,17 +5154,9 @@ enum sync_action md_sync_action(struct mddev *mddev)
>   	if (test_bit(MD_RECOVERY_RECOVER, &recovery))
>   		return ACTION_RECOVER;
>   
> -	if (test_bit(MD_RECOVERY_SYNC, &recovery)) {
> -		/*
> -		 * MD_RECOVERY_CHECK must be paired with
> -		 * MD_RECOVERY_REQUESTED.
> -		 */
> -		if (test_bit(MD_RECOVERY_CHECK, &recovery))
> -			return ACTION_CHECK;
> -		if (test_bit(MD_RECOVERY_REQUESTED, &recovery))
> -			return ACTION_REPAIR;
> -		return ACTION_RESYNC;
> -	}
> +	/* MD_RECOVERY_CHECK must be paired with MD_RECOVERY_REQUESTED. */
> +	if (test_bit(MD_RECOVERY_SYNC, &recovery))
> +		return get_recovery_sync_action(mddev);
>   
>   	/*
>   	 * MD_RECOVERY_NEEDED or MD_RECOVERY_RUNNING is set, however, no
> @@ -5300,11 +5345,10 @@ action_store(struct mddev *mddev, const char *page, size_t len)
>   			set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
>   			break;
>   		case ACTION_CHECK:
> -			set_bit(MD_RECOVERY_CHECK, &mddev->recovery);
> -			fallthrough;
>   		case ACTION_REPAIR:
> -			set_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
> -			set_bit(MD_RECOVERY_SYNC, &mddev->recovery);
> +			ret = handle_requested_sync_action(mddev, action);
> +			if (ret)
> +				goto out;
>   			fallthrough;
>   		case ACTION_RESYNC:
>   		case ACTION_IDLE:
> @@ -6783,7 +6827,7 @@ static void md_clean(struct mddev *mddev)
>   	mddev->dev_sectors = 0;
>   	mddev->raid_disks = 0;
>   	mddev->resync_offset = 0;
> -	mddev->resync_min = 0;
> +	init_recovery_position(mddev);
>   	mddev->resync_max = MaxSector;
>   	mddev->reshape_position = MaxSector;
>   	/* we still need mddev->external in export_rdev, do not clear it yet */
> @@ -9370,7 +9414,7 @@ static sector_t md_sync_position(struct mddev *mddev, enum sync_action action)
>   	switch (action) {
>   	case ACTION_CHECK:
>   	case ACTION_REPAIR:
> -		return mddev->resync_min;
> +		return get_requested_position(mddev);
>   	case ACTION_RESYNC:
>   		if (!mddev->bitmap)
>   			return mddev->resync_offset;
> @@ -9795,10 +9839,11 @@ void md_do_sync(struct md_thread *thread)
>   	if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
>   		/* We completed so min/max setting can be forgotten if used. */
>   		if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
> -			mddev->resync_min = 0;
> +			set_requested_position(mddev, 0);
>   		mddev->resync_max = MaxSector;
> -	} else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
> -		mddev->resync_min = mddev->curr_resync_completed;
> +	} else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
> +		set_requested_position(mddev, mddev->curr_resync_completed);
> +	}
>   	set_bit(MD_RECOVERY_DONE, &mddev->recovery);
>   	mddev->curr_resync = MD_RESYNC_NONE;
>   	spin_unlock(&mddev->lock);

-- 
Thanks,
Nan
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.