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 | |||
811 | spin_unlock(&head->batch_head->batch_lock); | 811 | spin_unlock(&head->batch_head->batch_lock); |
812 | goto unlock_out; | 812 | goto unlock_out; |
813 | } | 813 | } |
814 | /* | ||
815 | * We must assign batch_head of this stripe within the | ||
816 | * batch_lock, otherwise clear_batch_ready of batch head | ||
817 | * stripe could clear BATCH_READY bit of this stripe and | ||
818 | * this stripe->batch_head doesn't get assigned, which | ||
819 | * could confuse clear_batch_ready for this stripe | ||
820 | */ | ||
821 | sh->batch_head = head->batch_head; | ||
814 | 822 | ||
815 | /* | 823 | /* |
816 | * at this point, head's BATCH_READY could be cleared, but we | 824 | * 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 | |||
818 | */ | 826 | */ |
819 | list_add(&sh->batch_list, &head->batch_list); | 827 | list_add(&sh->batch_list, &head->batch_list); |
820 | spin_unlock(&head->batch_head->batch_lock); | 828 | spin_unlock(&head->batch_head->batch_lock); |
821 | |||
822 | sh->batch_head = head->batch_head; | ||
823 | } else { | 829 | } else { |
824 | head->batch_head = head; | 830 | head->batch_head = head; |
825 | sh->batch_head = head->batch_head; | 831 | sh->batch_head = head->batch_head; |
@@ -4599,7 +4605,8 @@ static void break_stripe_batch_list(struct stripe_head *head_sh, | |||
4599 | 4605 | ||
4600 | set_mask_bits(&sh->state, ~(STRIPE_EXPAND_SYNC_FLAGS | | 4606 | set_mask_bits(&sh->state, ~(STRIPE_EXPAND_SYNC_FLAGS | |
4601 | (1 << STRIPE_PREREAD_ACTIVE) | | 4607 | (1 << STRIPE_PREREAD_ACTIVE) | |
4602 | (1 << STRIPE_DEGRADED)), | 4608 | (1 << STRIPE_DEGRADED) | |
4609 | (1 << STRIPE_ON_UNPLUG_LIST)), | ||
4603 | head_sh->state & (1 << STRIPE_INSYNC)); | 4610 | head_sh->state & (1 << STRIPE_INSYNC)); |
4604 | 4611 | ||
4605 | sh->check_state = head_sh->check_state; | 4612 | sh->check_state = head_sh->check_state; |
@@ -6568,14 +6575,17 @@ static ssize_t | |||
6568 | raid5_store_group_thread_cnt(struct mddev *mddev, const char *page, size_t len) | 6575 | raid5_store_group_thread_cnt(struct mddev *mddev, const char *page, size_t len) |
6569 | { | 6576 | { |
6570 | struct r5conf *conf; | 6577 | struct r5conf *conf; |
6571 | unsigned long new; | 6578 | unsigned int new; |
6572 | int err; | 6579 | int err; |
6573 | struct r5worker_group *new_groups, *old_groups; | 6580 | struct r5worker_group *new_groups, *old_groups; |
6574 | int group_cnt, worker_cnt_per_group; | 6581 | int group_cnt, worker_cnt_per_group; |
6575 | 6582 | ||
6576 | if (len >= PAGE_SIZE) | 6583 | if (len >= PAGE_SIZE) |
6577 | return -EINVAL; | 6584 | return -EINVAL; |
6578 | if (kstrtoul(page, 10, &new)) | 6585 | if (kstrtouint(page, 10, &new)) |
6586 | return -EINVAL; | ||
6587 | /* 8192 should be big enough */ | ||
6588 | if (new > 8192) | ||
6579 | return -EINVAL; | 6589 | return -EINVAL; |
6580 | 6590 | ||
6581 | err = mddev_lock(mddev); | 6591 | err = mddev_lock(mddev); |