|
@@ -775,12 +775,36 @@ long wb_do_writeback(struct bdi_writeback *wb, int force_wait)
|
|
* Handle writeback of dirty data for the device backed by this bdi. Also
|
|
* Handle writeback of dirty data for the device backed by this bdi. Also
|
|
* wakes up periodically and does kupdated style flushing.
|
|
* wakes up periodically and does kupdated style flushing.
|
|
*/
|
|
*/
|
|
-int bdi_writeback_task(struct bdi_writeback *wb)
|
|
|
|
|
|
+int bdi_writeback_thread(void *data)
|
|
{
|
|
{
|
|
|
|
+ struct bdi_writeback *wb = data;
|
|
|
|
+ struct backing_dev_info *bdi = wb->bdi;
|
|
unsigned long last_active = jiffies;
|
|
unsigned long last_active = jiffies;
|
|
unsigned long wait_jiffies = -1UL;
|
|
unsigned long wait_jiffies = -1UL;
|
|
long pages_written;
|
|
long pages_written;
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Add us to the active bdi_list
|
|
|
|
+ */
|
|
|
|
+ spin_lock_bh(&bdi_lock);
|
|
|
|
+ list_add_rcu(&bdi->bdi_list, &bdi_list);
|
|
|
|
+ spin_unlock_bh(&bdi_lock);
|
|
|
|
+
|
|
|
|
+ current->flags |= PF_FLUSHER | PF_SWAPWRITE;
|
|
|
|
+ set_freezable();
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Our parent may run at a different priority, just set us to normal
|
|
|
|
+ */
|
|
|
|
+ set_user_nice(current, 0);
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Clear pending bit and wakeup anybody waiting to tear us down
|
|
|
|
+ */
|
|
|
|
+ clear_bit(BDI_pending, &bdi->state);
|
|
|
|
+ smp_mb__after_clear_bit();
|
|
|
|
+ wake_up_bit(&bdi->state, BDI_pending);
|
|
|
|
+
|
|
while (!kthread_should_stop()) {
|
|
while (!kthread_should_stop()) {
|
|
pages_written = wb_do_writeback(wb, 0);
|
|
pages_written = wb_do_writeback(wb, 0);
|
|
|
|
|
|
@@ -813,9 +837,18 @@ int bdi_writeback_task(struct bdi_writeback *wb)
|
|
try_to_freeze();
|
|
try_to_freeze();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ wb->task = NULL;
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * Flush any work that raced with us exiting. No new work
|
|
|
|
+ * will be added, since this bdi isn't discoverable anymore.
|
|
|
|
+ */
|
|
|
|
+ if (!list_empty(&bdi->work_list))
|
|
|
|
+ wb_do_writeback(wb, 1);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Start writeback of `nr_pages' pages. If `nr_pages' is zero, write back
|
|
* Start writeback of `nr_pages' pages. If `nr_pages' is zero, write back
|
|
* the whole world.
|
|
* the whole world.
|