aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_ioctl.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@infradead.org>2007-08-27 23:59:03 -0400
committerTim Shimmin <tes@chook.melbourne.sgi.com>2007-10-15 02:50:13 -0400
commit804c83c37607efe415774c3a170ad72a789e5992 (patch)
treef53df9e59968cf16904e7652bca7e2a7cd3da57b /fs/xfs/linux-2.6/xfs_ioctl.c
parent051e7cd44ab8f0f7c2958371485b4a1ff64a8d1b (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/xfs_ioctl.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c63
1 files changed, 45 insertions, 18 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(
349 return new_fd; 349 return new_fd;
350} 350}
351 351
352/*
353 * This is a copy from fs/namei.c:vfs_readlink(), except for removing it's
354 * unused first argument.
355 */
356STATIC int
357do_readlink(
358 char __user *buffer,
359 int buflen,
360 const char *link)
361{
362 int len;
363
364 len = PTR_ERR(link);
365 if (IS_ERR(link))
366 goto out;
367
368 len = strlen(link);
369 if (len > (unsigned) buflen)
370 len = buflen;
371 if (copy_to_user(buffer, link, len))
372 len = -EFAULT;
373 out:
374 return len;
375}
376
377
352STATIC int 378STATIC int
353xfs_readlink_by_handle( 379xfs_readlink_by_handle(
354 xfs_mount_t *mp, 380 xfs_mount_t *mp,
355 void __user *arg, 381 void __user *arg,
356 struct inode *parinode) 382 struct inode *parinode)
357{ 383{
358 int error;
359 struct iovec aiov;
360 struct uio auio;
361 struct inode *inode; 384 struct inode *inode;
362 xfs_fsop_handlereq_t hreq; 385 xfs_fsop_handlereq_t hreq;
363 bhv_vnode_t *vp; 386 bhv_vnode_t *vp;
364 __u32 olen; 387 __u32 olen;
388 void *link;
389 int error;
365 390
366 if (!capable(CAP_SYS_ADMIN)) 391 if (!capable(CAP_SYS_ADMIN))
367 return -XFS_ERROR(EPERM); 392 return -XFS_ERROR(EPERM);
@@ -374,29 +399,31 @@ xfs_readlink_by_handle(
374 399
375 /* Restrict this handle operation to symlinks only. */ 400 /* Restrict this handle operation to symlinks only. */
376 if (!S_ISLNK(inode->i_mode)) { 401 if (!S_ISLNK(inode->i_mode)) {
377 VN_RELE(vp); 402 error = -XFS_ERROR(EINVAL);
378 return -XFS_ERROR(EINVAL); 403 goto out_iput;
379 } 404 }
380 405
381 if (copy_from_user(&olen, hreq.ohandlen, sizeof(__u32))) { 406 if (copy_from_user(&olen, hreq.ohandlen, sizeof(__u32))) {
382 VN_RELE(vp); 407 error = -XFS_ERROR(EFAULT);
383 return -XFS_ERROR(EFAULT); 408 goto out_iput;
384 } 409 }
385 aiov.iov_len = olen;
386 aiov.iov_base = hreq.ohandle;
387 410
388 auio.uio_iov = (struct kvec *)&aiov; 411 link = kmalloc(MAXPATHLEN+1, GFP_KERNEL);
389 auio.uio_iovcnt = 1; 412 if (!link)
390 auio.uio_offset = 0; 413 goto out_iput;
391 auio.uio_segflg = UIO_USERSPACE;
392 auio.uio_resid = olen;
393 414
394 error = bhv_vop_readlink(vp, &auio, IO_INVIS, NULL); 415 error = -bhv_vop_readlink(vp, link);
395 VN_RELE(vp);
396 if (error) 416 if (error)
397 return -error; 417 goto out_kfree;
418 error = do_readlink(hreq.ohandle, olen, link);
419 if (error)
420 goto out_kfree;
398 421
399 return (olen - auio.uio_resid); 422 out_kfree:
423 kfree(link);
424 out_iput:
425 iput(inode);
426 return error;
400} 427}
401 428
402STATIC int 429STATIC int