diff options
-rw-r--r-- | fs/fs-writeback.c | 35 | ||||
-rw-r--r-- | include/linux/backing-dev.h | 2 | ||||
-rw-r--r-- | mm/backing-dev.c | 44 |
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 | */ |
778 | int bdi_writeback_task(struct bdi_writeback *wb) | 778 | int 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); | |||
102 | int bdi_setup_and_register(struct backing_dev_info *, char *, unsigned int); | 102 | int bdi_setup_and_register(struct backing_dev_info *, char *, unsigned int); |
103 | void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages); | 103 | void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages); |
104 | void bdi_start_background_writeback(struct backing_dev_info *bdi); | 104 | void bdi_start_background_writeback(struct backing_dev_info *bdi); |
105 | int bdi_writeback_task(struct bdi_writeback *wb); | 105 | int bdi_writeback_thread(void *data); |
106 | int bdi_has_dirty_io(struct backing_dev_info *bdi); | 106 | int bdi_has_dirty_io(struct backing_dev_info *bdi); |
107 | void bdi_arm_supers_timer(void); | 107 | void 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 | ||
263 | static 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 | |||
305 | int bdi_has_dirty_io(struct backing_dev_info *bdi) | 263 | int 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 |