Merge tag 'gfs2-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/steve...
[cascardo/linux.git] / fs / fs-writeback.c
index d754e3c..be568b7 100644 (file)
@@ -89,16 +89,31 @@ static inline struct inode *wb_inode(struct list_head *head)
 #define CREATE_TRACE_POINTS
 #include <trace/events/writeback.h>
 
+EXPORT_TRACEPOINT_SYMBOL_GPL(wbc_writepage);
+
+static void bdi_wakeup_thread(struct backing_dev_info *bdi)
+{
+       spin_lock_bh(&bdi->wb_lock);
+       if (test_bit(BDI_registered, &bdi->state))
+               mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
+       spin_unlock_bh(&bdi->wb_lock);
+}
+
 static void bdi_queue_work(struct backing_dev_info *bdi,
                           struct wb_writeback_work *work)
 {
        trace_writeback_queue(bdi, work);
 
        spin_lock_bh(&bdi->wb_lock);
+       if (!test_bit(BDI_registered, &bdi->state)) {
+               if (work->done)
+                       complete(work->done);
+               goto out_unlock;
+       }
        list_add_tail(&work->list, &bdi->work_list);
-       spin_unlock_bh(&bdi->wb_lock);
-
        mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
+out_unlock:
+       spin_unlock_bh(&bdi->wb_lock);
 }
 
 static void
@@ -114,7 +129,7 @@ __bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages,
        work = kzalloc(sizeof(*work), GFP_ATOMIC);
        if (!work) {
                trace_writeback_nowork(bdi);
-               mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
+               bdi_wakeup_thread(bdi);
                return;
        }
 
@@ -161,7 +176,7 @@ void bdi_start_background_writeback(struct backing_dev_info *bdi)
         * writeback as soon as there is no other work to do.
         */
        trace_writeback_wake_background(bdi);
-       mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
+       bdi_wakeup_thread(bdi);
 }
 
 /*
@@ -1017,7 +1032,7 @@ void bdi_writeback_workfn(struct work_struct *work)
        current->flags |= PF_SWAPWRITE;
 
        if (likely(!current_is_workqueue_rescuer() ||
-                  list_empty(&bdi->bdi_list))) {
+                  !test_bit(BDI_registered, &bdi->state))) {
                /*
                 * The normal path.  Keep writing back @bdi until its
                 * work_list is empty.  Note that this path is also taken
@@ -1039,10 +1054,10 @@ void bdi_writeback_workfn(struct work_struct *work)
                trace_writeback_pages_written(pages_written);
        }
 
-       if (!list_empty(&bdi->work_list) ||
-           (wb_has_dirty_io(wb) && dirty_writeback_interval))
-               queue_delayed_work(bdi_wq, &wb->dwork,
-                       msecs_to_jiffies(dirty_writeback_interval * 10));
+       if (!list_empty(&bdi->work_list))
+               mod_delayed_work(bdi_wq, &wb->dwork, 0);
+       else if (wb_has_dirty_io(wb) && dirty_writeback_interval)
+               bdi_wakeup_thread_delayed(bdi);
 
        current->flags &= ~PF_SWAPWRITE;
 }