writeback: add wb_writeback_work->auto_free
authorTejun Heo <tj@kernel.org>
Fri, 22 May 2015 21:13:57 +0000 (17:13 -0400)
committerJens Axboe <axboe@fb.com>
Tue, 2 Jun 2015 14:33:36 +0000 (08:33 -0600)
Currently, a wb_writeback_work is freed automatically on completion if
it doesn't have ->done set.  Add wb_writeback_work->auto_free to make
the switch explicit.  This will help cgroup writeback support where
waiting for completion and whether to free automatically don't
necessarily move together.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Jan Kara <jack@suse.cz>
Signed-off-by: Jens Axboe <axboe@fb.com>
fs/fs-writeback.c

index 8ae212e90ec3549764f084dbf417ee33a1b53501..22f1def4e63aafd33d9ec531a82520eea777a133 100644 (file)
@@ -47,6 +47,7 @@ struct wb_writeback_work {
        unsigned int range_cyclic:1;
        unsigned int for_background:1;
        unsigned int for_sync:1;        /* sync(2) WB_SYNC_ALL writeback */
+       unsigned int auto_free:1;       /* free on completion */
        enum wb_reason reason;          /* why was writeback initiated? */
 
        struct list_head list;          /* pending work list */
@@ -258,6 +259,7 @@ void wb_start_writeback(struct bdi_writeback *wb, long nr_pages,
        work->nr_pages  = nr_pages;
        work->range_cyclic = range_cyclic;
        work->reason    = reason;
+       work->auto_free = 1;
 
        wb_queue_work(wb, work);
 }
@@ -1141,19 +1143,16 @@ 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 completion *done = work->done;
 
                trace_writeback_exec(wb->bdi, work);
 
                wrote += wb_writeback(wb, work);
 
-               /*
-                * Notify the caller of completion if this is a synchronous
-                * work item, otherwise just free it.
-                */
-               if (work->done)
-                       complete(work->done);
-               else
+               if (work->auto_free)
                        kfree(work);
+               if (done)
+                       complete(done);
        }
 
        /*