[XFS] cleanup fid types mess
[sfrench/cifs-2.6.git] / fs / xfs / linux-2.6 / xfs_ioctl.c
index ff5c41ff8d40cd8c67d7609383cac2a8ff529d25..2b34bad48b079c73da80bc47c696d92a51198bd4 100644 (file)
@@ -47,6 +47,7 @@
 #include "xfs_utils.h"
 #include "xfs_dfrag.h"
 #include "xfs_fsops.h"
+#include "xfs_vnodeops.h"
 
 #include <linux/capability.h>
 #include <linux/dcache.h>
@@ -137,7 +138,8 @@ xfs_find_handle(
        vp = vn_from_inode(inode);
 
        /* now we can grab the fsid */
-       memcpy(&handle.ha_fsid, vp->v_vfsp->vfs_altfsid, sizeof(xfs_fsid_t));
+       memcpy(&handle.ha_fsid, XFS_I(inode)->i_mount->m_fixedfsid,
+                       sizeof(xfs_fsid_t));
        hsize = sizeof(xfs_fsid_t);
 
        if (cmd != XFS_IOC_PATH_TO_FSHANDLE) {
@@ -150,11 +152,11 @@ xfs_find_handle(
                lock_mode = xfs_ilock_map_shared(ip);
 
                /* fill in fid section of handle from inode */
-               handle.ha_fid.xfs_fid_len = sizeof(xfs_fid_t) -
-                                           sizeof(handle.ha_fid.xfs_fid_len);
-               handle.ha_fid.xfs_fid_pad = 0;
-               handle.ha_fid.xfs_fid_gen = ip->i_d.di_gen;
-               handle.ha_fid.xfs_fid_ino = ip->i_ino;
+               handle.ha_fid.fid_len = sizeof(xfs_fid_t) -
+                                       sizeof(handle.ha_fid.fid_len);
+               handle.ha_fid.fid_pad = 0;
+               handle.ha_fid.fid_gen = ip->i_d.di_gen;
+               handle.ha_fid.fid_ino = ip->i_ino;
 
                xfs_iunlock_map_shared(ip, lock_mode);
 
@@ -220,10 +222,10 @@ xfs_vget_fsop_handlereq(
        if (hlen < sizeof(*handlep))
                memset(((char *)handlep) + hlen, 0, sizeof(*handlep) - hlen);
        if (hlen > sizeof(handlep->ha_fsid)) {
-               if (handlep->ha_fid.xfs_fid_len !=
-                               (hlen - sizeof(handlep->ha_fsid)
-                                       - sizeof(handlep->ha_fid.xfs_fid_len))
-                   || handlep->ha_fid.xfs_fid_pad)
+               if (handlep->ha_fid.fid_len !=
+                   (hlen - sizeof(handlep->ha_fsid) -
+                           sizeof(handlep->ha_fid.fid_len)) ||
+                   handlep->ha_fid.fid_pad)
                        return XFS_ERROR(EINVAL);
        }
 
@@ -231,9 +233,9 @@ xfs_vget_fsop_handlereq(
         * Crack the handle, obtain the inode # & generation #
         */
        xfid = (struct xfs_fid *)&handlep->ha_fid;
-       if (xfid->xfs_fid_len == sizeof(*xfid) - sizeof(xfid->xfs_fid_len)) {
-               ino  = xfid->xfs_fid_ino;
-               igen = xfid->xfs_fid_gen;
+       if (xfid->fid_len == sizeof(*xfid) - sizeof(xfid->fid_len)) {
+               ino  = xfid->fid_ino;
+               igen = xfid->fid_gen;
        } else {
                return XFS_ERROR(EINVAL);
        }
@@ -349,19 +351,44 @@ xfs_open_by_handle(
        return new_fd;
 }
 
+/*
+ * This is a copy from fs/namei.c:vfs_readlink(), except for removing it's
+ * unused first argument.
+ */
+STATIC int
+do_readlink(
+       char __user             *buffer,
+       int                     buflen,
+       const char              *link)
+{
+        int len;
+
+       len = PTR_ERR(link);
+       if (IS_ERR(link))
+               goto out;
+
+       len = strlen(link);
+       if (len > (unsigned) buflen)
+               len = buflen;
+       if (copy_to_user(buffer, link, len))
+               len = -EFAULT;
+ out:
+       return len;
+}
+
+
 STATIC int
 xfs_readlink_by_handle(
        xfs_mount_t             *mp,
        void                    __user *arg,
        struct inode            *parinode)
 {
-       int                     error;
-       struct iovec            aiov;
-       struct uio              auio;
        struct inode            *inode;
        xfs_fsop_handlereq_t    hreq;
        bhv_vnode_t             *vp;
        __u32                   olen;
+       void                    *link;
+       int                     error;
 
        if (!capable(CAP_SYS_ADMIN))
                return -XFS_ERROR(EPERM);
@@ -374,29 +401,31 @@ xfs_readlink_by_handle(
 
        /* Restrict this handle operation to symlinks only. */
        if (!S_ISLNK(inode->i_mode)) {
-               VN_RELE(vp);
-               return -XFS_ERROR(EINVAL);
+               error = -XFS_ERROR(EINVAL);
+               goto out_iput;
        }
 
        if (copy_from_user(&olen, hreq.ohandlen, sizeof(__u32))) {
-               VN_RELE(vp);
-               return -XFS_ERROR(EFAULT);
+               error = -XFS_ERROR(EFAULT);
+               goto out_iput;
        }
-       aiov.iov_len    = olen;
-       aiov.iov_base   = hreq.ohandle;
 
-       auio.uio_iov    = (struct kvec *)&aiov;
-       auio.uio_iovcnt = 1;
-       auio.uio_offset = 0;
-       auio.uio_segflg = UIO_USERSPACE;
-       auio.uio_resid  = olen;
+       link = kmalloc(MAXPATHLEN+1, GFP_KERNEL);
+       if (!link)
+               goto out_iput;
 
-       error = bhv_vop_readlink(vp, &auio, IO_INVIS, NULL);
-       VN_RELE(vp);
+       error = -xfs_readlink(XFS_I(inode), link);
        if (error)
-               return -error;
+               goto out_kfree;
+       error = do_readlink(hreq.ohandle, olen, link);
+       if (error)
+               goto out_kfree;
 
-       return (olen - auio.uio_resid);
+ out_kfree:
+       kfree(link);
+ out_iput:
+       iput(inode);
+       return error;
 }
 
 STATIC int
@@ -409,7 +438,6 @@ xfs_fssetdm_by_handle(
        struct fsdmidata        fsd;
        xfs_fsop_setdm_handlereq_t dmhreq;
        struct inode            *inode;
-       bhv_desc_t              *bdp;
        bhv_vnode_t             *vp;
 
        if (!capable(CAP_MKNOD))
@@ -431,8 +459,8 @@ xfs_fssetdm_by_handle(
                return -XFS_ERROR(EFAULT);
        }
 
-       bdp = bhv_base_unlocked(VN_BHV_HEAD(vp));
-       error = xfs_set_dmattrs(bdp, fsd.fsd_dmevmask, fsd.fsd_dmstate, NULL);
+       error = xfs_set_dmattrs(xfs_vtoi(vp),
+                       fsd.fsd_dmevmask, fsd.fsd_dmstate);
 
        VN_RELE(vp);
        if (error)
@@ -470,8 +498,8 @@ xfs_attrlist_by_handle(
                goto out_vn_rele;
 
        cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
-       error = bhv_vop_attr_list(vp, kbuf, al_hreq.buflen, al_hreq.flags,
-                                       cursor, NULL);
+       error = xfs_attr_list(XFS_I(inode), kbuf, al_hreq.buflen,
+                                       al_hreq.flags, cursor);
        if (error)
                goto out_kfree;
 
@@ -488,7 +516,7 @@ xfs_attrlist_by_handle(
 
 STATIC int
 xfs_attrmulti_attr_get(
-       bhv_vnode_t             *vp,
+       struct inode            *inode,
        char                    *name,
        char                    __user *ubuf,
        __uint32_t              *len,
@@ -503,7 +531,7 @@ xfs_attrmulti_attr_get(
        if (!kbuf)
                return ENOMEM;
 
-       error = bhv_vop_attr_get(vp, name, kbuf, len, flags, NULL);
+       error = xfs_attr_get(XFS_I(inode), name, kbuf, len, flags, NULL);
        if (error)
                goto out_kfree;
 
@@ -517,7 +545,7 @@ xfs_attrmulti_attr_get(
 
 STATIC int
 xfs_attrmulti_attr_set(
-       bhv_vnode_t             *vp,
+       struct inode            *inode,
        char                    *name,
        const char              __user *ubuf,
        __uint32_t              len,
@@ -526,9 +554,9 @@ xfs_attrmulti_attr_set(
        char                    *kbuf;
        int                     error = EFAULT;
 
-       if (IS_RDONLY(&vp->v_inode))
+       if (IS_RDONLY(inode))
                return -EROFS;
-       if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode))
+       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
                return EPERM;
        if (len > XATTR_SIZE_MAX)
                return EINVAL;
@@ -540,7 +568,7 @@ xfs_attrmulti_attr_set(
        if (copy_from_user(kbuf, ubuf, len))
                goto out_kfree;
                        
-       error = bhv_vop_attr_set(vp, name, kbuf, len, flags, NULL);
+       error = xfs_attr_set(XFS_I(inode), name, kbuf, len, flags);
 
  out_kfree:
        kfree(kbuf);
@@ -549,15 +577,15 @@ xfs_attrmulti_attr_set(
 
 STATIC int
 xfs_attrmulti_attr_remove(
-       bhv_vnode_t             *vp,
+       struct inode            *inode,
        char                    *name,
        __uint32_t              flags)
 {
-       if (IS_RDONLY(&vp->v_inode))
+       if (IS_RDONLY(inode))
                return -EROFS;
-       if (IS_IMMUTABLE(&vp->v_inode) || IS_APPEND(&vp->v_inode))
+       if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
                return EPERM;
-       return bhv_vop_attr_remove(vp, name, flags, NULL);
+       return xfs_attr_remove(XFS_I(inode), name, flags);
 }
 
 STATIC int
@@ -613,17 +641,17 @@ xfs_attrmulti_by_handle(
 
                switch (ops[i].am_opcode) {
                case ATTR_OP_GET:
-                       ops[i].am_error = xfs_attrmulti_attr_get(vp,
+                       ops[i].am_error = xfs_attrmulti_attr_get(inode,
                                        attr_name, ops[i].am_attrvalue,
                                        &ops[i].am_length, ops[i].am_flags);
                        break;
                case ATTR_OP_SET:
-                       ops[i].am_error = xfs_attrmulti_attr_set(vp,
+                       ops[i].am_error = xfs_attrmulti_attr_set(inode,
                                        attr_name, ops[i].am_attrvalue,
                                        ops[i].am_length, ops[i].am_flags);
                        break;
                case ATTR_OP_REMOVE:
-                       ops[i].am_error = xfs_attrmulti_attr_remove(vp,
+                       ops[i].am_error = xfs_attrmulti_attr_remove(inode,
                                        attr_name, ops[i].am_flags);
                        break;
                default:
@@ -649,7 +677,7 @@ xfs_attrmulti_by_handle(
 
 STATIC int
 xfs_ioc_space(
-       bhv_desc_t              *bdp,
+       struct xfs_inode        *ip,
        struct inode            *inode,
        struct file             *filp,
        int                     flags,
@@ -680,38 +708,38 @@ xfs_ioc_xattr(
        unsigned int            cmd,
        void                    __user *arg);
 
+STATIC int
+xfs_ioc_fsgetxattr(
+       xfs_inode_t             *ip,
+       int                     attr,
+       void                    __user *arg);
+
 STATIC int
 xfs_ioc_getbmap(
-       bhv_desc_t              *bdp,
+       struct xfs_inode        *ip,
        int                     flags,
        unsigned int            cmd,
        void                    __user *arg);
 
 STATIC int
 xfs_ioc_getbmapx(
-       bhv_desc_t              *bdp,
+       struct xfs_inode        *ip,
        void                    __user *arg);
 
 int
 xfs_ioctl(
-       bhv_desc_t              *bdp,
-       struct inode            *inode,
+       xfs_inode_t             *ip,
        struct file             *filp,
        int                     ioflags,
        unsigned int            cmd,
        void                    __user *arg)
 {
+       struct inode            *inode = filp->f_path.dentry->d_inode;
+       bhv_vnode_t             *vp = vn_from_inode(inode);
+       xfs_mount_t             *mp = ip->i_mount;
        int                     error;
-       bhv_vnode_t             *vp;
-       xfs_inode_t             *ip;
-       xfs_mount_t             *mp;
 
-       vp = vn_from_inode(inode);
-
-       vn_trace_entry(vp, "xfs_ioctl", (inst_t *)__return_address);
-
-       ip = XFS_BHVTOI(bdp);
-       mp = ip->i_mount;
+       vn_trace_entry(XFS_I(inode), "xfs_ioctl", (inst_t *)__return_address);
 
        switch (cmd) {
 
@@ -731,7 +759,7 @@ xfs_ioctl(
                    !capable(CAP_SYS_ADMIN))
                        return -EPERM;
 
-               return xfs_ioc_space(bdp, inode, filp, ioflags, cmd, arg);
+               return xfs_ioc_space(ip, inode, filp, ioflags, cmd, arg);
 
        case XFS_IOC_DIOINFO: {
                struct dioattr  da;
@@ -761,11 +789,13 @@ xfs_ioctl(
        case XFS_IOC_GETVERSION:
                return put_user(inode->i_generation, (int __user *)arg);
 
+       case XFS_IOC_FSGETXATTR:
+               return xfs_ioc_fsgetxattr(ip, 0, arg);
+       case XFS_IOC_FSGETXATTRA:
+               return xfs_ioc_fsgetxattr(ip, 1, arg);
        case XFS_IOC_GETXFLAGS:
        case XFS_IOC_SETXFLAGS:
-       case XFS_IOC_FSGETXATTR:
        case XFS_IOC_FSSETXATTR:
-       case XFS_IOC_FSGETXATTRA:
                return xfs_ioc_xattr(vp, ip, filp, cmd, arg);
 
        case XFS_IOC_FSSETDM: {
@@ -774,17 +804,17 @@ xfs_ioctl(
                if (copy_from_user(&dmi, arg, sizeof(dmi)))
                        return -XFS_ERROR(EFAULT);
 
-               error = xfs_set_dmattrs(bdp, dmi.fsd_dmevmask, dmi.fsd_dmstate,
-                                                       NULL);
+               error = xfs_set_dmattrs(ip, dmi.fsd_dmevmask,
+                               dmi.fsd_dmstate);
                return -error;
        }
 
        case XFS_IOC_GETBMAP:
        case XFS_IOC_GETBMAPA:
-               return xfs_ioc_getbmap(bdp, ioflags, cmd, arg);
+               return xfs_ioc_getbmap(ip, ioflags, cmd, arg);
 
        case XFS_IOC_GETBMAPX:
-               return xfs_ioc_getbmapx(bdp, arg);
+               return xfs_ioc_getbmapx(ip, arg);
 
        case XFS_IOC_FD_TO_HANDLE:
        case XFS_IOC_PATH_TO_HANDLE:
@@ -944,7 +974,7 @@ xfs_ioctl(
                if (!capable(CAP_SYS_ADMIN))
                        return -EPERM;
 
-               error = xfs_errortag_clearall(mp);
+               error = xfs_errortag_clearall(mp, 1);
                return -error;
 
        default:
@@ -954,7 +984,7 @@ xfs_ioctl(
 
 STATIC int
 xfs_ioc_space(
-       bhv_desc_t              *bdp,
+       struct xfs_inode        *ip,
        struct inode            *inode,
        struct file             *filp,
        int                     ioflags,
@@ -982,7 +1012,7 @@ xfs_ioc_space(
        if (ioflags & IO_INVIS)
                attr_flags |= ATTR_DMI;
 
-       error = xfs_change_file_space(bdp, cmd, &bf, filp->f_pos,
+       error = xfs_change_file_space(ip, cmd, &bf, filp->f_pos,
                                              NULL, attr_flags);
        return -error;
 }
@@ -1019,7 +1049,7 @@ xfs_ioc_bulkstat(
 
        if (cmd == XFS_IOC_FSINUMBERS)
                error = xfs_inumbers(mp, &inlast, &count,
-                                               bulkreq.ubuffer);
+                                       bulkreq.ubuffer, xfs_inumbers_fmt);
        else if (cmd == XFS_IOC_FSBULKSTAT_SINGLE)
                error = xfs_bulkstat_single(mp, &inlast,
                                                bulkreq.ubuffer, &done);
@@ -1139,6 +1169,42 @@ xfs_di2lxflags(
        return flags;
 }
 
+STATIC int
+xfs_ioc_fsgetxattr(
+       xfs_inode_t             *ip,
+       int                     attr,
+       void                    __user *arg)
+{
+       struct fsxattr          fa;
+
+       xfs_ilock(ip, XFS_ILOCK_SHARED);
+       fa.fsx_xflags = xfs_ip2xflags(ip);
+       fa.fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog;
+       fa.fsx_projid = ip->i_d.di_projid;
+
+       if (attr) {
+               if (ip->i_afp) {
+                       if (ip->i_afp->if_flags & XFS_IFEXTENTS)
+                               fa.fsx_nextents = ip->i_afp->if_bytes /
+                                                       sizeof(xfs_bmbt_rec_t);
+                       else
+                               fa.fsx_nextents = ip->i_d.di_anextents;
+               } else
+                       fa.fsx_nextents = 0;
+       } else {
+               if (ip->i_df.if_flags & XFS_IFEXTENTS)
+                       fa.fsx_nextents = ip->i_df.if_bytes /
+                                               sizeof(xfs_bmbt_rec_t);
+               else
+                       fa.fsx_nextents = ip->i_d.di_nextents;
+       }
+       xfs_iunlock(ip, XFS_ILOCK_SHARED);
+
+       if (copy_to_user(arg, &fa, sizeof(fa)))
+               return -EFAULT;
+       return 0;
+}
+
 STATIC int
 xfs_ioc_xattr(
        bhv_vnode_t             *vp,
@@ -1158,27 +1224,6 @@ xfs_ioc_xattr(
                return -ENOMEM;
 
        switch (cmd) {
-       case XFS_IOC_FSGETXATTR: {
-               vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
-                                XFS_AT_NEXTENTS | XFS_AT_PROJID;
-               error = bhv_vop_getattr(vp, vattr, 0, NULL);
-               if (unlikely(error)) {
-                       error = -error;
-                       break;
-               }
-
-               fa.fsx_xflags   = vattr->va_xflags;
-               fa.fsx_extsize  = vattr->va_extsize;
-               fa.fsx_nextents = vattr->va_nextents;
-               fa.fsx_projid   = vattr->va_projid;
-
-               if (copy_to_user(arg, &fa, sizeof(fa))) {
-                       error = -EFAULT;
-                       break;
-               }
-               break;
-       }
-
        case XFS_IOC_FSSETXATTR: {
                if (copy_from_user(&fa, arg, sizeof(fa))) {
                        error = -EFAULT;
@@ -1194,34 +1239,13 @@ xfs_ioc_xattr(
                vattr->va_extsize = fa.fsx_extsize;
                vattr->va_projid  = fa.fsx_projid;
 
-               error = bhv_vop_setattr(vp, vattr, attr_flags, NULL);
+               error = xfs_setattr(ip, vattr, attr_flags, NULL);
                if (likely(!error))
                        __vn_revalidate(vp, vattr);     /* update flags */
                error = -error;
                break;
        }
 
-       case XFS_IOC_FSGETXATTRA: {
-               vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | \
-                                XFS_AT_ANEXTENTS | XFS_AT_PROJID;
-               error = bhv_vop_getattr(vp, vattr, 0, NULL);
-               if (unlikely(error)) {
-                       error = -error;
-                       break;
-               }
-
-               fa.fsx_xflags   = vattr->va_xflags;
-               fa.fsx_extsize  = vattr->va_extsize;
-               fa.fsx_nextents = vattr->va_anextents;
-               fa.fsx_projid   = vattr->va_projid;
-
-               if (copy_to_user(arg, &fa, sizeof(fa))) {
-                       error = -EFAULT;
-                       break;
-               }
-               break;
-       }
-
        case XFS_IOC_GETXFLAGS: {
                flags = xfs_di2lxflags(ip->i_d.di_flags);
                if (copy_to_user(arg, &flags, sizeof(flags)))
@@ -1250,7 +1274,7 @@ xfs_ioc_xattr(
                vattr->va_xflags = xfs_merge_ioc_xflags(flags,
                                                        xfs_ip2xflags(ip));
 
-               error = bhv_vop_setattr(vp, vattr, attr_flags, NULL);
+               error = xfs_setattr(ip, vattr, attr_flags, NULL);
                if (likely(!error))
                        __vn_revalidate(vp, vattr);     /* update flags */
                error = -error;
@@ -1268,7 +1292,7 @@ xfs_ioc_xattr(
 
 STATIC int
 xfs_ioc_getbmap(
-       bhv_desc_t              *bdp,
+       struct xfs_inode        *ip,
        int                     ioflags,
        unsigned int            cmd,
        void                    __user *arg)
@@ -1287,7 +1311,7 @@ xfs_ioc_getbmap(
        if (ioflags & IO_INVIS)
                iflags |= BMV_IF_NO_DMAPI_READ;
 
-       error = xfs_getbmap(bdp, &bm, (struct getbmap __user *)arg+1, iflags);
+       error = xfs_getbmap(ip, &bm, (struct getbmap __user *)arg+1, iflags);
        if (error)
                return -error;
 
@@ -1298,7 +1322,7 @@ xfs_ioc_getbmap(
 
 STATIC int
 xfs_ioc_getbmapx(
-       bhv_desc_t              *bdp,
+       struct xfs_inode        *ip,
        void                    __user *arg)
 {
        struct getbmapx         bmx;
@@ -1325,7 +1349,7 @@ xfs_ioc_getbmapx(
 
        iflags |= BMV_IF_EXTENDED;
 
-       error = xfs_getbmap(bdp, &bm, (struct getbmapx __user *)arg+1, iflags);
+       error = xfs_getbmap(ip, &bm, (struct getbmapx __user *)arg+1, iflags);
        if (error)
                return -error;