Merge remote-tracking branch 'lsk/v3.10/topic/gator' into linux-linaro-lsk
[firefly-linux-kernel-4.4.55.git] / fs / fs-writeback.c
index f79f641de4ff87d8908301c26a748822c3524388..387213ac2608ff6c3375ae411ad45716d4ef15e6 100644 (file)
@@ -87,16 +87,29 @@ static inline struct inode *wb_inode(struct list_head *head)
 #define CREATE_TRACE_POINTS
 #include <trace/events/writeback.h>
 
+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
@@ -112,7 +125,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;
        }
 
@@ -159,7 +172,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);
 }
 
 /*
@@ -1016,7 +1029,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