[Patch] convert drivers/scsi/sg.c use .unlocked_ioctl | |
| [Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] | |
Convert drivers/scsi/sg.c to use the unlocked_ioctl. This is based on
the linux-next tree.
Signed-off-by: Stoyan Gaydarov <stoyboyker@xxxxxxxxx>
diff -uprN linux-next/drivers/scsi/sg.c devel/drivers/scsi/sg.c
--- linux-next/drivers/scsi/sg.c 2008-07-11 05:14:06.000000000 -0500
+++ devel/drivers/scsi/sg.c 2008-07-11 07:33:43.000000000 -0500
@@ -779,20 +779,23 @@ sg_srp_done(Sg_request *srp, Sg_fd *sfp)
return done;
}
-static int
-sg_ioctl(struct inode *inode, struct file *filp,
- unsigned int cmd_in, unsigned long arg)
+static long
+sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
{
void __user *p = (void __user *)arg;
int __user *ip = p;
- int result, val, read_only;
+ int result, val, read_only, error;
Sg_device *sdp;
Sg_fd *sfp;
Sg_request *srp;
unsigned long iflags;
- if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
- return -ENXIO;
+ lock_kernel();
+
+ if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) {
+ error = -ENXIO;
+ goto out;
+ }
SCSI_LOG_TIMEOUT(3, printk("sg_ioctl: %s, cmd=0x%x\n",
sdp->disk->disk_name, (int) cmd_in));
read_only = (O_RDWR != (filp->f_flags & O_ACCMODE));
@@ -802,57 +805,80 @@ sg_ioctl(struct inode *inode, struct fil
{
int blocking = 1; /* ignore O_NONBLOCK flag */
- if (sdp->detached)
- return -ENODEV;
- if (!scsi_block_when_processing_errors(sdp->device))
- return -ENXIO;
- if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR))
- return -EFAULT;
+ if (sdp->detached) {
+ error = -ENODEV;
+ goto out;
+ }
+ if (!scsi_block_when_processing_errors(sdp->device)) {
+ error = -ENXIO;
+ goto out;
+ }
+ if (!access_ok(VERIFY_WRITE, p, SZ_SG_IO_HDR)) {
+ error = -EFAULT;
+ goto out;
+ }
result =
sg_new_write(sfp, filp, p, SZ_SG_IO_HDR,
blocking, read_only, &srp);
- if (result < 0)
- return result;
+ if (result < 0) {
+ error = result;
+ goto out;
+ }
srp->sg_io_owned = 1;
while (1) {
result = 0; /* following macro to beat race condition */
__wait_event_interruptible(sfp->read_wait,
(sdp->detached || sfp->closed || sg_srp_done(srp, sfp)),
result);
- if (sdp->detached)
- return -ENODEV;
- if (sfp->closed)
- return 0; /* request packet dropped already */
+ if (sdp->detached) {
+ error = -ENODEV;
+ goto out;
+ }
+ if (sfp->closed) {
+ error = 0; /* request packet dropped already */
+ goto out;
+ }
if (0 == result)
break;
srp->orphan = 1;
- return result; /* -ERESTARTSYS because signal hit process */
+
+ error = result; /* -ERESTARTSYS because signal hit process */
+ goto out;
}
write_lock_irqsave(&sfp->rq_list_lock, iflags);
srp->done = 2;
write_unlock_irqrestore(&sfp->rq_list_lock, iflags);
result = sg_new_read(sfp, p, SZ_SG_IO_HDR, srp);
- return (result < 0) ? result : 0;
+ error = (result < 0) ? result : 0;
+ goto out;
}
case SG_SET_TIMEOUT:
result = get_user(val, ip);
- if (result)
- return result;
- if (val < 0)
- return -EIO;
+ if (result) {
+ error = result;
+ goto out;
+ }
+ if (val < 0) {
+ error = -EIO;
+ goto out;
+ }
if (val >= MULDIV (INT_MAX, USER_HZ, HZ))
val = MULDIV (INT_MAX, USER_HZ, HZ);
sfp->timeout_user = val;
sfp->timeout = MULDIV (val, HZ, USER_HZ);
- return 0;
+ error = 0;
+ goto out;
case SG_GET_TIMEOUT: /* N.B. User receives timeout as return value */
/* strange ..., for backward compatibility */
- return sfp->timeout_user;
+ error = sfp->timeout_user;
+ goto out;
case SG_SET_FORCE_LOW_DMA:
result = get_user(val, ip);
- if (result)
- return result;
+ if (result) {
+ error = result;
+ goto out;
+ }
if (val) {
sfp->low_dma = 1;
if ((0 == sfp->low_dma) && (0 == sg_res_in_use(sfp))) {
@@ -861,21 +887,29 @@ sg_ioctl(struct inode *inode, struct fil
sg_build_reserve(sfp, val);
}
} else {
- if (sdp->detached)
- return -ENODEV;
+ if (sdp->detached) {
+ error = -ENODEV;
+ goto out;
+ }
sfp->low_dma = sdp->device->host->unchecked_isa_dma;
}
- return 0;
+ error = 0;
+ goto out;
case SG_GET_LOW_DMA:
- return put_user((int) sfp->low_dma, ip);
+ error = put_user((int) sfp->low_dma, ip);
+ goto out;
case SG_GET_SCSI_ID:
- if (!access_ok(VERIFY_WRITE, p, sizeof (sg_scsi_id_t)))
- return -EFAULT;
+ if (!access_ok(VERIFY_WRITE, p, sizeof (sg_scsi_id_t))) {
+ error = -EFAULT;
+ goto out;
+ }
else {
sg_scsi_id_t __user *sg_idp = p;
- if (sdp->detached)
- return -ENODEV;
+ if (sdp->detached) {
+ error = -ENODEV;
+ goto out;
+ }
__put_user((int) sdp->device->host->host_no,
&sg_idp->host_no);
__put_user((int) sdp->device->channel,
@@ -889,29 +923,37 @@ sg_ioctl(struct inode *inode, struct fil
&sg_idp->d_queue_depth);
__put_user(0, &sg_idp->unused[0]);
__put_user(0, &sg_idp->unused[1]);
- return 0;
+ error = 0;
+ goto out;
}
case SG_SET_FORCE_PACK_ID:
result = get_user(val, ip);
if (result)
- return result;
- sfp->force_packid = val ? 1 : 0;
- return 0;
+ error = result;
+ else {
+ sfp->force_packid = val ? 1 : 0;
+ error = 0;
+ }
+ goto out;
case SG_GET_PACK_ID:
- if (!access_ok(VERIFY_WRITE, ip, sizeof (int)))
- return -EFAULT;
+ if (!access_ok(VERIFY_WRITE, ip, sizeof (int))) {
+ error = -EFAULT;
+ goto out;
+ }
read_lock_irqsave(&sfp->rq_list_lock, iflags);
for (srp = sfp->headrp; srp; srp = srp->nextrp) {
if ((1 == srp->done) && (!srp->sg_io_owned)) {
read_unlock_irqrestore(&sfp->rq_list_lock,
iflags);
__put_user(srp->header.pack_id, ip);
- return 0;
+ error = 0;
+ goto out;
}
}
read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
__put_user(-1, ip);
- return 0;
+ error = 0;
+ goto out;
case SG_GET_NUM_WAITING:
read_lock_irqsave(&sfp->rq_list_lock, iflags);
for (val = 0, srp = sfp->headrp; srp; srp = srp->nextrp) {
@@ -919,67 +961,94 @@ sg_ioctl(struct inode *inode, struct fil
++val;
}
read_unlock_irqrestore(&sfp->rq_list_lock, iflags);
- return put_user(val, ip);
+ error = put_user(val, ip);
+ goto out;
case SG_GET_SG_TABLESIZE:
- return put_user(sdp->sg_tablesize, ip);
+ error = put_user(sdp->sg_tablesize, ip);
+ goto out;
case SG_SET_RESERVED_SIZE:
result = get_user(val, ip);
- if (result)
- return result;
- if (val < 0)
- return -EINVAL;
+ if (result) {
+ error = result;
+ goto out;
+ }
+ if (val < 0) {
+ error = -EINVAL;
+ goto out;
+ }
val = min_t(int, val,
sdp->device->request_queue->max_sectors * 512);
if (val != sfp->reserve.bufflen) {
- if (sg_res_in_use(sfp) || sfp->mmap_called)
- return -EBUSY;
+ if (sg_res_in_use(sfp) || sfp->mmap_called) {
+ error = -EBUSY;
+ goto out;
+ }
sg_remove_scat(&sfp->reserve);
sg_build_reserve(sfp, val);
}
- return 0;
+ error = 0;
+ goto out;
case SG_GET_RESERVED_SIZE:
val = min_t(int, sfp->reserve.bufflen,
sdp->device->request_queue->max_sectors * 512);
- return put_user(val, ip);
+ error = put_user(val, ip);
+ goto out;
case SG_SET_COMMAND_Q:
result = get_user(val, ip);
if (result)
- return result;
- sfp->cmd_q = val ? 1 : 0;
- return 0;
+ error = result;
+ else {
+ sfp->cmd_q = val ? 1 : 0;
+ error = 0;
+ }
+ goto out;
case SG_GET_COMMAND_Q:
- return put_user((int) sfp->cmd_q, ip);
+ error = put_user((int) sfp->cmd_q, ip);
+ goto out;
case SG_SET_KEEP_ORPHAN:
result = get_user(val, ip);
if (result)
- return result;
- sfp->keep_orphan = val;
- return 0;
+ error = result;
+ else {
+ sfp->keep_orphan = val;
+ error = 0;
+ }
+ goto out;
case SG_GET_KEEP_ORPHAN:
- return put_user((int) sfp->keep_orphan, ip);
+ error = put_user((int) sfp->keep_orphan, ip);
+ goto out;
case SG_NEXT_CMD_LEN:
result = get_user(val, ip);
if (result)
- return result;
- sfp->next_cmd_len = (val > 0) ? val : 0;
- return 0;
+ error = result;
+ else {
+ sfp->next_cmd_len = (val > 0) ? val : 0;
+ error = 0;
+ }
+ goto out;
case SG_GET_VERSION_NUM:
- return put_user(sg_version_num, ip);
+ error = put_user(sg_version_num, ip);
+ goto out;
case SG_GET_ACCESS_COUNT:
/* faked - we don't have a real access count anymore */
val = (sdp->device ? 1 : 0);
- return put_user(val, ip);
+ error = put_user(val, ip);
+ goto out;
case SG_GET_REQUEST_TABLE:
- if (!access_ok(VERIFY_WRITE, p, SZ_SG_REQ_INFO * SG_MAX_QUEUE))
- return -EFAULT;
+ if (!access_ok(VERIFY_WRITE, p, SZ_SG_REQ_INFO * SG_MAX_QUEUE)) {
+ error = -EFAULT;
+ goto out;
+ }
else {
sg_req_info_t *rinfo;
unsigned int ms;
rinfo = kmalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE,
GFP_KERNEL);
- if (!rinfo)
- return -ENOMEM;
+ if (!rinfo) {
+ error = -ENOMEM;
+ goto out;
+ }
read_lock_irqsave(&sfp->rq_list_lock, iflags);
for (srp = sfp->headrp, val = 0; val < SG_MAX_QUEUE;
++val, srp = srp ? srp->nextrp : srp) {
@@ -1013,25 +1082,38 @@ sg_ioctl(struct inode *inode, struct fil
SZ_SG_REQ_INFO * SG_MAX_QUEUE);
result = result ? -EFAULT : 0;
kfree(rinfo);
- return result;
+ error = result;
+ goto out;
}
case SG_EMULATED_HOST:
if (sdp->detached)
- return -ENODEV;
- return put_user(sdp->device->host->hostt->emulated, ip);
+ error = -ENODEV;
+ else
+ error = put_user(sdp->device->host->hostt->emulated, ip);
+ goto out;
case SG_SCSI_RESET:
- if (sdp->detached)
- return -ENODEV;
+ if (sdp->detached) {
+ error = -ENODEV;
+ goto out;
+ }
if (filp->f_flags & O_NONBLOCK) {
- if (scsi_host_in_recovery(sdp->device->host))
- return -EBUSY;
- } else if (!scsi_block_when_processing_errors(sdp->device))
- return -EBUSY;
+ if (scsi_host_in_recovery(sdp->device->host)) {
+ error = -EBUSY;
+ goto out;
+ }
+ } else if (!scsi_block_when_processing_errors(sdp->device)) {
+ error = -EBUSY;
+ goto out;
+ }
result = get_user(val, ip);
- if (result)
- return result;
- if (SG_SCSI_RESET_NOTHING == val)
- return 0;
+ if (result) {
+ error = result;
+ goto out;
+ }
+ if (SG_SCSI_RESET_NOTHING == val) {
+ error = 0;
+ goto out;
+ }
switch (val) {
case SG_SCSI_RESET_DEVICE:
val = SCSI_TRY_RESET_DEVICE;
@@ -1046,57 +1128,81 @@ sg_ioctl(struct inode *inode, struct fil
val = SCSI_TRY_RESET_HOST;
break;
default:
- return -EINVAL;
+ error = -EINVAL;
+ goto out;
}
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
- return -EACCES;
- return (scsi_reset_provider(sdp->device, val) ==
- SUCCESS) ? 0 : -EIO;
+ error = -EACCES;
+ else
+ error = (scsi_reset_provider(sdp->device, val) == SUCCESS) ? 0 : -EIO;
+ goto out;
case SCSI_IOCTL_SEND_COMMAND:
- if (sdp->detached)
- return -ENODEV;
+ if (sdp->detached) {
+ error = -ENODEV;
+ goto out;
+ }
if (read_only) {
unsigned char opcode = WRITE_6;
Scsi_Ioctl_Command __user *siocp = p;
- if (copy_from_user(&opcode, siocp->data, 1))
- return -EFAULT;
- if (!blk_verify_command(filp, &opcode))
- return -EPERM;
+ if (copy_from_user(&opcode, siocp->data, 1)) {
+ error = -EFAULT;
+ goto out;
+ }
+ if (!blk_verify_command(filp, &opcode)) {
+ error = -EPERM;
+ goto out;
+ }
}
- return sg_scsi_ioctl(filp, sdp->device->request_queue, NULL, p);
+ error = sg_scsi_ioctl(filp, sdp->device->request_queue, NULL, p);
+ goto out;
case SG_SET_DEBUG:
result = get_user(val, ip);
if (result)
- return result;
- sdp->sgdebug = (char) val;
- return 0;
+ error = result;
+ else {
+ sdp->sgdebug = (char) val;
+ error = 0;
+ }
+ goto out;
case SCSI_IOCTL_GET_IDLUN:
case SCSI_IOCTL_GET_BUS_NUMBER:
case SCSI_IOCTL_PROBE_HOST:
case SG_GET_TRANSFORM:
if (sdp->detached)
- return -ENODEV;
- return scsi_ioctl(sdp->device, cmd_in, p);
+ error = -ENODEV;
+ else
+ error = scsi_ioctl(sdp->device, cmd_in, p);
+ goto out;
case BLKSECTGET:
- return put_user(sdp->device->request_queue->max_sectors * 512,
- ip);
+ error = put_user(sdp->device->request_queue->max_sectors * 512, ip);
+ goto out;
case BLKTRACESETUP:
- return blk_trace_setup(sdp->device->request_queue,
- sdp->disk->disk_name,
- sdp->device->sdev_gendev.devt,
- (char *)arg);
+ error = blk_trace_setup(sdp->device->request_queue,
+ sdp->disk->disk_name,
+ sdp->device->sdev_gendev.devt,
+ (char *)arg);
+ goto out;
case BLKTRACESTART:
- return blk_trace_startstop(sdp->device->request_queue, 1);
+ error = blk_trace_startstop(sdp->device->request_queue, 1);
+ goto out;
case BLKTRACESTOP:
- return blk_trace_startstop(sdp->device->request_queue, 0);
+ error = blk_trace_startstop(sdp->device->request_queue, 0);
+ goto out;
case BLKTRACETEARDOWN:
- return blk_trace_remove(sdp->device->request_queue);
+ error = blk_trace_remove(sdp->device->request_queue);
+ goto out;
default:
if (read_only)
- return -EPERM; /* don't know so take safe approach */
- return scsi_ioctl(sdp->device, cmd_in, p);
+ error = -EPERM; /* don't know so take safe approach */
+ else
+ error = scsi_ioctl(sdp->device, cmd_in, p);
+ goto out;
}
+
+out:
+ unlock_kernel();
+ return error;
}
#ifdef CONFIG_COMPAT
@@ -1342,7 +1448,7 @@ static struct file_operations sg_fops =
.read = sg_read,
.write = sg_write,
.poll = sg_poll,
- .ioctl = sg_ioctl,
+ .unlocked_ioctl = sg_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl = sg_compat_ioctl,
#endif
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
[Site Home] [Kernel Newbies] [Linux SCSI Target Infrastructure] [Share Photos] [IDE] [Security] [Git] [Netfilter] [Bugtraq] [Rubini] [Photo] [Yosemite] [Yosemite News] [MIPS Linux] [ARM Linux] [Linux Security] [Linux RAID] [Linux ATA RAID] [Samba] [Video 4 Linux] [Device Mapper] [Linux Resources]
![]() |
![]() |