[XFS] Move copy_from_user calls out of ioctl helpers into ioctl switch.
[safe/jmp/linux-2.6] / fs / xfs / linux-2.6 / xfs_ioctl.c
index 534b175..03c55b8 100644 (file)
 STATIC int
 xfs_find_handle(
        unsigned int            cmd,
-       void                    __user *arg)
+       xfs_fsop_handlereq_t    *hreq)
 {
        int                     hsize;
        xfs_handle_t            handle;
-       xfs_fsop_handlereq_t    hreq;
        struct inode            *inode;
 
-       if (copy_from_user(&hreq, arg, sizeof(hreq)))
-               return -XFS_ERROR(EFAULT);
-
        memset((char *)&handle, 0, sizeof(handle));
 
        switch (cmd) {
        case XFS_IOC_PATH_TO_FSHANDLE:
        case XFS_IOC_PATH_TO_HANDLE: {
                struct path path;
-               int error = user_lpath((const char __user *)hreq.path, &path);
+               int error = user_lpath((const char __user *)hreq->path, &path);
                if (error)
                        return error;
 
@@ -101,7 +97,7 @@ xfs_find_handle(
        case XFS_IOC_FD_TO_HANDLE: {
                struct file     *file;
 
-               file = fget(hreq.fd);
+               file = fget(hreq->fd);
                if (!file)
                    return -EBADF;
 
@@ -158,8 +154,8 @@ xfs_find_handle(
        }
 
        /* now copy our handle into the user buffer & write out the size */
-       if (copy_to_user(hreq.ohandle, &handle, hsize) ||
-           copy_to_user(hreq.ohandlen, &hsize, sizeof(__s32))) {
+       if (copy_to_user(hreq->ohandle, &handle, hsize) ||
+           copy_to_user(hreq->ohandlen, &hsize, sizeof(__s32))) {
                iput(inode);
                return -XFS_ERROR(EFAULT);
        }
@@ -252,7 +248,7 @@ xfs_vget_fsop_handlereq(
 STATIC int
 xfs_open_by_handle(
        xfs_mount_t             *mp,
-       void                    __user *arg,
+       xfs_fsop_handlereq_t    *hreq,
        struct file             *parfilp,
        struct inode            *parinode)
 {
@@ -262,14 +258,11 @@ xfs_open_by_handle(
        struct file             *filp;
        struct inode            *inode;
        struct dentry           *dentry;
-       xfs_fsop_handlereq_t    hreq;
 
        if (!capable(CAP_SYS_ADMIN))
                return -XFS_ERROR(EPERM);
-       if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
-               return -XFS_ERROR(EFAULT);
 
-       error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &inode);
+       error = xfs_vget_fsop_handlereq(mp, parinode, hreq, &inode);
        if (error)
                return -error;
 
@@ -280,10 +273,10 @@ xfs_open_by_handle(
        }
 
 #if BITS_PER_LONG != 32
-       hreq.oflags |= O_LARGEFILE;
+       hreq->oflags |= O_LARGEFILE;
 #endif
        /* Put open permission in namei format. */
-       permflag = hreq.oflags;
+       permflag = hreq->oflags;
        if ((permflag+1) & O_ACCMODE)
                permflag++;
        if (permflag & O_TRUNC)
@@ -321,7 +314,7 @@ xfs_open_by_handle(
        mntget(parfilp->f_path.mnt);
 
        /* Create file pointer. */
-       filp = dentry_open(dentry, parfilp->f_path.mnt, hreq.oflags);
+       filp = dentry_open(dentry, parfilp->f_path.mnt, hreq->oflags);
        if (IS_ERR(filp)) {
                put_unused_fd(new_fd);
                return -XFS_ERROR(-PTR_ERR(filp));
@@ -365,21 +358,18 @@ do_readlink(
 STATIC int
 xfs_readlink_by_handle(
        xfs_mount_t             *mp,
-       void                    __user *arg,
+       xfs_fsop_handlereq_t    *hreq,
        struct inode            *parinode)
 {
        struct inode            *inode;
-       xfs_fsop_handlereq_t    hreq;
        __u32                   olen;
        void                    *link;
        int                     error;
 
        if (!capable(CAP_SYS_ADMIN))
                return -XFS_ERROR(EPERM);
-       if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
-               return -XFS_ERROR(EFAULT);
 
-       error = xfs_vget_fsop_handlereq(mp, parinode, &hreq, &inode);
+       error = xfs_vget_fsop_handlereq(mp, parinode, hreq, &inode);
        if (error)
                return -error;
 
@@ -389,7 +379,7 @@ xfs_readlink_by_handle(
                goto out_iput;
        }
 
-       if (copy_from_user(&olen, hreq.ohandlen, sizeof(__u32))) {
+       if (copy_from_user(&olen, hreq->ohandlen, sizeof(__u32))) {
                error = -XFS_ERROR(EFAULT);
                goto out_iput;
        }
@@ -401,7 +391,7 @@ xfs_readlink_by_handle(
        error = -xfs_readlink(XFS_I(inode), link);
        if (error)
                goto out_kfree;
-       error = do_readlink(hreq.ohandle, olen, link);
+       error = do_readlink(hreq->ohandle, olen, link);
        if (error)
                goto out_kfree;
 
@@ -668,12 +658,19 @@ xfs_ioc_space(
        struct file             *filp,
        int                     ioflags,
        unsigned int            cmd,
-       void                    __user *arg)
+       xfs_flock64_t           *bf)
 {
-       xfs_flock64_t           bf;
        int                     attr_flags = 0;
        int                     error;
 
+       /*
+        * Only allow the sys admin to reserve space unless
+        * unwritten extents are enabled.
+        */
+       if (!xfs_sb_version_hasextflgbit(&ip->i_mount->m_sb) &&
+           !capable(CAP_SYS_ADMIN))
+               return -XFS_ERROR(EPERM);
+
        if (inode->i_flags & (S_IMMUTABLE|S_APPEND))
                return -XFS_ERROR(EPERM);
 
@@ -683,15 +680,12 @@ xfs_ioc_space(
        if (!S_ISREG(inode->i_mode))
                return -XFS_ERROR(EINVAL);
 
-       if (copy_from_user(&bf, arg, sizeof(bf)))
-               return -XFS_ERROR(EFAULT);
-
        if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
                attr_flags |= XFS_ATTR_NONBLOCK;
        if (ioflags & IO_INVIS)
                attr_flags |= XFS_ATTR_DMI;
 
-       error = xfs_change_file_space(ip, cmd, &bf, filp->f_pos, attr_flags);
+       error = xfs_change_file_space(ip, cmd, bf, filp->f_pos, attr_flags);
        return -error;
 }
 
@@ -1356,17 +1350,13 @@ xfs_ioctl(
        case XFS_IOC_ALLOCSP64:
        case XFS_IOC_FREESP64:
        case XFS_IOC_RESVSP64:
-       case XFS_IOC_UNRESVSP64:
-               /*
-                * Only allow the sys admin to reserve space unless
-                * unwritten extents are enabled.
-                */
-               if (!xfs_sb_version_hasextflgbit(&mp->m_sb) &&
-                   !capable(CAP_SYS_ADMIN))
-                       return -EPERM;
-
-               return xfs_ioc_space(ip, inode, filp, ioflags, cmd, arg);
+       case XFS_IOC_UNRESVSP64: {
+               xfs_flock64_t           bf;
 
+               if (copy_from_user(&bf, arg, sizeof(bf)))
+                       return -XFS_ERROR(EFAULT);
+               return xfs_ioc_space(ip, inode, filp, ioflags, cmd, &bf);
+       }
        case XFS_IOC_DIOINFO: {
                struct dioattr  da;
                xfs_buftarg_t   *target =
@@ -1426,18 +1416,30 @@ xfs_ioctl(
 
        case XFS_IOC_FD_TO_HANDLE:
        case XFS_IOC_PATH_TO_HANDLE:
-       case XFS_IOC_PATH_TO_FSHANDLE:
-               return xfs_find_handle(cmd, arg);
+       case XFS_IOC_PATH_TO_FSHANDLE: {
+               xfs_fsop_handlereq_t    hreq;
 
-       case XFS_IOC_OPEN_BY_HANDLE:
-               return xfs_open_by_handle(mp, arg, filp, inode);
+               if (copy_from_user(&hreq, arg, sizeof(hreq)))
+                       return -XFS_ERROR(EFAULT);
+               return xfs_find_handle(cmd, &hreq);
+       }
+       case XFS_IOC_OPEN_BY_HANDLE: {
+               xfs_fsop_handlereq_t    hreq;
 
+               if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
+                       return -XFS_ERROR(EFAULT);
+               return xfs_open_by_handle(mp, &hreq, filp, inode);
+       }
        case XFS_IOC_FSSETDM_BY_HANDLE:
                return xfs_fssetdm_by_handle(mp, arg, inode);
 
-       case XFS_IOC_READLINK_BY_HANDLE:
-               return xfs_readlink_by_handle(mp, arg, inode);
+       case XFS_IOC_READLINK_BY_HANDLE: {
+               xfs_fsop_handlereq_t    hreq;
 
+               if (copy_from_user(&hreq, arg, sizeof(xfs_fsop_handlereq_t)))
+                       return -XFS_ERROR(EFAULT);
+               return xfs_readlink_by_handle(mp, &hreq, inode);
+       }
        case XFS_IOC_ATTRLIST_BY_HANDLE:
                return xfs_attrlist_by_handle(mp, arg, inode);
 
@@ -1445,7 +1447,11 @@ xfs_ioctl(
                return xfs_attrmulti_by_handle(mp, arg, filp, inode);
 
        case XFS_IOC_SWAPEXT: {
-               error = xfs_swapext((struct xfs_swapext __user *)arg);
+               struct xfs_swapext      sxp;
+
+               if (copy_from_user(&sxp, arg, sizeof(xfs_swapext_t)))
+                       return -XFS_ERROR(EFAULT);
+               error = xfs_swapext(&sxp);
                return -error;
        }
 
@@ -1501,9 +1507,6 @@ xfs_ioctl(
        case XFS_IOC_FSGROWFSDATA: {
                xfs_growfs_data_t in;
 
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EPERM;
-
                if (copy_from_user(&in, arg, sizeof(in)))
                        return -XFS_ERROR(EFAULT);
 
@@ -1514,9 +1517,6 @@ xfs_ioctl(
        case XFS_IOC_FSGROWFSLOG: {
                xfs_growfs_log_t in;
 
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EPERM;
-
                if (copy_from_user(&in, arg, sizeof(in)))
                        return -XFS_ERROR(EFAULT);
 
@@ -1527,9 +1527,6 @@ xfs_ioctl(
        case XFS_IOC_FSGROWFSRT: {
                xfs_growfs_rt_t in;
 
-               if (!capable(CAP_SYS_ADMIN))
-                       return -EPERM;
-
                if (copy_from_user(&in, arg, sizeof(in)))
                        return -XFS_ERROR(EFAULT);