diff options
author | sandeen@sandeen.net <sandeen@sandeen.net> | 2008-11-25 22:20:15 -0500 |
---|---|---|
committer | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-12-02 01:17:07 -0500 |
commit | 28750975ace79c547407a84d3969cbed516be8f8 (patch) | |
tree | 79707c1e3c304ec7a11ea920cda38760d0248d5c /fs/xfs/linux-2.6/xfs_ioctl32.c | |
parent | ebeecd2b04645a4b79e1bc00d69cf4f98e03a684 (diff) |
[XFS] Hook up compat XFS_IOC_ATTRMULTI_BY_HANDLE ioctl handler
Add a compat handler for XFS_IOC_ATTRMULTI_BY_HANDLE
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_ioctl32.c')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_ioctl32.c | 94 |
1 files changed, 90 insertions, 4 deletions
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c index e7eb0d7e0d56..17993352aa64 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl32.c +++ b/fs/xfs/linux-2.6/xfs_ioctl32.c | |||
@@ -476,6 +476,93 @@ xfs_compat_attrlist_by_handle( | |||
476 | return -error; | 476 | return -error; |
477 | } | 477 | } |
478 | 478 | ||
479 | STATIC int | ||
480 | xfs_compat_attrmulti_by_handle( | ||
481 | xfs_mount_t *mp, | ||
482 | void __user *arg, | ||
483 | struct inode *parinode) | ||
484 | { | ||
485 | int error; | ||
486 | compat_xfs_attr_multiop_t *ops; | ||
487 | compat_xfs_fsop_attrmulti_handlereq_t am_hreq; | ||
488 | struct inode *inode; | ||
489 | unsigned int i, size; | ||
490 | char *attr_name; | ||
491 | |||
492 | if (!capable(CAP_SYS_ADMIN)) | ||
493 | return -XFS_ERROR(EPERM); | ||
494 | if (copy_from_user(&am_hreq, arg, | ||
495 | sizeof(compat_xfs_fsop_attrmulti_handlereq_t))) | ||
496 | return -XFS_ERROR(EFAULT); | ||
497 | |||
498 | error = xfs_vget_fsop_handlereq_compat(mp, parinode, &am_hreq.hreq, | ||
499 | &inode); | ||
500 | if (error) | ||
501 | goto out; | ||
502 | |||
503 | error = E2BIG; | ||
504 | size = am_hreq.opcount * sizeof(compat_xfs_attr_multiop_t); | ||
505 | if (!size || size > 16 * PAGE_SIZE) | ||
506 | goto out_vn_rele; | ||
507 | |||
508 | error = ENOMEM; | ||
509 | ops = kmalloc(size, GFP_KERNEL); | ||
510 | if (!ops) | ||
511 | goto out_vn_rele; | ||
512 | |||
513 | error = EFAULT; | ||
514 | if (copy_from_user(ops, compat_ptr(am_hreq.ops), size)) | ||
515 | goto out_kfree_ops; | ||
516 | |||
517 | attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL); | ||
518 | if (!attr_name) | ||
519 | goto out_kfree_ops; | ||
520 | |||
521 | |||
522 | error = 0; | ||
523 | for (i = 0; i < am_hreq.opcount; i++) { | ||
524 | ops[i].am_error = strncpy_from_user(attr_name, | ||
525 | compat_ptr(ops[i].am_attrname), | ||
526 | MAXNAMELEN); | ||
527 | if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN) | ||
528 | error = -ERANGE; | ||
529 | if (ops[i].am_error < 0) | ||
530 | break; | ||
531 | |||
532 | switch (ops[i].am_opcode) { | ||
533 | case ATTR_OP_GET: | ||
534 | ops[i].am_error = xfs_attrmulti_attr_get(inode, | ||
535 | attr_name, | ||
536 | compat_ptr(ops[i].am_attrvalue), | ||
537 | &ops[i].am_length, ops[i].am_flags); | ||
538 | break; | ||
539 | case ATTR_OP_SET: | ||
540 | ops[i].am_error = xfs_attrmulti_attr_set(inode, | ||
541 | attr_name, | ||
542 | compat_ptr(ops[i].am_attrvalue), | ||
543 | ops[i].am_length, ops[i].am_flags); | ||
544 | break; | ||
545 | case ATTR_OP_REMOVE: | ||
546 | ops[i].am_error = xfs_attrmulti_attr_remove(inode, | ||
547 | attr_name, ops[i].am_flags); | ||
548 | break; | ||
549 | default: | ||
550 | ops[i].am_error = EINVAL; | ||
551 | } | ||
552 | } | ||
553 | |||
554 | if (copy_to_user(compat_ptr(am_hreq.ops), ops, size)) | ||
555 | error = XFS_ERROR(EFAULT); | ||
556 | |||
557 | kfree(attr_name); | ||
558 | out_kfree_ops: | ||
559 | kfree(ops); | ||
560 | out_vn_rele: | ||
561 | iput(inode); | ||
562 | out: | ||
563 | return -error; | ||
564 | } | ||
565 | |||
479 | STATIC long | 566 | STATIC long |
480 | xfs_compat_ioctl( | 567 | xfs_compat_ioctl( |
481 | xfs_inode_t *ip, | 568 | xfs_inode_t *ip, |
@@ -499,10 +586,7 @@ xfs_compat_ioctl( | |||
499 | case XFS_IOC_GETBMAP: | 586 | case XFS_IOC_GETBMAP: |
500 | case XFS_IOC_GETBMAPA: | 587 | case XFS_IOC_GETBMAPA: |
501 | case XFS_IOC_GETBMAPX: | 588 | case XFS_IOC_GETBMAPX: |
502 | /* not handled | 589 | /* case XFS_IOC_FSSETDM_BY_HANDLE: not handled */ |
503 | case XFS_IOC_FSSETDM_BY_HANDLE: | ||
504 | case XFS_IOC_ATTRMULTI_BY_HANDLE: | ||
505 | */ | ||
506 | case XFS_IOC_FSCOUNTS: | 590 | case XFS_IOC_FSCOUNTS: |
507 | case XFS_IOC_SET_RESBLKS: | 591 | case XFS_IOC_SET_RESBLKS: |
508 | case XFS_IOC_GET_RESBLKS: | 592 | case XFS_IOC_GET_RESBLKS: |
@@ -610,6 +694,8 @@ xfs_compat_ioctl( | |||
610 | } | 694 | } |
611 | case XFS_IOC_ATTRLIST_BY_HANDLE_32: | 695 | case XFS_IOC_ATTRLIST_BY_HANDLE_32: |
612 | return xfs_compat_attrlist_by_handle(mp, arg, inode); | 696 | return xfs_compat_attrlist_by_handle(mp, arg, inode); |
697 | case XFS_IOC_ATTRMULTI_BY_HANDLE_32: | ||
698 | return xfs_compat_attrmulti_by_handle(mp, arg, inode); | ||
613 | default: | 699 | default: |
614 | return -XFS_ERROR(ENOIOCTLCMD); | 700 | return -XFS_ERROR(ENOIOCTLCMD); |
615 | } | 701 | } |