[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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux