diff options
| author | Tejun Heo <tj@kernel.org> | 2012-03-05 13:15:25 -0800 | 
|---|---|---|
| committer | Jens Axboe <axboe@kernel.dk> | 2012-03-06 21:27:24 +0100 | 
| commit | 3d48749d93a3dce732dd30a14002ab90ec4355f3 (patch) | |
| tree | 50ce414ec87e590493476cf644092439c5f337fd | |
| parent | 24acfc34fba0b4f62ef9d5c2616eb0faa802b606 (diff) | |
| download | olio-linux-3.10-3d48749d93a3dce732dd30a14002ab90ec4355f3.tar.xz olio-linux-3.10-3d48749d93a3dce732dd30a14002ab90ec4355f3.zip  | |
block: ioc_task_link() can't fail
ioc_task_link() is used to share %current's ioc on clone.  If
%current->io_context is set, %current is guaranteed to have refcount
on the ioc and, thus, ioc_task_link() can't fail.
Replace error checking in ioc_task_link() with WARN_ON_ONCE() and make
it just increment refcount and nr_tasks.
-v2: Description typo fix (Vivek).
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Vivek Goyal <vgoyal@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
| -rw-r--r-- | include/linux/iocontext.h | 16 | ||||
| -rw-r--r-- | kernel/fork.c | 5 | 
2 files changed, 7 insertions, 14 deletions
diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h index 1a301806303..81a8870ac22 100644 --- a/include/linux/iocontext.h +++ b/include/linux/iocontext.h @@ -120,18 +120,12 @@ struct io_context {  	struct work_struct release_work;  }; -static inline struct io_context *ioc_task_link(struct io_context *ioc) +static inline void ioc_task_link(struct io_context *ioc)  { -	/* -	 * if ref count is zero, don't allow sharing (ioc is going away, it's -	 * a race). -	 */ -	if (ioc && atomic_long_inc_not_zero(&ioc->refcount)) { -		atomic_inc(&ioc->nr_tasks); -		return ioc; -	} - -	return NULL; +	WARN_ON_ONCE(atomic_long_read(&ioc->refcount) <= 0); +	WARN_ON_ONCE(atomic_read(&ioc->nr_tasks) <= 0); +	atomic_long_inc(&ioc->refcount); +	atomic_inc(&ioc->nr_tasks);  }  struct task_struct; diff --git a/kernel/fork.c b/kernel/fork.c index b77fd559c78..a1b632713e4 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -901,9 +901,8 @@ static int copy_io(unsigned long clone_flags, struct task_struct *tsk)  	 * Share io context with parent, if CLONE_IO is set  	 */  	if (clone_flags & CLONE_IO) { -		tsk->io_context = ioc_task_link(ioc); -		if (unlikely(!tsk->io_context)) -			return -ENOMEM; +		ioc_task_link(ioc); +		tsk->io_context = ioc;  	} else if (ioprio_valid(ioc->ioprio)) {  		new_ioc = get_task_io_context(tsk, GFP_KERNEL, NUMA_NO_NODE);  		if (unlikely(!new_ioc))  |