aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/md.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2010-03-28 21:07:53 -0400
committerNeilBrown <neilb@suse.de>2010-05-18 01:27:54 -0400
commita047e125403112ceb4d41e68307a2e7498ddba4e (patch)
tree392928f408e3a6a2d40a7c3b6a178fbb3c411e06 /drivers/md/md.c
parent6177b472ab14e1ac88896960370dd54ba577d926 (diff)
md: factor md_stop_writes out of do_md_stop.
Further refactoring of do_md_stop. This one requires some explanation as it takes code from different places in do_md_stop, so some re-ordering happens. We only get into this part of do_md_stop if there are no active opens of the device, so no writes can be happening and the device must have been flushed. In md_stop_writes we want to stop any internal sources of writes - i.e. resync - and flush out the metadata. The only code that was previously before some of this code is code to clean up the queue, the mddev, the gendisk, or sysfs, all of which is probably better after code that makes active changes (i.e. triggers writes). Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r--drivers/md/md.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 002d0a34d6ea..86dfbc361cc0 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -4610,6 +4610,27 @@ static void md_clean(mddev_t *mddev)
4610 mddev->bitmap_info.max_write_behind = 0; 4610 mddev->bitmap_info.max_write_behind = 0;
4611} 4611}
4612 4612
4613static void md_stop_writes(mddev_t *mddev)
4614{
4615 if (mddev->sync_thread) {
4616 set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
4617 set_bit(MD_RECOVERY_INTR, &mddev->recovery);
4618 md_unregister_thread(mddev->sync_thread);
4619 mddev->sync_thread = NULL;
4620 }
4621
4622 del_timer_sync(&mddev->safemode_timer);
4623
4624 bitmap_flush(mddev);
4625 md_super_wait(mddev);
4626
4627 if (!mddev->in_sync || mddev->flags) {
4628 /* mark array as shutdown cleanly */
4629 mddev->in_sync = 1;
4630 md_update_sb(mddev, 1);
4631 }
4632}
4633
4613static void md_stop(mddev_t *mddev) 4634static void md_stop(mddev_t *mddev)
4614{ 4635{
4615 mddev->pers->stop(mddev); 4636 mddev->pers->stop(mddev);
@@ -4637,14 +4658,7 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
4637 err = -EBUSY; 4658 err = -EBUSY;
4638 } else if (mddev->pers) { 4659 } else if (mddev->pers) {
4639 4660
4640 if (mddev->sync_thread) { 4661 md_stop_writes(mddev);
4641 set_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
4642 set_bit(MD_RECOVERY_INTR, &mddev->recovery);
4643 md_unregister_thread(mddev->sync_thread);
4644 mddev->sync_thread = NULL;
4645 }
4646
4647 del_timer_sync(&mddev->safemode_timer);
4648 4662
4649 switch(mode) { 4663 switch(mode) {
4650 case 1: /* readonly */ 4664 case 1: /* readonly */
@@ -4655,8 +4669,6 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
4655 break; 4669 break;
4656 case 0: /* disassemble */ 4670 case 0: /* disassemble */
4657 case 2: /* stop */ 4671 case 2: /* stop */
4658 bitmap_flush(mddev);
4659 md_super_wait(mddev);
4660 if (mddev->ro) 4672 if (mddev->ro)
4661 set_disk_ro(disk, 0); 4673 set_disk_ro(disk, 0);
4662 4674
@@ -4681,11 +4693,6 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
4681 if (mddev->ro) 4693 if (mddev->ro)
4682 mddev->ro = 0; 4694 mddev->ro = 0;
4683 } 4695 }
4684 if (!mddev->in_sync || mddev->flags) {
4685 /* mark array as shutdown cleanly */
4686 mddev->in_sync = 1;
4687 md_update_sb(mddev, 1);
4688 }
4689 if (mode == 1) 4696 if (mode == 1)
4690 set_disk_ro(disk, 1); 4697 set_disk_ro(disk, 1);
4691 clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery); 4698 clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);