Skip to content

Commit

Permalink
[SCSI] sd: revive sd_index_lock
Browse files Browse the repository at this point in the history
Commit f27bac2 which converted sd to
use ida instead of idr incorrectly removed sd_index_lock around id
allocation and free.  idr/ida do have internal locks but they protect
their free object lists not the allocation itself.  The caller is
responsible for that.  This missing synchronization led to the same id
being assigned to multiple devices leading to oops.

Reported and tracked down by Stuart Hayes of Dell.

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Stable Tree <stable@kernel.org>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
  • Loading branch information
Tejun Heo authored and James Bottomley committed Feb 22, 2009
1 parent b7e7bd3 commit 4034cc6
Showing 1 changed file with 7 additions and 0 deletions.
7 changes: 7 additions & 0 deletions drivers/scsi/sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ static void scsi_disk_release(struct device *cdev);
static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *);
static void sd_print_result(struct scsi_disk *, int);

static DEFINE_SPINLOCK(sd_index_lock);
static DEFINE_IDA(sd_index_ida);

/* This semaphore is used to mediate the 0->1 reference get in the
Expand Down Expand Up @@ -1914,7 +1915,9 @@ static int sd_probe(struct device *dev)
if (!ida_pre_get(&sd_index_ida, GFP_KERNEL))
goto out_put;

spin_lock(&sd_index_lock);
error = ida_get_new(&sd_index_ida, &index);
spin_unlock(&sd_index_lock);
} while (error == -EAGAIN);

if (error)
Expand All @@ -1936,7 +1939,9 @@ static int sd_probe(struct device *dev)
return 0;

out_free_index:
spin_lock(&sd_index_lock);
ida_remove(&sd_index_ida, index);
spin_unlock(&sd_index_lock);
out_put:
put_disk(gd);
out_free:
Expand Down Expand Up @@ -1986,7 +1991,9 @@ static void scsi_disk_release(struct device *dev)
struct scsi_disk *sdkp = to_scsi_disk(dev);
struct gendisk *disk = sdkp->disk;

spin_lock(&sd_index_lock);
ida_remove(&sd_index_ida, sdkp->index);
spin_unlock(&sd_index_lock);

disk->private_data = NULL;
put_disk(disk);
Expand Down

0 comments on commit 4034cc6

Please sign in to comment.