Browse Source

writeback: add wb_writeback_work->auto_free

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>
Tejun Heo 10 years ago
parent
commit
ac7b19a34f
1 changed files with 6 additions and 7 deletions
  1. 6 7
      fs/fs-writeback.c

+ 6 - 7
fs/fs-writeback.c

@@ -47,6 +47,7 @@ struct wb_writeback_work {
 	unsigned int range_cyclic:1;
 	unsigned int range_cyclic:1;
 	unsigned int for_background:1;
 	unsigned int for_background:1;
 	unsigned int for_sync:1;	/* sync(2) WB_SYNC_ALL writeback */
 	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? */
 	enum wb_reason reason;		/* why was writeback initiated? */
 
 
 	struct list_head list;		/* pending work list */
 	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->nr_pages	= nr_pages;
 	work->range_cyclic = range_cyclic;
 	work->range_cyclic = range_cyclic;
 	work->reason	= reason;
 	work->reason	= reason;
+	work->auto_free	= 1;
 
 
 	wb_queue_work(wb, work);
 	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);
 	set_bit(WB_writeback_running, &wb->state);
 	while ((work = get_next_work_item(wb)) != NULL) {
 	while ((work = get_next_work_item(wb)) != NULL) {
+		struct completion *done = work->done;
 
 
 		trace_writeback_exec(wb->bdi, work);
 		trace_writeback_exec(wb->bdi, work);
 
 
 		wrote += wb_writeback(wb, 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);
 			kfree(work);
+		if (done)
+			complete(done);
 	}
 	}
 
 
 	/*
 	/*