aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fs-writeback.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fs-writeback.c')
-rw-r--r--fs/fs-writeback.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index d754e3cf99a8..be568b7311d6 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -89,16 +89,31 @@ static inline struct inode *wb_inode(struct list_head *head)
89#define CREATE_TRACE_POINTS 89#define CREATE_TRACE_POINTS
90#include <trace/events/writeback.h> 90#include <trace/events/writeback.h>
91 91
92EXPORT_TRACEPOINT_SYMBOL_GPL(wbc_writepage);
93
94static void bdi_wakeup_thread(struct backing_dev_info *bdi)
95{
96 spin_lock_bh(&bdi->wb_lock);
97 if (test_bit(BDI_registered, &bdi->state))
98 mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
99 spin_unlock_bh(&bdi->wb_lock);
100}
101
92static void bdi_queue_work(struct backing_dev_info *bdi, 102static void bdi_queue_work(struct backing_dev_info *bdi,
93 struct wb_writeback_work *work) 103 struct wb_writeback_work *work)
94{ 104{
95 trace_writeback_queue(bdi, work); 105 trace_writeback_queue(bdi, work);
96 106
97 spin_lock_bh(&bdi->wb_lock); 107 spin_lock_bh(&bdi->wb_lock);
108 if (!test_bit(BDI_registered, &bdi->state)) {
109 if (work->done)
110 complete(work->done);
111 goto out_unlock;
112 }
98 list_add_tail(&work->list, &bdi->work_list); 113 list_add_tail(&work->list, &bdi->work_list);
99 spin_unlock_bh(&bdi->wb_lock);
100
101 mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0); 114 mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0);
115out_unlock:
116 spin_unlock_bh(&bdi->wb_lock);
102} 117}
103 118
104static void 119static void
@@ -114,7 +129,7 @@ __bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages,
114 work = kzalloc(sizeof(*work), GFP_ATOMIC); 129 work = kzalloc(sizeof(*work), GFP_ATOMIC);
115 if (!work) { 130 if (!work) {
116 trace_writeback_nowork(bdi); 131 trace_writeback_nowork(bdi);
117 mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0); 132 bdi_wakeup_thread(bdi);
118 return; 133 return;
119 } 134 }
120 135
@@ -161,7 +176,7 @@ void bdi_start_background_writeback(struct backing_dev_info *bdi)
161 * writeback as soon as there is no other work to do. 176 * writeback as soon as there is no other work to do.
162 */ 177 */
163 trace_writeback_wake_background(bdi); 178 trace_writeback_wake_background(bdi);
164 mod_delayed_work(bdi_wq, &bdi->wb.dwork, 0); 179 bdi_wakeup_thread(bdi);
165} 180}
166 181
167/* 182/*
@@ -1017,7 +1032,7 @@ void bdi_writeback_workfn(struct work_struct *work)
1017 current->flags |= PF_SWAPWRITE; 1032 current->flags |= PF_SWAPWRITE;
1018 1033
1019 if (likely(!current_is_workqueue_rescuer() || 1034 if (likely(!current_is_workqueue_rescuer() ||
1020 list_empty(&bdi->bdi_list))) { 1035 !test_bit(BDI_registered, &bdi->state))) {
1021 /* 1036 /*
1022 * The normal path. Keep writing back @bdi until its 1037 * The normal path. Keep writing back @bdi until its
1023 * work_list is empty. Note that this path is also taken 1038 * work_list is empty. Note that this path is also taken
@@ -1039,10 +1054,10 @@ void bdi_writeback_workfn(struct work_struct *work)
1039 trace_writeback_pages_written(pages_written); 1054 trace_writeback_pages_written(pages_written);
1040 } 1055 }
1041 1056
1042 if (!list_empty(&bdi->work_list) || 1057 if (!list_empty(&bdi->work_list))
1043 (wb_has_dirty_io(wb) && dirty_writeback_interval)) 1058 mod_delayed_work(bdi_wq, &wb->dwork, 0);
1044 queue_delayed_work(bdi_wq, &wb->dwork, 1059 else if (wb_has_dirty_io(wb) && dirty_writeback_interval)
1045 msecs_to_jiffies(dirty_writeback_interval * 10)); 1060 bdi_wakeup_thread_delayed(bdi);
1046 1061
1047 current->flags &= ~PF_SWAPWRITE; 1062 current->flags &= ~PF_SWAPWRITE;
1048} 1063}