unsigned int for_background:1;
        unsigned int for_sync:1;        /* sync(2) WB_SYNC_ALL writeback */
        unsigned int auto_free:1;       /* free on completion */
+       unsigned int single_wait:1;
+       unsigned int single_done:1;
        enum wb_reason reason;          /* why was writeback initiated? */
 
        struct list_head list;          /* pending work list */
        trace_writeback_queue(wb->bdi, work);
 
        spin_lock_bh(&wb->work_lock);
-       if (!test_bit(WB_registered, &wb->state))
+       if (!test_bit(WB_registered, &wb->state)) {
+               if (work->single_wait)
+                       work->single_done = 1;
                goto out_unlock;
+       }
        if (work->done)
                atomic_inc(&work->done->cnt);
        list_add_tail(&work->list, &wb->work_list);
 }
 EXPORT_SYMBOL_GPL(inode_congested);
 
+/**
+ * wb_wait_for_single_work - wait for completion of a single bdi_writeback_work
+ * @bdi: bdi the work item was issued to
+ * @work: work item to wait for
+ *
+ * Wait for the completion of @work which was issued to one of @bdi's
+ * bdi_writeback's.  The caller must have set @work->single_wait before
+ * issuing it.  This wait operates independently fo
+ * wb_wait_for_completion() and also disables automatic freeing of @work.
+ */
+static void wb_wait_for_single_work(struct backing_dev_info *bdi,
+                                   struct wb_writeback_work *work)
+{
+       if (WARN_ON_ONCE(!work->single_wait))
+               return;
+
+       wait_event(bdi->wb_waitq, work->single_done);
+
+       /*
+        * Paired with smp_wmb() in wb_do_writeback() and ensures that all
+        * modifications to @work prior to assertion of ->single_done is
+        * visible to the caller once this function returns.
+        */
+       smp_rmb();
+}
+
 /**
  * wb_split_bdi_pages - split nr_pages to write according to bandwidth
  * @wb: target bdi_writeback to split @nr_pages to
        set_bit(WB_writeback_running, &wb->state);
        while ((work = get_next_work_item(wb)) != NULL) {
                struct wb_completion *done = work->done;
+               bool need_wake_up = false;
 
                trace_writeback_exec(wb->bdi, work);
 
                wrote += wb_writeback(wb, work);
 
-               if (work->auto_free)
+               if (work->single_wait) {
+                       WARN_ON_ONCE(work->auto_free);
+                       /* paired w/ rmb in wb_wait_for_single_work() */
+                       smp_wmb();
+                       work->single_done = 1;
+                       need_wake_up = true;
+               } else if (work->auto_free) {
                        kfree(work);
+               }
+
                if (done && atomic_dec_and_test(&done->cnt))
+                       need_wake_up = true;
+
+               if (need_wake_up)
                        wake_up_all(&wb->bdi->wb_waitq);
        }