block: prevent possible io_context->refcount overflow

Currently io_context has an atomic_t(32-bit) as refcount.  In the case of
cfq, for each device against whcih a task does I/O, a reference to the
io_context would be taken.  And when there are multiple process sharing
io_contexts(CLONE_IO) would also have a reference to the same io_context.

Theoretically the possible maximum number of processes sharing the same
io_context + the number of disks/cfq_data referring to the same io_context
can overflow the 32-bit counter on a very high-end machine.

Even though it is an improbable case, let us make it atomic_long_t.

Signed-off-by: Nikanth Karthikesan <knikanth@suse.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
This commit is contained in:
Nikanth Karthikesan 2009-06-10 12:57:06 -07:00 committed by Jens Axboe
parent 1d589bb16b
commit d9c7d394a8
3 changed files with 10 additions and 10 deletions

View file

@ -64,7 +64,7 @@ struct cfq_io_context {
* and kmalloc'ed. These could be shared between processes.
*/
struct io_context {
atomic_t refcount;
atomic_long_t refcount;
atomic_t nr_tasks;
/* all the fields below are protected by this lock */
@ -91,8 +91,8 @@ static inline struct io_context *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_inc_not_zero(&ioc->refcount)) {
atomic_inc(&ioc->nr_tasks);
if (ioc && atomic_long_inc_not_zero(&ioc->refcount)) {
atomic_long_inc(&ioc->refcount);
return ioc;
}