diff options
Diffstat (limited to 'drivers/md/raid5.c')
| -rw-r--r-- | drivers/md/raid5.c | 20 | 
1 files changed, 15 insertions, 5 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 4188a4881148..928e24a07133 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -811,6 +811,14 @@ static void stripe_add_to_batch_list(struct r5conf *conf, struct stripe_head *sh  			spin_unlock(&head->batch_head->batch_lock);  			goto unlock_out;  		} +		/* +		 * We must assign batch_head of this stripe within the +		 * batch_lock, otherwise clear_batch_ready of batch head +		 * stripe could clear BATCH_READY bit of this stripe and +		 * this stripe->batch_head doesn't get assigned, which +		 * could confuse clear_batch_ready for this stripe +		 */ +		sh->batch_head = head->batch_head;  		/*  		 * at this point, head's BATCH_READY could be cleared, but we @@ -818,8 +826,6 @@ static void stripe_add_to_batch_list(struct r5conf *conf, struct stripe_head *sh  		 */  		list_add(&sh->batch_list, &head->batch_list);  		spin_unlock(&head->batch_head->batch_lock); - -		sh->batch_head = head->batch_head;  	} else {  		head->batch_head = head;  		sh->batch_head = head->batch_head; @@ -4599,7 +4605,8 @@ static void break_stripe_batch_list(struct stripe_head *head_sh,  		set_mask_bits(&sh->state, ~(STRIPE_EXPAND_SYNC_FLAGS |  					    (1 << STRIPE_PREREAD_ACTIVE) | -					    (1 << STRIPE_DEGRADED)), +					    (1 << STRIPE_DEGRADED) | +					    (1 << STRIPE_ON_UNPLUG_LIST)),  			      head_sh->state & (1 << STRIPE_INSYNC));  		sh->check_state = head_sh->check_state; @@ -6568,14 +6575,17 @@ static ssize_t  raid5_store_group_thread_cnt(struct mddev *mddev, const char *page, size_t len)  {  	struct r5conf *conf; -	unsigned long new; +	unsigned int new;  	int err;  	struct r5worker_group *new_groups, *old_groups;  	int group_cnt, worker_cnt_per_group;  	if (len >= PAGE_SIZE)  		return -EINVAL; -	if (kstrtoul(page, 10, &new)) +	if (kstrtouint(page, 10, &new)) +		return -EINVAL; +	/* 8192 should be big enough */ +	if (new > 8192)  		return -EINVAL;  	err = mddev_lock(mddev);  |