aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_ioctl.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2008-04-24 11:26:50 -0400
committerSteve French <sfrench@us.ibm.com>2008-04-24 11:26:50 -0400
commit36d99df2fb474222ab47fbe8ae7385661033223b (patch)
tree962e068491b752a944f61c454fad3f8619a1ea3f /fs/xfs/linux-2.6/xfs_ioctl.c
parent076d8423a98659a92837b07aa494cb74bfefe77c (diff)
parent3dc5063786b273f1aee545844f6bd4e9651ebffe (diff)
Merge branch 'master' of /pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_ioctl.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c689
1 files changed, 321 insertions, 368 deletions
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index f34bd010eb51..4ddb86b73c6b 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -535,8 +535,6 @@ xfs_attrmulti_attr_set(
535 char *kbuf; 535 char *kbuf;
536 int error = EFAULT; 536 int error = EFAULT;
537 537
538 if (IS_RDONLY(inode))
539 return -EROFS;
540 if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) 538 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
541 return EPERM; 539 return EPERM;
542 if (len > XATTR_SIZE_MAX) 540 if (len > XATTR_SIZE_MAX)
@@ -562,8 +560,6 @@ xfs_attrmulti_attr_remove(
562 char *name, 560 char *name,
563 __uint32_t flags) 561 __uint32_t flags)
564{ 562{
565 if (IS_RDONLY(inode))
566 return -EROFS;
567 if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) 563 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
568 return EPERM; 564 return EPERM;
569 return xfs_attr_remove(XFS_I(inode), name, flags); 565 return xfs_attr_remove(XFS_I(inode), name, flags);
@@ -573,6 +569,7 @@ STATIC int
573xfs_attrmulti_by_handle( 569xfs_attrmulti_by_handle(
574 xfs_mount_t *mp, 570 xfs_mount_t *mp,
575 void __user *arg, 571 void __user *arg,
572 struct file *parfilp,
576 struct inode *parinode) 573 struct inode *parinode)
577{ 574{
578 int error; 575 int error;
@@ -626,13 +623,21 @@ xfs_attrmulti_by_handle(
626 &ops[i].am_length, ops[i].am_flags); 623 &ops[i].am_length, ops[i].am_flags);
627 break; 624 break;
628 case ATTR_OP_SET: 625 case ATTR_OP_SET:
626 ops[i].am_error = mnt_want_write(parfilp->f_path.mnt);
627 if (ops[i].am_error)
628 break;
629 ops[i].am_error = xfs_attrmulti_attr_set(inode, 629 ops[i].am_error = xfs_attrmulti_attr_set(inode,
630 attr_name, ops[i].am_attrvalue, 630 attr_name, ops[i].am_attrvalue,
631 ops[i].am_length, ops[i].am_flags); 631 ops[i].am_length, ops[i].am_flags);
632 mnt_drop_write(parfilp->f_path.mnt);
632 break; 633 break;
633 case ATTR_OP_REMOVE: 634 case ATTR_OP_REMOVE:
635 ops[i].am_error = mnt_want_write(parfilp->f_path.mnt);
636 if (ops[i].am_error)
637 break;
634 ops[i].am_error = xfs_attrmulti_attr_remove(inode, 638 ops[i].am_error = xfs_attrmulti_attr_remove(inode,
635 attr_name, ops[i].am_flags); 639 attr_name, ops[i].am_flags);
640 mnt_drop_write(parfilp->f_path.mnt);
636 break; 641 break;
637 default: 642 default:
638 ops[i].am_error = EINVAL; 643 ops[i].am_error = EINVAL;
@@ -651,314 +656,6 @@ xfs_attrmulti_by_handle(
651 return -error; 656 return -error;
652} 657}
653 658
654/* prototypes for a few of the stack-hungry cases that have
655 * their own functions. Functions are defined after their use
656 * so gcc doesn't get fancy and inline them with -03 */
657
658STATIC int
659xfs_ioc_space(
660 struct xfs_inode *ip,
661 struct inode *inode,
662 struct file *filp,
663 int flags,
664 unsigned int cmd,
665 void __user *arg);
666
667STATIC int
668xfs_ioc_bulkstat(
669 xfs_mount_t *mp,
670 unsigned int cmd,
671 void __user *arg);
672
673STATIC int
674xfs_ioc_fsgeometry_v1(
675 xfs_mount_t *mp,
676 void __user *arg);
677
678STATIC int
679xfs_ioc_fsgeometry(
680 xfs_mount_t *mp,
681 void __user *arg);
682
683STATIC int
684xfs_ioc_xattr(
685 xfs_inode_t *ip,
686 struct file *filp,
687 unsigned int cmd,
688 void __user *arg);
689
690STATIC int
691xfs_ioc_fsgetxattr(
692 xfs_inode_t *ip,
693 int attr,
694 void __user *arg);
695
696STATIC int
697xfs_ioc_getbmap(
698 struct xfs_inode *ip,
699 int flags,
700 unsigned int cmd,
701 void __user *arg);
702
703STATIC int
704xfs_ioc_getbmapx(
705 struct xfs_inode *ip,
706 void __user *arg);
707
708int
709xfs_ioctl(
710 xfs_inode_t *ip,
711 struct file *filp,
712 int ioflags,
713 unsigned int cmd,
714 void __user *arg)
715{
716 struct inode *inode = filp->f_path.dentry->d_inode;
717 xfs_mount_t *mp = ip->i_mount;
718 int error;
719
720 xfs_itrace_entry(XFS_I(inode));
721 switch (cmd) {
722
723 case XFS_IOC_ALLOCSP:
724 case XFS_IOC_FREESP:
725 case XFS_IOC_RESVSP:
726 case XFS_IOC_UNRESVSP:
727 case XFS_IOC_ALLOCSP64:
728 case XFS_IOC_FREESP64:
729 case XFS_IOC_RESVSP64:
730 case XFS_IOC_UNRESVSP64:
731 /*
732 * Only allow the sys admin to reserve space unless
733 * unwritten extents are enabled.
734 */
735 if (!xfs_sb_version_hasextflgbit(&mp->m_sb) &&
736 !capable(CAP_SYS_ADMIN))
737 return -EPERM;
738
739 return xfs_ioc_space(ip, inode, filp, ioflags, cmd, arg);
740
741 case XFS_IOC_DIOINFO: {
742 struct dioattr da;
743 xfs_buftarg_t *target =
744 XFS_IS_REALTIME_INODE(ip) ?
745 mp->m_rtdev_targp : mp->m_ddev_targp;
746
747 da.d_mem = da.d_miniosz = 1 << target->bt_sshift;
748 da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1);
749
750 if (copy_to_user(arg, &da, sizeof(da)))
751 return -XFS_ERROR(EFAULT);
752 return 0;
753 }
754
755 case XFS_IOC_FSBULKSTAT_SINGLE:
756 case XFS_IOC_FSBULKSTAT:
757 case XFS_IOC_FSINUMBERS:
758 return xfs_ioc_bulkstat(mp, cmd, arg);
759
760 case XFS_IOC_FSGEOMETRY_V1:
761 return xfs_ioc_fsgeometry_v1(mp, arg);
762
763 case XFS_IOC_FSGEOMETRY:
764 return xfs_ioc_fsgeometry(mp, arg);
765
766 case XFS_IOC_GETVERSION:
767 return put_user(inode->i_generation, (int __user *)arg);
768
769 case XFS_IOC_FSGETXATTR:
770 return xfs_ioc_fsgetxattr(ip, 0, arg);
771 case XFS_IOC_FSGETXATTRA:
772 return xfs_ioc_fsgetxattr(ip, 1, arg);
773 case XFS_IOC_GETXFLAGS:
774 case XFS_IOC_SETXFLAGS:
775 case XFS_IOC_FSSETXATTR:
776 return xfs_ioc_xattr(ip, filp, cmd, arg);
777
778 case XFS_IOC_FSSETDM: {
779 struct fsdmidata dmi;
780
781 if (copy_from_user(&dmi, arg, sizeof(dmi)))
782 return -XFS_ERROR(EFAULT);
783
784 error = xfs_set_dmattrs(ip, dmi.fsd_dmevmask,
785 dmi.fsd_dmstate);
786 return -error;
787 }
788
789 case XFS_IOC_GETBMAP:
790 case XFS_IOC_GETBMAPA:
791 return xfs_ioc_getbmap(ip, ioflags, cmd, arg);
792
793 case XFS_IOC_GETBMAPX:
794 return xfs_ioc_getbmapx(ip, arg);
795
796 case XFS_IOC_FD_TO_HANDLE:
797 case XFS_IOC_PATH_TO_HANDLE:
798 case XFS_IOC_PATH_TO_FSHANDLE:
799 return xfs_find_handle(cmd, arg);
800
801 case XFS_IOC_OPEN_BY_HANDLE:
802 return xfs_open_by_handle(mp, arg, filp, inode);
803
804 case XFS_IOC_FSSETDM_BY_HANDLE:
805 return xfs_fssetdm_by_handle(mp, arg, inode);
806
807 case XFS_IOC_READLINK_BY_HANDLE:
808 return xfs_readlink_by_handle(mp, arg, inode);
809
810 case XFS_IOC_ATTRLIST_BY_HANDLE:
811 return xfs_attrlist_by_handle(mp, arg, inode);
812
813 case XFS_IOC_ATTRMULTI_BY_HANDLE:
814 return xfs_attrmulti_by_handle(mp, arg, inode);
815
816 case XFS_IOC_SWAPEXT: {
817 error = xfs_swapext((struct xfs_swapext __user *)arg);
818 return -error;
819 }
820
821 case XFS_IOC_FSCOUNTS: {
822 xfs_fsop_counts_t out;
823
824 error = xfs_fs_counts(mp, &out);
825 if (error)
826 return -error;
827
828 if (copy_to_user(arg, &out, sizeof(out)))
829 return -XFS_ERROR(EFAULT);
830 return 0;
831 }
832
833 case XFS_IOC_SET_RESBLKS: {
834 xfs_fsop_resblks_t inout;
835 __uint64_t in;
836
837 if (!capable(CAP_SYS_ADMIN))
838 return -EPERM;
839
840 if (copy_from_user(&inout, arg, sizeof(inout)))
841 return -XFS_ERROR(EFAULT);
842
843 /* input parameter is passed in resblks field of structure */
844 in = inout.resblks;
845 error = xfs_reserve_blocks(mp, &in, &inout);
846 if (error)
847 return -error;
848
849 if (copy_to_user(arg, &inout, sizeof(inout)))
850 return -XFS_ERROR(EFAULT);
851 return 0;
852 }
853
854 case XFS_IOC_GET_RESBLKS: {
855 xfs_fsop_resblks_t out;
856
857 if (!capable(CAP_SYS_ADMIN))
858 return -EPERM;
859
860 error = xfs_reserve_blocks(mp, NULL, &out);
861 if (error)
862 return -error;
863
864 if (copy_to_user(arg, &out, sizeof(out)))
865 return -XFS_ERROR(EFAULT);
866
867 return 0;
868 }
869
870 case XFS_IOC_FSGROWFSDATA: {
871 xfs_growfs_data_t in;
872
873 if (!capable(CAP_SYS_ADMIN))
874 return -EPERM;
875
876 if (copy_from_user(&in, arg, sizeof(in)))
877 return -XFS_ERROR(EFAULT);
878
879 error = xfs_growfs_data(mp, &in);
880 return -error;
881 }
882
883 case XFS_IOC_FSGROWFSLOG: {
884 xfs_growfs_log_t in;
885
886 if (!capable(CAP_SYS_ADMIN))
887 return -EPERM;
888
889 if (copy_from_user(&in, arg, sizeof(in)))
890 return -XFS_ERROR(EFAULT);
891
892 error = xfs_growfs_log(mp, &in);
893 return -error;
894 }
895
896 case XFS_IOC_FSGROWFSRT: {
897 xfs_growfs_rt_t in;
898
899 if (!capable(CAP_SYS_ADMIN))
900 return -EPERM;
901
902 if (copy_from_user(&in, arg, sizeof(in)))
903 return -XFS_ERROR(EFAULT);
904
905 error = xfs_growfs_rt(mp, &in);
906 return -error;
907 }
908
909 case XFS_IOC_FREEZE:
910 if (!capable(CAP_SYS_ADMIN))
911 return -EPERM;
912
913 if (inode->i_sb->s_frozen == SB_UNFROZEN)
914 freeze_bdev(inode->i_sb->s_bdev);
915 return 0;
916
917 case XFS_IOC_THAW:
918 if (!capable(CAP_SYS_ADMIN))
919 return -EPERM;
920 if (inode->i_sb->s_frozen != SB_UNFROZEN)
921 thaw_bdev(inode->i_sb->s_bdev, inode->i_sb);
922 return 0;
923
924 case XFS_IOC_GOINGDOWN: {
925 __uint32_t in;
926
927 if (!capable(CAP_SYS_ADMIN))
928 return -EPERM;
929
930 if (get_user(in, (__uint32_t __user *)arg))
931 return -XFS_ERROR(EFAULT);
932
933 error = xfs_fs_goingdown(mp, in);
934 return -error;
935 }
936
937 case XFS_IOC_ERROR_INJECTION: {
938 xfs_error_injection_t in;
939
940 if (!capable(CAP_SYS_ADMIN))
941 return -EPERM;
942
943 if (copy_from_user(&in, arg, sizeof(in)))
944 return -XFS_ERROR(EFAULT);
945
946 error = xfs_errortag_add(in.errtag, mp);
947 return -error;
948 }
949
950 case XFS_IOC_ERROR_CLEARALL:
951 if (!capable(CAP_SYS_ADMIN))
952 return -EPERM;
953
954 error = xfs_errortag_clearall(mp, 1);
955 return -error;
956
957 default:
958 return -ENOTTY;
959 }
960}
961
962STATIC int 659STATIC int
963xfs_ioc_space( 660xfs_ioc_space(
964 struct xfs_inode *ip, 661 struct xfs_inode *ip,
@@ -1179,85 +876,85 @@ xfs_ioc_fsgetxattr(
1179} 876}
1180 877
1181STATIC int 878STATIC int
1182xfs_ioc_xattr( 879xfs_ioc_fssetxattr(
1183 xfs_inode_t *ip, 880 xfs_inode_t *ip,
1184 struct file *filp, 881 struct file *filp,
1185 unsigned int cmd,
1186 void __user *arg) 882 void __user *arg)
1187{ 883{
1188 struct fsxattr fa; 884 struct fsxattr fa;
1189 struct bhv_vattr *vattr; 885 struct bhv_vattr *vattr;
1190 int error = 0; 886 int error;
1191 int attr_flags; 887 int attr_flags;
1192 unsigned int flags; 888
889 if (copy_from_user(&fa, arg, sizeof(fa)))
890 return -EFAULT;
1193 891
1194 vattr = kmalloc(sizeof(*vattr), GFP_KERNEL); 892 vattr = kmalloc(sizeof(*vattr), GFP_KERNEL);
1195 if (unlikely(!vattr)) 893 if (unlikely(!vattr))
1196 return -ENOMEM; 894 return -ENOMEM;
1197 895
1198 switch (cmd) { 896 attr_flags = 0;
1199 case XFS_IOC_FSSETXATTR: { 897 if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
1200 if (copy_from_user(&fa, arg, sizeof(fa))) { 898 attr_flags |= ATTR_NONBLOCK;
1201 error = -EFAULT;
1202 break;
1203 }
1204 899
1205 attr_flags = 0; 900 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | XFS_AT_PROJID;
1206 if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) 901 vattr->va_xflags = fa.fsx_xflags;
1207 attr_flags |= ATTR_NONBLOCK; 902 vattr->va_extsize = fa.fsx_extsize;
903 vattr->va_projid = fa.fsx_projid;
1208 904
1209 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | XFS_AT_PROJID; 905 error = -xfs_setattr(ip, vattr, attr_flags, NULL);
1210 vattr->va_xflags = fa.fsx_xflags; 906 if (!error)
1211 vattr->va_extsize = fa.fsx_extsize; 907 vn_revalidate(XFS_ITOV(ip)); /* update flags */
1212 vattr->va_projid = fa.fsx_projid; 908 kfree(vattr);
909 return 0;
910}
1213 911
1214 error = xfs_setattr(ip, vattr, attr_flags, NULL); 912STATIC int
1215 if (likely(!error)) 913xfs_ioc_getxflags(
1216 vn_revalidate(XFS_ITOV(ip)); /* update flags */ 914 xfs_inode_t *ip,
1217 error = -error; 915 void __user *arg)
1218 break; 916{
1219 } 917 unsigned int flags;
1220 918
1221 case XFS_IOC_GETXFLAGS: { 919 flags = xfs_di2lxflags(ip->i_d.di_flags);
1222 flags = xfs_di2lxflags(ip->i_d.di_flags); 920 if (copy_to_user(arg, &flags, sizeof(flags)))
1223 if (copy_to_user(arg, &flags, sizeof(flags))) 921 return -EFAULT;
1224 error = -EFAULT; 922 return 0;
1225 break; 923}
1226 }
1227 924
1228 case XFS_IOC_SETXFLAGS: { 925STATIC int
1229 if (copy_from_user(&flags, arg, sizeof(flags))) { 926xfs_ioc_setxflags(
1230 error = -EFAULT; 927 xfs_inode_t *ip,
1231 break; 928 struct file *filp,
1232 } 929 void __user *arg)
930{
931 struct bhv_vattr *vattr;
932 unsigned int flags;
933 int attr_flags;
934 int error;
1233 935
1234 if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \ 936 if (copy_from_user(&flags, arg, sizeof(flags)))
1235 FS_NOATIME_FL | FS_NODUMP_FL | \ 937 return -EFAULT;
1236 FS_SYNC_FL)) {
1237 error = -EOPNOTSUPP;
1238 break;
1239 }
1240 938
1241 attr_flags = 0; 939 if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \
1242 if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) 940 FS_NOATIME_FL | FS_NODUMP_FL | \
1243 attr_flags |= ATTR_NONBLOCK; 941 FS_SYNC_FL))
942 return -EOPNOTSUPP;
1244 943
1245 vattr->va_mask = XFS_AT_XFLAGS; 944 vattr = kmalloc(sizeof(*vattr), GFP_KERNEL);
1246 vattr->va_xflags = xfs_merge_ioc_xflags(flags, 945 if (unlikely(!vattr))
1247 xfs_ip2xflags(ip)); 946 return -ENOMEM;
1248 947
1249 error = xfs_setattr(ip, vattr, attr_flags, NULL); 948 attr_flags = 0;
1250 if (likely(!error)) 949 if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
1251 vn_revalidate(XFS_ITOV(ip)); /* update flags */ 950 attr_flags |= ATTR_NONBLOCK;
1252 error = -error;
1253 break;
1254 }
1255 951
1256 default: 952 vattr->va_mask = XFS_AT_XFLAGS;
1257 error = -ENOTTY; 953 vattr->va_xflags = xfs_merge_ioc_xflags(flags, xfs_ip2xflags(ip));
1258 break;
1259 }
1260 954
955 error = -xfs_setattr(ip, vattr, attr_flags, NULL);
956 if (likely(!error))
957 vn_revalidate(XFS_ITOV(ip)); /* update flags */
1261 kfree(vattr); 958 kfree(vattr);
1262 return error; 959 return error;
1263} 960}
@@ -1332,3 +1029,259 @@ xfs_ioc_getbmapx(
1332 1029
1333 return 0; 1030 return 0;
1334} 1031}
1032
1033int
1034xfs_ioctl(
1035 xfs_inode_t *ip,
1036 struct file *filp,
1037 int ioflags,
1038 unsigned int cmd,
1039 void __user *arg)
1040{
1041 struct inode *inode = filp->f_path.dentry->d_inode;
1042 xfs_mount_t *mp = ip->i_mount;
1043 int error;
1044
1045 xfs_itrace_entry(XFS_I(inode));
1046 switch (cmd) {
1047
1048 case XFS_IOC_ALLOCSP:
1049 case XFS_IOC_FREESP:
1050 case XFS_IOC_RESVSP:
1051 case XFS_IOC_UNRESVSP:
1052 case XFS_IOC_ALLOCSP64:
1053 case XFS_IOC_FREESP64:
1054 case XFS_IOC_RESVSP64:
1055 case XFS_IOC_UNRESVSP64:
1056 /*
1057 * Only allow the sys admin to reserve space unless
1058 * unwritten extents are enabled.
1059 */
1060 if (!xfs_sb_version_hasextflgbit(&mp->m_sb) &&
1061 !capable(CAP_SYS_ADMIN))
1062 return -EPERM;
1063
1064 return xfs_ioc_space(ip, inode, filp, ioflags, cmd, arg);
1065
1066 case XFS_IOC_DIOINFO: {
1067 struct dioattr da;
1068 xfs_buftarg_t *target =
1069 XFS_IS_REALTIME_INODE(ip) ?
1070 mp->m_rtdev_targp : mp->m_ddev_targp;
1071
1072 da.d_mem = da.d_miniosz = 1 << target->bt_sshift;
1073 da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1);
1074
1075 if (copy_to_user(arg, &da, sizeof(da)))
1076 return -XFS_ERROR(EFAULT);
1077 return 0;
1078 }
1079
1080 case XFS_IOC_FSBULKSTAT_SINGLE:
1081 case XFS_IOC_FSBULKSTAT:
1082 case XFS_IOC_FSINUMBERS:
1083 return xfs_ioc_bulkstat(mp, cmd, arg);
1084
1085 case XFS_IOC_FSGEOMETRY_V1:
1086 return xfs_ioc_fsgeometry_v1(mp, arg);
1087
1088 case XFS_IOC_FSGEOMETRY:
1089 return xfs_ioc_fsgeometry(mp, arg);
1090
1091 case XFS_IOC_GETVERSION:
1092 return put_user(inode->i_generation, (int __user *)arg);
1093
1094 case XFS_IOC_FSGETXATTR:
1095 return xfs_ioc_fsgetxattr(ip, 0, arg);
1096 case XFS_IOC_FSGETXATTRA:
1097 return xfs_ioc_fsgetxattr(ip, 1, arg);
1098 case XFS_IOC_FSSETXATTR:
1099 return xfs_ioc_fssetxattr(ip, filp, arg);
1100 case XFS_IOC_GETXFLAGS:
1101 return xfs_ioc_getxflags(ip, arg);
1102 case XFS_IOC_SETXFLAGS:
1103 return xfs_ioc_setxflags(ip, filp, arg);
1104
1105 case XFS_IOC_FSSETDM: {
1106 struct fsdmidata dmi;
1107
1108 if (copy_from_user(&dmi, arg, sizeof(dmi)))
1109 return -XFS_ERROR(EFAULT);
1110
1111 error = xfs_set_dmattrs(ip, dmi.fsd_dmevmask,
1112 dmi.fsd_dmstate);
1113 return -error;
1114 }
1115
1116 case XFS_IOC_GETBMAP:
1117 case XFS_IOC_GETBMAPA:
1118 return xfs_ioc_getbmap(ip, ioflags, cmd, arg);
1119
1120 case XFS_IOC_GETBMAPX:
1121 return xfs_ioc_getbmapx(ip, arg);
1122
1123 case XFS_IOC_FD_TO_HANDLE:
1124 case XFS_IOC_PATH_TO_HANDLE:
1125 case XFS_IOC_PATH_TO_FSHANDLE:
1126 return xfs_find_handle(cmd, arg);
1127
1128 case XFS_IOC_OPEN_BY_HANDLE:
1129 return xfs_open_by_handle(mp, arg, filp, inode);
1130
1131 case XFS_IOC_FSSETDM_BY_HANDLE:
1132 return xfs_fssetdm_by_handle(mp, arg, inode);
1133
1134 case XFS_IOC_READLINK_BY_HANDLE:
1135 return xfs_readlink_by_handle(mp, arg, inode);
1136
1137 case XFS_IOC_ATTRLIST_BY_HANDLE:
1138 return xfs_attrlist_by_handle(mp, arg, inode);
1139
1140 case XFS_IOC_ATTRMULTI_BY_HANDLE:
1141 return xfs_attrmulti_by_handle(mp, arg, filp, inode);
1142
1143 case XFS_IOC_SWAPEXT: {
1144 error = xfs_swapext((struct xfs_swapext __user *)arg);
1145 return -error;
1146 }
1147
1148 case XFS_IOC_FSCOUNTS: {
1149 xfs_fsop_counts_t out;
1150
1151 error = xfs_fs_counts(mp, &out);
1152 if (error)
1153 return -error;
1154
1155 if (copy_to_user(arg, &out, sizeof(out)))
1156 return -XFS_ERROR(EFAULT);
1157 return 0;
1158 }
1159
1160 case XFS_IOC_SET_RESBLKS: {
1161 xfs_fsop_resblks_t inout;
1162 __uint64_t in;
1163
1164 if (!capable(CAP_SYS_ADMIN))
1165 return -EPERM;
1166
1167 if (copy_from_user(&inout, arg, sizeof(inout)))
1168 return -XFS_ERROR(EFAULT);
1169
1170 /* input parameter is passed in resblks field of structure */
1171 in = inout.resblks;
1172 error = xfs_reserve_blocks(mp, &in, &inout);
1173 if (error)
1174 return -error;
1175
1176 if (copy_to_user(arg, &inout, sizeof(inout)))
1177 return -XFS_ERROR(EFAULT);
1178 return 0;
1179 }
1180
1181 case XFS_IOC_GET_RESBLKS: {
1182 xfs_fsop_resblks_t out;
1183
1184 if (!capable(CAP_SYS_ADMIN))
1185 return -EPERM;
1186
1187 error = xfs_reserve_blocks(mp, NULL, &out);
1188 if (error)
1189 return -error;
1190
1191 if (copy_to_user(arg, &out, sizeof(out)))
1192 return -XFS_ERROR(EFAULT);
1193
1194 return 0;
1195 }
1196
1197 case XFS_IOC_FSGROWFSDATA: {
1198 xfs_growfs_data_t in;
1199
1200 if (!capable(CAP_SYS_ADMIN))
1201 return -EPERM;
1202
1203 if (copy_from_user(&in, arg, sizeof(in)))
1204 return -XFS_ERROR(EFAULT);
1205
1206 error = xfs_growfs_data(mp, &in);
1207 return -error;
1208 }
1209
1210 case XFS_IOC_FSGROWFSLOG: {
1211 xfs_growfs_log_t in;
1212
1213 if (!capable(CAP_SYS_ADMIN))
1214 return -EPERM;
1215
1216 if (copy_from_user(&in, arg, sizeof(in)))
1217 return -XFS_ERROR(EFAULT);
1218
1219 error = xfs_growfs_log(mp, &in);
1220 return -error;
1221 }
1222
1223 case XFS_IOC_FSGROWFSRT: {
1224 xfs_growfs_rt_t in;
1225
1226 if (!capable(CAP_SYS_ADMIN))
1227 return -EPERM;
1228
1229 if (copy_from_user(&in, arg, sizeof(in)))
1230 return -XFS_ERROR(EFAULT);
1231
1232 error = xfs_growfs_rt(mp, &in);
1233 return -error;
1234 }
1235
1236 case XFS_IOC_FREEZE:
1237 if (!capable(CAP_SYS_ADMIN))
1238 return -EPERM;
1239
1240 if (inode->i_sb->s_frozen == SB_UNFROZEN)
1241 freeze_bdev(inode->i_sb->s_bdev);
1242 return 0;
1243
1244 case XFS_IOC_THAW:
1245 if (!capable(CAP_SYS_ADMIN))
1246 return -EPERM;
1247 if (inode->i_sb->s_frozen != SB_UNFROZEN)
1248 thaw_bdev(inode->i_sb->s_bdev, inode->i_sb);
1249 return 0;
1250
1251 case XFS_IOC_GOINGDOWN: {
1252 __uint32_t in;
1253
1254 if (!capable(CAP_SYS_ADMIN))
1255 return -EPERM;
1256
1257 if (get_user(in, (__uint32_t __user *)arg))
1258 return -XFS_ERROR(EFAULT);
1259
1260 error = xfs_fs_goingdown(mp, in);
1261 return -error;
1262 }
1263
1264 case XFS_IOC_ERROR_INJECTION: {
1265 xfs_error_injection_t in;
1266
1267 if (!capable(CAP_SYS_ADMIN))
1268 return -EPERM;
1269
1270 if (copy_from_user(&in, arg, sizeof(in)))
1271 return -XFS_ERROR(EFAULT);
1272
1273 error = xfs_errortag_add(in.errtag, mp);
1274 return -error;
1275 }
1276
1277 case XFS_IOC_ERROR_CLEARALL:
1278 if (!capable(CAP_SYS_ADMIN))
1279 return -EPERM;
1280
1281 error = xfs_errortag_clearall(mp, 1);
1282 return -error;
1283
1284 default:
1285 return -ENOTTY;
1286 }
1287}