aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/fs-writeback.c35
-rw-r--r--include/linux/backing-dev.h2
-rw-r--r--mm/backing-dev.c44
3 files changed, 36 insertions, 45 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index d67989b8ba44..c8471b3ddccf 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -775,12 +775,36 @@ long wb_do_writeback(struct bdi_writeback *wb, int force_wait)
775 * Handle writeback of dirty data for the device backed by this bdi. Also 775 * Handle writeback of dirty data for the device backed by this bdi. Also
776 * wakes up periodically and does kupdated style flushing. 776 * wakes up periodically and does kupdated style flushing.
777 */ 777 */
778int bdi_writeback_task(struct bdi_writeback *wb) 778int bdi_writeback_thread(void *data)
779{ 779{
780 struct bdi_writeback *wb = data;
781 struct backing_dev_info *bdi = wb->bdi;
780 unsigned long last_active = jiffies; 782 unsigned long last_active = jiffies;
781 unsigned long wait_jiffies = -1UL; 783 unsigned long wait_jiffies = -1UL;
782 long pages_written; 784 long pages_written;
783 785
786 /*
787 * Add us to the active bdi_list
788 */
789 spin_lock_bh(&bdi_lock);
790 list_add_rcu(&bdi->bdi_list, &bdi_list);
791 spin_unlock_bh(&bdi_lock);
792
793 current->flags |= PF_FLUSHER | PF_SWAPWRITE;
794 set_freezable();
795
796 /*
797 * Our parent may run at a different priority, just set us to normal
798 */
799 set_user_nice(current, 0);
800
801 /*
802 * Clear pending bit and wakeup anybody waiting to tear us down
803 */
804 clear_bit(BDI_pending, &bdi->state);
805 smp_mb__after_clear_bit();
806 wake_up_bit(&bdi->state, BDI_pending);
807
784 while (!kthread_should_stop()) { 808 while (!kthread_should_stop()) {
785 pages_written = wb_do_writeback(wb, 0); 809 pages_written = wb_do_writeback(wb, 0);
786 810
@@ -813,9 +837,18 @@ int bdi_writeback_task(struct bdi_writeback *wb)
813 try_to_freeze(); 837 try_to_freeze();
814 } 838 }
815 839
840 wb->task = NULL;
841
842 /*
843 * Flush any work that raced with us exiting. No new work
844 * will be added, since this bdi isn't discoverable anymore.
845 */
846 if (!list_empty(&bdi->work_list))
847 wb_do_writeback(wb, 1);
816 return 0; 848 return 0;
817} 849}
818 850
851
819/* 852/*
820 * Start writeback of `nr_pages' pages. If `nr_pages' is zero, write back 853 * Start writeback of `nr_pages' pages. If `nr_pages' is zero, write back
821 * the whole world. 854 * the whole world.
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index 50f146146169..e536f3a74e60 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -102,7 +102,7 @@ void bdi_unregister(struct backing_dev_info *bdi);
102int bdi_setup_and_register(struct backing_dev_info *, char *, unsigned int); 102int bdi_setup_and_register(struct backing_dev_info *, char *, unsigned int);
103void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages); 103void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages);
104void bdi_start_background_writeback(struct backing_dev_info *bdi); 104void bdi_start_background_writeback(struct backing_dev_info *bdi);
105int bdi_writeback_task(struct bdi_writeback *wb); 105int bdi_writeback_thread(void *data);
106int bdi_has_dirty_io(struct backing_dev_info *bdi); 106int bdi_has_dirty_io(struct backing_dev_info *bdi);
107void bdi_arm_supers_timer(void); 107void bdi_arm_supers_timer(void);
108 108
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 6c2a09c8922c..bceac647e4d1 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -260,48 +260,6 @@ static void bdi_wb_init(struct bdi_writeback *wb, struct backing_dev_info *bdi)
260 INIT_LIST_HEAD(&wb->b_more_io); 260 INIT_LIST_HEAD(&wb->b_more_io);
261} 261}
262 262
263static int bdi_start_fn(void *ptr)
264{
265 struct bdi_writeback *wb = ptr;
266 struct backing_dev_info *bdi = wb->bdi;
267 int ret;
268
269 /*
270 * Add us to the active bdi_list
271 */
272 spin_lock_bh(&bdi_lock);
273 list_add_rcu(&bdi->bdi_list, &bdi_list);
274 spin_unlock_bh(&bdi_lock);
275
276 current->flags |= PF_FLUSHER | PF_SWAPWRITE;
277 set_freezable();
278
279 /*
280 * Our parent may run at a different priority, just set us to normal
281 */
282 set_user_nice(current, 0);
283
284 /*
285 * Clear pending bit and wakeup anybody waiting to tear us down
286 */
287 clear_bit(BDI_pending, &bdi->state);
288 smp_mb__after_clear_bit();
289 wake_up_bit(&bdi->state, BDI_pending);
290
291 ret = bdi_writeback_task(wb);
292
293 wb->task = NULL;
294
295 /*
296 * Flush any work that raced with us exiting. No new work
297 * will be added, since this bdi isn't discoverable anymore.
298 */
299 if (!list_empty(&bdi->work_list))
300 wb_do_writeback(wb, 1);
301
302 return ret;
303}
304
305int bdi_has_dirty_io(struct backing_dev_info *bdi) 263int bdi_has_dirty_io(struct backing_dev_info *bdi)
306{ 264{
307 return wb_has_dirty_io(&bdi->wb); 265 return wb_has_dirty_io(&bdi->wb);
@@ -425,7 +383,7 @@ static int bdi_forker_task(void *ptr)
425 spin_unlock_bh(&bdi_lock); 383 spin_unlock_bh(&bdi_lock);
426 384
427 wb = &bdi->wb; 385 wb = &bdi->wb;
428 wb->task = kthread_run(bdi_start_fn, wb, "flush-%s", 386 wb->task = kthread_run(bdi_writeback_thread, wb, "flush-%s",
429 dev_name(bdi->dev)); 387 dev_name(bdi->dev));
430 /* 388 /*
431 * If task creation fails, then readd the bdi to 389 * If task creation fails, then readd the bdi to