diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/sg.c | 17 |
1 files changed, 9 insertions, 8 deletions
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index d4af13269e85..64df1ab141e5 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -295,23 +295,20 @@ sg_open(struct inode *inode, struct file *filp) if (flags & O_EXCL) sdp->exclude = 1; /* used by release lock */ - if (sdp->detached) { - retval = -ENODEV; - goto sem_out; - } if (sfds_list_empty(sdp)) { /* no existing opens on this device */ sdp->sgdebug = 0; q = sdp->device->request_queue; sdp->sg_tablesize = queue_max_segments(q); } - if ((sfp = sg_add_sfp(sdp, dev))) + sfp = sg_add_sfp(sdp, dev); + if (!IS_ERR(sfp)) filp->private_data = sfp; /* retval is already provably zero at this point because of the * check after retval = scsi_autopm_get_device(sdp->device)) */ else { - retval = -ENOMEM; -sem_out: + retval = PTR_ERR(sfp); + if (flags & O_EXCL) { sdp->exclude = 0; /* undo if error */ up_write(&sdp->o_sem); @@ -2045,7 +2042,7 @@ sg_add_sfp(Sg_device * sdp, int dev) sfp = kzalloc(sizeof(*sfp), GFP_ATOMIC | __GFP_NOWARN); if (!sfp) - return NULL; + return ERR_PTR(-ENOMEM); init_waitqueue_head(&sfp->read_wait); rwlock_init(&sfp->rq_list_lock); @@ -2060,6 +2057,10 @@ sg_add_sfp(Sg_device * sdp, int dev) sfp->keep_orphan = SG_DEF_KEEP_ORPHAN; sfp->parentdp = sdp; write_lock_irqsave(&sg_index_lock, iflags); + if (sdp->detached) { + write_unlock_irqrestore(&sg_index_lock, iflags); + return ERR_PTR(-ENODEV); + } list_add_tail(&sfp->sfd_siblings, &sdp->sfds); write_unlock_irqrestore(&sg_index_lock, iflags); SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: sfp=0x%p\n", sfp)); |