aboutsummaryrefslogtreecommitdiffstats
path: root/mm/backing-dev.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/backing-dev.c')
-rw-r--r--mm/backing-dev.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 1065b715ef64..67a33a5a1a93 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -604,10 +604,14 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi)
604 604
605 /* 605 /*
606 * Finally, kill the kernel threads. We don't need to be RCU 606 * Finally, kill the kernel threads. We don't need to be RCU
607 * safe anymore, since the bdi is gone from visibility. 607 * safe anymore, since the bdi is gone from visibility. Force
608 * unfreeze of the thread before calling kthread_stop(), otherwise
609 * it would never exet if it is currently stuck in the refrigerator.
608 */ 610 */
609 list_for_each_entry(wb, &bdi->wb_list, list) 611 list_for_each_entry(wb, &bdi->wb_list, list) {
612 wb->task->flags &= ~PF_FROZEN;
610 kthread_stop(wb->task); 613 kthread_stop(wb->task);
614 }
611} 615}
612 616
613/* 617/*
@@ -628,6 +632,8 @@ static void bdi_prune_sb(struct backing_dev_info *bdi)
628void bdi_unregister(struct backing_dev_info *bdi) 632void bdi_unregister(struct backing_dev_info *bdi)
629{ 633{
630 if (bdi->dev) { 634 if (bdi->dev) {
635 bdi_prune_sb(bdi);
636
631 if (!bdi_cap_flush_forker(bdi)) 637 if (!bdi_cap_flush_forker(bdi))
632 bdi_wb_shutdown(bdi); 638 bdi_wb_shutdown(bdi);
633 bdi_debug_unregister(bdi); 639 bdi_debug_unregister(bdi);
@@ -697,7 +703,6 @@ void bdi_destroy(struct backing_dev_info *bdi)
697 spin_unlock(&inode_lock); 703 spin_unlock(&inode_lock);
698 } 704 }
699 705
700 bdi_prune_sb(bdi);
701 bdi_unregister(bdi); 706 bdi_unregister(bdi);
702 707
703 for (i = 0; i < NR_BDI_STAT_ITEMS; i++) 708 for (i = 0; i < NR_BDI_STAT_ITEMS; i++)