diff options
author | Christoph Hellwig <hch@infradead.org> | 2007-08-28 13:59:03 +1000 |
---|---|---|
committer | Tim Shimmin <tes@chook.melbourne.sgi.com> | 2007-10-15 16:50:13 +1000 |
commit | 804c83c37607efe415774c3a170ad72a789e5992 (patch) | |
tree | f53df9e59968cf16904e7652bca7e2a7cd3da57b /fs/xfs/linux-2.6 | |
parent | 051e7cd44ab8f0f7c2958371485b4a1ff64a8d1b (diff) |
[XFS] stop using uio in the readlink code
Simplify the readlink code to get rid of the last user of uio.
SGI-PV: 968563
SGI-Modid: xfs-linux-melb:xfs-kern:29479a
Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: David Chinner <dgc@sgi.com>
Signed-off-by: Tim Shimmin <tes@sgi.com>
Diffstat (limited to 'fs/xfs/linux-2.6')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_ioctl.c | 63 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_iops.c | 50 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_vnode.h | 8 |
3 files changed, 61 insertions, 60 deletions
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index 5917808abbd6..47cfde6cfae2 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c @@ -349,19 +349,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 +399,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 = -bhv_vop_readlink(vp, 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 diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 0b5fa124bef2..ef941f99b2bc 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c @@ -542,50 +542,26 @@ xfs_vn_follow_link( struct dentry *dentry, struct nameidata *nd) { - bhv_vnode_t *vp; - uio_t *uio; - iovec_t iov; - int error; + bhv_vnode_t *vp = vn_from_inode(dentry->d_inode); char *link; - - ASSERT(dentry); - ASSERT(nd); + int error = -ENOMEM; link = kmalloc(MAXPATHLEN+1, GFP_KERNEL); - if (!link) { - nd_set_link(nd, ERR_PTR(-ENOMEM)); - return NULL; - } - - uio = kmalloc(sizeof(uio_t), GFP_KERNEL); - if (!uio) { - kfree(link); - nd_set_link(nd, ERR_PTR(-ENOMEM)); - return NULL; - } - - vp = vn_from_inode(dentry->d_inode); + if (!link) + goto out_err; - iov.iov_base = link; - iov.iov_len = MAXPATHLEN; - - uio->uio_iov = &iov; - uio->uio_offset = 0; - uio->uio_segflg = UIO_SYSSPACE; - uio->uio_resid = MAXPATHLEN; - uio->uio_iovcnt = 1; - - error = bhv_vop_readlink(vp, uio, 0, NULL); - if (unlikely(error)) { - kfree(link); - link = ERR_PTR(-error); - } else { - link[MAXPATHLEN - uio->uio_resid] = '\0'; - } - kfree(uio); + error = -bhv_vop_readlink(vp, link); + if (unlikely(error)) + goto out_kfree; nd_set_link(nd, link); return NULL; + + out_kfree: + kfree(link); + out_err: + nd_set_link(nd, ERR_PTR(error)); + return NULL; } STATIC void diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index 146c84ba6941..bddbdb904234 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h @@ -18,7 +18,6 @@ #ifndef __XFS_VNODE_H__ #define __XFS_VNODE_H__ -struct uio; struct file; struct bhv_vfs; struct bhv_vattr; @@ -165,8 +164,7 @@ typedef int (*vop_readdir_t)(bhv_desc_t *, void *dirent, size_t bufsize, xfs_off_t *offset, filldir_t filldir); typedef int (*vop_symlink_t)(bhv_desc_t *, bhv_vname_t *, struct bhv_vattr*, char *, bhv_vnode_t **, struct cred *); -typedef int (*vop_readlink_t)(bhv_desc_t *, struct uio *, int, - struct cred *); +typedef int (*vop_readlink_t)(bhv_desc_t *, char *); typedef int (*vop_fsync_t)(bhv_desc_t *, int, struct cred *, xfs_off_t, xfs_off_t); typedef int (*vop_inactive_t)(bhv_desc_t *, struct cred *); @@ -271,8 +269,8 @@ typedef struct bhv_vnodeops { VOP(vop_readdir, vp)(VNHEAD(vp),dirent,bufsize,offset,filldir) #define bhv_vop_symlink(dvp,d,vap,tnm,vpp,cr) \ VOP(vop_symlink, dvp)(VNHEAD(dvp),d,vap,tnm,vpp,cr) -#define bhv_vop_readlink(vp,uiop,fl,cr) \ - VOP(vop_readlink, vp)(VNHEAD(vp),uiop,fl,cr) +#define bhv_vop_readlink(vp,link) \ + VOP(vop_readlink, vp)(VNHEAD(vp), link) #define bhv_vop_fsync(vp,f,cr,b,e) VOP(vop_fsync, vp)(VNHEAD(vp),f,cr,b,e) #define bhv_vop_inactive(vp,cr) VOP(vop_inactive, vp)(VNHEAD(vp),cr) #define bhv_vop_release(vp) VOP(vop_release, vp)(VNHEAD(vp)) |