diff options
author | Alex Dubov <oakad@yahoo.com> | 2011-01-12 20:01:04 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-13 11:03:22 -0500 |
commit | d8256d487840f9c2c372f8fc615a5d378bc133f1 (patch) | |
tree | c9b17bcf583e047ecb55bf775b55053c85b21935 /drivers/memstick/core/memstick.c | |
parent | 8930c8aa740b12ad69f44a35137bcc39bfa3dc41 (diff) |
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 <oakad@yahoo.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/memstick/core/memstick.c')
-rw-r--r-- | drivers/memstick/core/memstick.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c index 4303b7ef73e..e9a3eab7b0c 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) | |||
511 | { | 511 | { |
512 | int rc; | 512 | int rc; |
513 | 513 | ||
514 | if (!idr_pre_get(&memstick_host_idr, GFP_KERNEL)) | 514 | while (1) { |
515 | return -ENOMEM; | 515 | if (!idr_pre_get(&memstick_host_idr, GFP_KERNEL)) |
516 | return -ENOMEM; | ||
516 | 517 | ||
517 | spin_lock(&memstick_host_lock); | 518 | spin_lock(&memstick_host_lock); |
518 | rc = idr_get_new(&memstick_host_idr, host, &host->id); | 519 | rc = idr_get_new(&memstick_host_idr, host, &host->id); |
519 | spin_unlock(&memstick_host_lock); | 520 | spin_unlock(&memstick_host_lock); |
520 | if (rc) | 521 | if (!rc) |
521 | return rc; | 522 | break; |
523 | else if (rc != -EAGAIN) | ||
524 | return rc; | ||
525 | } | ||
522 | 526 | ||
523 | dev_set_name(&host->dev, "memstick%u", host->id); | 527 | dev_set_name(&host->dev, "memstick%u", host->id); |
524 | 528 | ||