aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Dubov <oakad@yahoo.com>2011-01-12 20:01:04 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-13 11:03:22 -0500
commitd8256d487840f9c2c372f8fc615a5d378bc133f1 (patch)
treec9b17bcf583e047ecb55bf775b55053c85b21935
parent8930c8aa740b12ad69f44a35137bcc39bfa3dc41 (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>
-rw-r--r--drivers/memstick/core/memstick.c18
-rw-r--r--drivers/memstick/core/mspro_block.c6
2 files changed, 15 insertions, 9 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
diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c
index 02362eccc58..a167938d451 100644
--- a/drivers/memstick/core/mspro_block.c
+++ b/drivers/memstick/core/mspro_block.c
@@ -1206,10 +1206,12 @@ static int mspro_block_init_disk(struct memstick_dev *card)
1206 1206
1207 msb->page_size = be16_to_cpu(sys_info->unit_size); 1207 msb->page_size = be16_to_cpu(sys_info->unit_size);
1208 1208
1209 if (!idr_pre_get(&mspro_block_disk_idr, GFP_KERNEL)) 1209 mutex_lock(&mspro_block_disk_lock);
1210 if (!idr_pre_get(&mspro_block_disk_idr, GFP_KERNEL)) {
1211 mutex_unlock(&mspro_block_disk_lock);
1210 return -ENOMEM; 1212 return -ENOMEM;
1213 }
1211 1214
1212 mutex_lock(&mspro_block_disk_lock);
1213 rc = idr_get_new(&mspro_block_disk_idr, card, &disk_id); 1215 rc = idr_get_new(&mspro_block_disk_idr, card, &disk_id);
1214 mutex_unlock(&mspro_block_disk_lock); 1216 mutex_unlock(&mspro_block_disk_lock);
1215 1217