Three fixes for md
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIVAwUAVIzozznsnt1WYoG5AQKEOQ/9G31KYGhe3/Tn+Hhyy7o16+6fjOBSUN2z 6GCGtOuHhom0Q+y4cdeAohw+eW9bJPqc9tRyRrLnVCuAkeymPP1t7fIRLGAuOHq5 QjjX7ZwKK8urmPAFIxRFgJwrJctFEoaCQiZHk4Pcx9YcYm4paJP2liqqQ0khGPcl KGGjWgD3KMAG0moJzNmLMWBZevG3SLCTirPxOcDJuBkQ7KfP0e4UGVn/UYXdgF+f 73yForADVIE/Jq/CXnsOEZa/nPTM7DIsXZAQqqFCnkUiuCvwhgfkowxhwCExx2d6 w3+I69anD1WII1Z27bNDBgnJGR5xvdiAl6NTJ+GY1uMCo3lnV9OYpQrJxAEJP4dC nXILm6SVm7WLfLvVY1lJm3wZndIyWNmTcDxODGyMZhAY4RmjDHG+AZ9tcnY1pM+9 rt0jHbmaj/ZZ5jKbGxPKBlQ3/U7EP8d4oiruOaDWCGT4sN+e2dbZVLpaWoNaBFUx eyUft+DEvY82ryz2Ktn/Exsx1aWk2Cy3cMl0ELq2L/2WAcjhA6gsikNmKG7tfafn Bd6WIGzAygATaFs4hOtFANyXqWubWi8TgLUHXNYUkJ2JooaMuSIfWrpeMNJyHHU7 5bWTaSZqZ86Ygb6upvJqaA3olePMo1RPBsOev46TnuFT9vtfpzPRy6FlvbXfx8sK M5YCqNpTDTs= =Ar2y -----END PGP SIGNATURE----- Merge tag 'md/3.19' of git://neil.brown.name/md Pull md updates from Neil Brown: "Three fixes for md. I did have a largish set of locking changes queued, but late testing showed they weren't quite as stable as I thought and while I fixed what I found, I decided it safer to delay them a release ... particularly as I'll be AFK for a few weeks. So expect a larger batch next time :-)" * tag 'md/3.19' of git://neil.brown.name/md: md: Check MD_RECOVERY_RUNNING as well as ->sync_thread. md: fix semicolon.cocci warnings md/raid5: fetch_block must fetch all the blocks handle_stripe_dirtying wants.
This commit is contained in:
commit
8fd9589ced
2 changed files with 32 additions and 13 deletions
|
@ -2691,7 +2691,8 @@ static ssize_t new_offset_store(struct md_rdev *rdev,
|
|||
if (kstrtoull(buf, 10, &new_offset) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (mddev->sync_thread)
|
||||
if (mddev->sync_thread ||
|
||||
test_bit(MD_RECOVERY_RUNNING,&mddev->recovery))
|
||||
return -EBUSY;
|
||||
if (new_offset == rdev->data_offset)
|
||||
/* reset is always permitted */
|
||||
|
@ -3268,6 +3269,7 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
|
|||
*/
|
||||
|
||||
if (mddev->sync_thread ||
|
||||
test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
|
||||
mddev->reshape_position != MaxSector ||
|
||||
mddev->sysfs_active)
|
||||
return -EBUSY;
|
||||
|
@ -4022,6 +4024,7 @@ action_store(struct mddev *mddev, const char *page, size_t len)
|
|||
clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
|
||||
|
||||
if (cmd_match(page, "idle") || cmd_match(page, "frozen")) {
|
||||
flush_workqueue(md_misc_wq);
|
||||
if (mddev->sync_thread) {
|
||||
set_bit(MD_RECOVERY_INTR, &mddev->recovery);
|
||||
md_reap_sync_thread(mddev);
|
||||
|
@ -5040,6 +5043,7 @@ static void md_clean(struct mddev *mddev)
|
|||
static void __md_stop_writes(struct mddev *mddev)
|
||||
{
|
||||
set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
|
||||
flush_workqueue(md_misc_wq);
|
||||
if (mddev->sync_thread) {
|
||||
set_bit(MD_RECOVERY_INTR, &mddev->recovery);
|
||||
md_reap_sync_thread(mddev);
|
||||
|
@ -5100,19 +5104,22 @@ static int md_set_readonly(struct mddev *mddev, struct block_device *bdev)
|
|||
set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
|
||||
md_wakeup_thread(mddev->thread);
|
||||
}
|
||||
if (mddev->sync_thread) {
|
||||
if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
|
||||
set_bit(MD_RECOVERY_INTR, &mddev->recovery);
|
||||
if (mddev->sync_thread)
|
||||
/* Thread might be blocked waiting for metadata update
|
||||
* which will now never happen */
|
||||
wake_up_process(mddev->sync_thread->tsk);
|
||||
}
|
||||
|
||||
mddev_unlock(mddev);
|
||||
wait_event(resync_wait, mddev->sync_thread == NULL);
|
||||
wait_event(resync_wait, !test_bit(MD_RECOVERY_RUNNING,
|
||||
&mddev->recovery));
|
||||
mddev_lock_nointr(mddev);
|
||||
|
||||
mutex_lock(&mddev->open_mutex);
|
||||
if ((mddev->pers && atomic_read(&mddev->openers) > !!bdev) ||
|
||||
mddev->sync_thread ||
|
||||
test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
|
||||
(bdev && !test_bit(MD_STILL_CLOSED, &mddev->flags))) {
|
||||
printk("md: %s still in use.\n",mdname(mddev));
|
||||
if (did_freeze) {
|
||||
|
@ -5158,20 +5165,24 @@ static int do_md_stop(struct mddev *mddev, int mode,
|
|||
set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
|
||||
md_wakeup_thread(mddev->thread);
|
||||
}
|
||||
if (mddev->sync_thread) {
|
||||
if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery))
|
||||
set_bit(MD_RECOVERY_INTR, &mddev->recovery);
|
||||
if (mddev->sync_thread)
|
||||
/* Thread might be blocked waiting for metadata update
|
||||
* which will now never happen */
|
||||
wake_up_process(mddev->sync_thread->tsk);
|
||||
}
|
||||
|
||||
mddev_unlock(mddev);
|
||||
wait_event(resync_wait, mddev->sync_thread == NULL);
|
||||
wait_event(resync_wait, (mddev->sync_thread == NULL &&
|
||||
!test_bit(MD_RECOVERY_RUNNING,
|
||||
&mddev->recovery)));
|
||||
mddev_lock_nointr(mddev);
|
||||
|
||||
mutex_lock(&mddev->open_mutex);
|
||||
if ((mddev->pers && atomic_read(&mddev->openers) > !!bdev) ||
|
||||
mddev->sysfs_active ||
|
||||
mddev->sync_thread ||
|
||||
test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
|
||||
(bdev && !test_bit(MD_STILL_CLOSED, &mddev->flags))) {
|
||||
printk("md: %s still in use.\n",mdname(mddev));
|
||||
mutex_unlock(&mddev->open_mutex);
|
||||
|
@ -5946,7 +5957,8 @@ static int update_size(struct mddev *mddev, sector_t num_sectors)
|
|||
* of each device. If num_sectors is zero, we find the largest size
|
||||
* that fits.
|
||||
*/
|
||||
if (mddev->sync_thread)
|
||||
if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
|
||||
mddev->sync_thread)
|
||||
return -EBUSY;
|
||||
if (mddev->ro)
|
||||
return -EROFS;
|
||||
|
@ -5977,7 +5989,9 @@ static int update_raid_disks(struct mddev *mddev, int raid_disks)
|
|||
if (raid_disks <= 0 ||
|
||||
(mddev->max_disks && raid_disks >= mddev->max_disks))
|
||||
return -EINVAL;
|
||||
if (mddev->sync_thread || mddev->reshape_position != MaxSector)
|
||||
if (mddev->sync_thread ||
|
||||
test_bit(MD_RECOVERY_RUNNING, &mddev->recovery) ||
|
||||
mddev->reshape_position != MaxSector)
|
||||
return -EBUSY;
|
||||
|
||||
rdev_for_each(rdev, mddev) {
|
||||
|
@ -6965,7 +6979,7 @@ static unsigned int mdstat_poll(struct file *filp, poll_table *wait)
|
|||
int mask;
|
||||
|
||||
if (md_unloading)
|
||||
return POLLIN|POLLRDNORM|POLLERR|POLLPRI;;
|
||||
return POLLIN|POLLRDNORM|POLLERR|POLLPRI;
|
||||
poll_wait(filp, &md_event_waiters, wait);
|
||||
|
||||
/* always allow read */
|
||||
|
@ -7589,6 +7603,7 @@ static void md_start_sync(struct work_struct *ws)
|
|||
clear_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
|
||||
clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
|
||||
clear_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
|
||||
wake_up(&resync_wait);
|
||||
if (test_and_clear_bit(MD_RECOVERY_RECOVER,
|
||||
&mddev->recovery))
|
||||
if (mddev->sysfs_action)
|
||||
|
@ -7757,6 +7772,7 @@ void md_check_recovery(struct mddev *mddev)
|
|||
not_running:
|
||||
if (!mddev->sync_thread) {
|
||||
clear_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
|
||||
wake_up(&resync_wait);
|
||||
if (test_and_clear_bit(MD_RECOVERY_RECOVER,
|
||||
&mddev->recovery))
|
||||
if (mddev->sysfs_action)
|
||||
|
@ -7775,7 +7791,6 @@ void md_reap_sync_thread(struct mddev *mddev)
|
|||
|
||||
/* resync has finished, collect result */
|
||||
md_unregister_thread(&mddev->sync_thread);
|
||||
wake_up(&resync_wait);
|
||||
if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery) &&
|
||||
!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
|
||||
/* success...*/
|
||||
|
@ -7803,6 +7818,7 @@ void md_reap_sync_thread(struct mddev *mddev)
|
|||
clear_bit(MD_RECOVERY_RESHAPE, &mddev->recovery);
|
||||
clear_bit(MD_RECOVERY_REQUESTED, &mddev->recovery);
|
||||
clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
|
||||
wake_up(&resync_wait);
|
||||
/* flag recovery needed just to double check */
|
||||
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
|
||||
sysfs_notify_dirent_safe(mddev->sysfs_action);
|
||||
|
|
|
@ -2917,8 +2917,11 @@ static int fetch_block(struct stripe_head *sh, struct stripe_head_state *s,
|
|||
(sh->raid_conf->level <= 5 && s->failed && fdev[0]->towrite &&
|
||||
(!test_bit(R5_Insync, &dev->flags) || test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) &&
|
||||
!test_bit(R5_OVERWRITE, &fdev[0]->flags)) ||
|
||||
(sh->raid_conf->level == 6 && s->failed && s->to_write &&
|
||||
s->to_write - s->non_overwrite < sh->raid_conf->raid_disks - 2 &&
|
||||
((sh->raid_conf->level == 6 ||
|
||||
sh->sector >= sh->raid_conf->mddev->recovery_cp)
|
||||
&& s->failed && s->to_write &&
|
||||
(s->to_write - s->non_overwrite <
|
||||
sh->raid_conf->raid_disks - sh->raid_conf->max_degraded) &&
|
||||
(!test_bit(R5_Insync, &dev->flags) || test_bit(STRIPE_PREREAD_ACTIVE, &sh->state))))) {
|
||||
/* we would like to get this block, possibly by computing it,
|
||||
* otherwise read it if the backing disk is insync
|
||||
|
|
Loading…
Reference in a new issue