Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/fs/ioctl.c |  182 ++++++++++++++++++++++++++---------------------------
 1 files changed, 92 insertions(+), 90 deletions(-)

diff -puN fs/ioctl.c~ioctl-cleanup fs/ioctl.c
--- 25/fs/ioctl.c~ioctl-cleanup	2004-12-09 20:55:23.521523040 -0800
+++ 25-akpm/fs/ioctl.c	2004-12-09 21:10:47.000132952 -0800
@@ -16,46 +16,12 @@
 #include <asm/uaccess.h>
 #include <asm/ioctls.h>
 
-static int file_ioctl(struct file *filp,unsigned int cmd,unsigned long arg)
-{
-	int error;
-	int block;
-	struct inode * inode = filp->f_dentry->d_inode;
-	int __user *p = (int __user *)arg;
-
-	switch (cmd) {
-		case FIBMAP:
-		{
-			struct address_space *mapping = filp->f_mapping;
-			int res;
-			/* do we support this mess? */
-			if (!mapping->a_ops->bmap)
-				return -EINVAL;
-			if (!capable(CAP_SYS_RAWIO))
-				return -EPERM;
-			if ((error = get_user(block, p)) != 0)
-				return error;
-
-			res = mapping->a_ops->bmap(mapping, block);
-			return put_user(res, p);
-		}
-		case FIGETBSZ:
-			if (inode->i_sb == NULL)
-				return -EBADF;
-			return put_user(inode->i_sb->s_blocksize, p);
-		case FIONREAD:
-			return put_user(i_size_read(inode) - filp->f_pos, p);
-	}
-	if (filp->f_op && filp->f_op->ioctl)
-		return filp->f_op->ioctl(inode, filp, cmd, arg);
-	return -ENOTTY;
-}
-
-
 asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 {	
-	struct file * filp;
+	struct inode *inode;
+	struct file *filp;
 	unsigned int flag;
+	int __user *p = (int __user *)arg;
 	int on, error = -EBADF;
 
 	filp = fget(fd);
@@ -68,71 +34,107 @@ asmlinkage long sys_ioctl(unsigned int f
                 goto out;
         }
 
+	inode = filp->f_dentry->d_inode;
 	lock_kernel();
 	switch (cmd) {
-		case FIOCLEX:
-			set_close_on_exec(fd, 1);
-			break;
-
-		case FIONCLEX:
-			set_close_on_exec(fd, 0);
-			break;
-
-		case FIONBIO:
-			if ((error = get_user(on, (int __user *)arg)) != 0)
-				break;
-			flag = O_NONBLOCK;
+	case FIOCLEX:
+		set_close_on_exec(fd, 1);
+		goto done;
+	case FIONCLEX:
+		set_close_on_exec(fd, 0);
+		goto done;
+	case FIONBIO:
+		if ((error = get_user(on, (int __user *)arg)) != 0)
+			goto done;
+		flag = O_NONBLOCK;
 #ifdef __sparc__
-			/* SunOS compatibility item. */
-			if(O_NONBLOCK != O_NDELAY)
-				flag |= O_NDELAY;
+		/* SunOS compatibility item. */
+		if(O_NONBLOCK != O_NDELAY)
+			flag |= O_NDELAY;
 #endif
-			if (on)
-				filp->f_flags |= flag;
+		if (on)
+			filp->f_flags |= flag;
+		else
+			filp->f_flags &= ~flag;
+		goto done;
+	case FIOASYNC:
+		if ((error = get_user(on, (int __user *)arg)) != 0)
+			goto done;
+		flag = on ? FASYNC : 0;
+
+		/* Did FASYNC state change ? */
+		if ((flag ^ filp->f_flags) & FASYNC) {
+			if (filp->f_op && filp->f_op->fasync)
+				error = filp->f_op->fasync(fd, filp, on);
 			else
-				filp->f_flags &= ~flag;
-			break;
-
-		case FIOASYNC:
-			if ((error = get_user(on, (int __user *)arg)) != 0)
-				break;
-			flag = on ? FASYNC : 0;
-
-			/* Did FASYNC state change ? */
-			if ((flag ^ filp->f_flags) & FASYNC) {
-				if (filp->f_op && filp->f_op->fasync)
-					error = filp->f_op->fasync(fd, filp, on);
-				else error = -ENOTTY;
-			}
-			if (error != 0)
-				break;
+				error = -ENOTTY;
+		}
+		if (error != 0)
+			goto done;
 
-			if (on)
-				filp->f_flags |= FASYNC;
-			else
-				filp->f_flags &= ~FASYNC;
-			break;
+		if (on)
+			filp->f_flags |= FASYNC;
+		else
+			filp->f_flags &= ~FASYNC;
+		goto done;
+	case FIOQSIZE:
+		error = -ENOTTY;
+		if (S_ISDIR(inode->i_mode) || S_ISREG(inode->i_mode) ||
+				S_ISLNK(inode->i_mode)) {
+			loff_t res = inode_get_bytes(inode);
+			error = put_user(res, (loff_t __user *)arg);
+		}
+		goto done;
+	case FIBMAP:
+		{
+			struct address_space *mapping = filp->f_mapping;
+			int block;
+			int res;
 
-		case FIOQSIZE:
-			if (S_ISDIR(filp->f_dentry->d_inode->i_mode) ||
-			    S_ISREG(filp->f_dentry->d_inode->i_mode) ||
-			    S_ISLNK(filp->f_dentry->d_inode->i_mode)) {
-				loff_t res = inode_get_bytes(filp->f_dentry->d_inode);
-				error = copy_to_user((loff_t __user *)arg, &res, sizeof(res)) ? -EFAULT : 0;
-			}
-			else
+			if (!S_ISREG(inode->i_mode)) {
 				error = -ENOTTY;
-			break;
-		default:
+				goto done;
+			}
+			/* do we support this mess? */
+			if (!mapping->a_ops->bmap) {
+				error = -EINVAL;
+				goto done;
+			}
+			if (!capable(CAP_SYS_RAWIO)) {
+				error = -EPERM;
+				goto done;
+			}
+			if ((error = get_user(block, p)))
+				goto done;
+
+			res = mapping->a_ops->bmap(mapping, block);
+			error = put_user(res, p);
+			goto done;
+		}
+	case FIGETBSZ:
+		if (!S_ISREG(inode->i_mode)) {
+			error = -ENOTTY;
+			goto done;
+		}
+		error = -EBADF;
+		if (inode->i_sb)
+			error = put_user(inode->i_sb->s_blocksize, p);
+		goto done;
+	case FIONREAD:
+		if (!S_ISREG(inode->i_mode)) {
 			error = -ENOTTY;
-			if (S_ISREG(filp->f_dentry->d_inode->i_mode))
-				error = file_ioctl(filp, cmd, arg);
-			else if (filp->f_op && filp->f_op->ioctl)
-				error = filp->f_op->ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
+			goto done;
+		}
+		error = put_user(i_size_read(inode) - filp->f_pos, p);
+		goto done;
 	}
+
+	error = -ENOTTY;
+	if (filp->f_op && filp->f_op->ioctl)
+		error = filp->f_op->ioctl(inode, filp, cmd, arg);
+done:
 	unlock_kernel();
 	fput(filp);
-
 out:
 	return error;
 }
_