From d8256d487840f9c2c372f8fc615a5d378bc133f1 Mon Sep 17 00:00:00 2001 From: Alex Dubov Date: Wed, 12 Jan 2011 17:01:04 -0800 Subject: memstick: avert possible race condition between idr_pre_get and idr_get_new Implement the usual pattern around idr_pre_get() and idr_get_new() to handlethe situation where another thread concurrently steals this thread's idr_pre_get() preallocation. Signed-off-by: Alex Dubov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/memstick/core/memstick.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers/memstick/core/memstick.c') diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c index 4303b7ef73e2..e9a3eab7b0cf 100644 --- a/drivers/memstick/core/memstick.c +++ b/drivers/memstick/core/memstick.c @@ -511,14 +511,18 @@ int memstick_add_host(struct memstick_host *host) { int rc; - if (!idr_pre_get(&memstick_host_idr, GFP_KERNEL)) - return -ENOMEM; + while (1) { + if (!idr_pre_get(&memstick_host_idr, GFP_KERNEL)) + return -ENOMEM; - spin_lock(&memstick_host_lock); - rc = idr_get_new(&memstick_host_idr, host, &host->id); - spin_unlock(&memstick_host_lock); - if (rc) - return rc; + spin_lock(&memstick_host_lock); + rc = idr_get_new(&memstick_host_idr, host, &host->id); + spin_unlock(&memstick_host_lock); + if (!rc) + break; + else if (rc != -EAGAIN) + return rc; + } dev_set_name(&host->dev, "memstick%u", host->id); -- cgit v1.2.3