diff options
Diffstat (limited to 'fs/fs-writeback.c')
| -rw-r--r-- | fs/fs-writeback.c | 35 | 
1 files changed, 21 insertions, 14 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index ef600591d96f..63ee2940775c 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -173,19 +173,33 @@ static void wb_wakeup(struct bdi_writeback *wb)  	spin_unlock_bh(&wb->work_lock);  } +static void finish_writeback_work(struct bdi_writeback *wb, +				  struct wb_writeback_work *work) +{ +	struct wb_completion *done = work->done; + +	if (work->auto_free) +		kfree(work); +	if (done && atomic_dec_and_test(&done->cnt)) +		wake_up_all(&wb->bdi->wb_waitq); +} +  static void wb_queue_work(struct bdi_writeback *wb,  			  struct wb_writeback_work *work)  {  	trace_writeback_queue(wb, work); -	spin_lock_bh(&wb->work_lock); -	if (!test_bit(WB_registered, &wb->state)) -		goto out_unlock;  	if (work->done)  		atomic_inc(&work->done->cnt); -	list_add_tail(&work->list, &wb->work_list); -	mod_delayed_work(bdi_wq, &wb->dwork, 0); -out_unlock: + +	spin_lock_bh(&wb->work_lock); + +	if (test_bit(WB_registered, &wb->state)) { +		list_add_tail(&work->list, &wb->work_list); +		mod_delayed_work(bdi_wq, &wb->dwork, 0); +	} else +		finish_writeback_work(wb, work); +  	spin_unlock_bh(&wb->work_lock);  } @@ -1873,16 +1887,9 @@ static long wb_do_writeback(struct bdi_writeback *wb)  	set_bit(WB_writeback_running, &wb->state);  	while ((work = get_next_work_item(wb)) != NULL) { -		struct wb_completion *done = work->done; -  		trace_writeback_exec(wb, work); -  		wrote += wb_writeback(wb, work); - -		if (work->auto_free) -			kfree(work); -		if (done && atomic_dec_and_test(&done->cnt)) -			wake_up_all(&wb->bdi->wb_waitq); +		finish_writeback_work(wb, work);  	}  	/*  | 
