aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/linux-2.6/xfs_ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/linux-2.6/xfs_ioctl.c')
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c676
1 files changed, 312 insertions, 364 deletions
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index f34bd010eb51..bf7759793856 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -651,314 +651,6 @@ xfs_attrmulti_by_handle(
651 return -error; 651 return -error;
652} 652}
653 653
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 654STATIC int
963xfs_ioc_space( 655xfs_ioc_space(
964 struct xfs_inode *ip, 656 struct xfs_inode *ip,
@@ -1179,85 +871,85 @@ xfs_ioc_fsgetxattr(
1179} 871}
1180 872
1181STATIC int 873STATIC int
1182xfs_ioc_xattr( 874xfs_ioc_fssetxattr(
1183 xfs_inode_t *ip, 875 xfs_inode_t *ip,
1184 struct file *filp, 876 struct file *filp,
1185 unsigned int cmd,
1186 void __user *arg) 877 void __user *arg)
1187{ 878{
1188 struct fsxattr fa; 879 struct fsxattr fa;
1189 struct bhv_vattr *vattr; 880 struct bhv_vattr *vattr;
1190 int error = 0; 881 int error;
1191 int attr_flags; 882 int attr_flags;
1192 unsigned int flags; 883
884 if (copy_from_user(&fa, arg, sizeof(fa)))
885 return -EFAULT;
1193 886
1194 vattr = kmalloc(sizeof(*vattr), GFP_KERNEL); 887 vattr = kmalloc(sizeof(*vattr), GFP_KERNEL);
1195 if (unlikely(!vattr)) 888 if (unlikely(!vattr))
1196 return -ENOMEM; 889 return -ENOMEM;
1197 890
1198 switch (cmd) { 891 attr_flags = 0;
1199 case XFS_IOC_FSSETXATTR: { 892 if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
1200 if (copy_from_user(&fa, arg, sizeof(fa))) { 893 attr_flags |= ATTR_NONBLOCK;
1201 error = -EFAULT;
1202 break;
1203 }
1204 894
1205 attr_flags = 0; 895 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | XFS_AT_PROJID;
1206 if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) 896 vattr->va_xflags = fa.fsx_xflags;
1207 attr_flags |= ATTR_NONBLOCK; 897 vattr->va_extsize = fa.fsx_extsize;
898 vattr->va_projid = fa.fsx_projid;
1208 899
1209 vattr->va_mask = XFS_AT_XFLAGS | XFS_AT_EXTSIZE | XFS_AT_PROJID; 900 error = -xfs_setattr(ip, vattr, attr_flags, NULL);
1210 vattr->va_xflags = fa.fsx_xflags; 901 if (!error)
1211 vattr->va_extsize = fa.fsx_extsize; 902 vn_revalidate(XFS_ITOV(ip)); /* update flags */
1212 vattr->va_projid = fa.fsx_projid; 903 kfree(vattr);
904 return 0;
905}
1213 906
1214 error = xfs_setattr(ip, vattr, attr_flags, NULL); 907STATIC int
1215 if (likely(!error)) 908xfs_ioc_getxflags(
1216 vn_revalidate(XFS_ITOV(ip)); /* update flags */ 909 xfs_inode_t *ip,
1217 error = -error; 910 void __user *arg)
1218 break; 911{
1219 } 912 unsigned int flags;
1220 913
1221 case XFS_IOC_GETXFLAGS: { 914 flags = xfs_di2lxflags(ip->i_d.di_flags);
1222 flags = xfs_di2lxflags(ip->i_d.di_flags); 915 if (copy_to_user(arg, &flags, sizeof(flags)))
1223 if (copy_to_user(arg, &flags, sizeof(flags))) 916 return -EFAULT;
1224 error = -EFAULT; 917 return 0;
1225 break; 918}
1226 }
1227 919
1228 case XFS_IOC_SETXFLAGS: { 920STATIC int
1229 if (copy_from_user(&flags, arg, sizeof(flags))) { 921xfs_ioc_setxflags(
1230 error = -EFAULT; 922 xfs_inode_t *ip,
1231 break; 923 struct file *filp,
1232 } 924 void __user *arg)
925{
926 struct bhv_vattr *vattr;
927 unsigned int flags;
928 int attr_flags;
929 int error;
1233 930
1234 if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \ 931 if (copy_from_user(&flags, arg, sizeof(flags)))
1235 FS_NOATIME_FL | FS_NODUMP_FL | \ 932 return -EFAULT;
1236 FS_SYNC_FL)) {
1237 error = -EOPNOTSUPP;
1238 break;
1239 }
1240 933
1241 attr_flags = 0; 934 if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \
1242 if (filp->f_flags & (O_NDELAY|O_NONBLOCK)) 935 FS_NOATIME_FL | FS_NODUMP_FL | \
1243 attr_flags |= ATTR_NONBLOCK; 936 FS_SYNC_FL))
937 return -EOPNOTSUPP;
1244 938
1245 vattr->va_mask = XFS_AT_XFLAGS; 939 vattr = kmalloc(sizeof(*vattr), GFP_KERNEL);
1246 vattr->va_xflags = xfs_merge_ioc_xflags(flags, 940 if (unlikely(!vattr))
1247 xfs_ip2xflags(ip)); 941 return -ENOMEM;
1248 942
1249 error = xfs_setattr(ip, vattr, attr_flags, NULL); 943 attr_flags = 0;
1250 if (likely(!error)) 944 if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
1251 vn_revalidate(XFS_ITOV(ip)); /* update flags */ 945 attr_flags |= ATTR_NONBLOCK;
1252 error = -error;
1253 break;
1254 }
1255 946
1256 default: 947 vattr->va_mask = XFS_AT_XFLAGS;
1257 error = -ENOTTY; 948 vattr->va_xflags = xfs_merge_ioc_xflags(flags, xfs_ip2xflags(ip));
1258 break;
1259 }
1260 949
950 error = -xfs_setattr(ip, vattr, attr_flags, NULL);
951 if (likely(!error))
952 vn_revalidate(XFS_ITOV(ip)); /* update flags */
1261 kfree(vattr); 953 kfree(vattr);
1262 return error; 954 return error;
1263} 955}
@@ -1332,3 +1024,259 @@ xfs_ioc_getbmapx(
1332 1024
1333 return 0; 1025 return 0;
1334} 1026}
1027
1028int
1029xfs_ioctl(
1030 xfs_inode_t *ip,
1031 struct file *filp,
1032 int ioflags,
1033 unsigned int cmd,
1034 void __user *arg)
1035{
1036 struct inode *inode = filp->f_path.dentry->d_inode;
1037 xfs_mount_t *mp = ip->i_mount;
1038 int error;
1039
1040 xfs_itrace_entry(XFS_I(inode));
1041 switch (cmd) {
1042
1043 case XFS_IOC_ALLOCSP:
1044 case XFS_IOC_FREESP:
1045 case XFS_IOC_RESVSP:
1046 case XFS_IOC_UNRESVSP:
1047 case XFS_IOC_ALLOCSP64:
1048 case XFS_IOC_FREESP64:
1049 case XFS_IOC_RESVSP64:
1050 case XFS_IOC_UNRESVSP64:
1051 /*
1052 * Only allow the sys admin to reserve space unless
1053 * unwritten extents are enabled.
1054 */
1055 if (!xfs_sb_version_hasextflgbit(&mp->m_sb) &&
1056 !capable(CAP_SYS_ADMIN))
1057 return -EPERM;
1058
1059 return xfs_ioc_space(ip, inode, filp, ioflags, cmd, arg);
1060
1061 case XFS_IOC_DIOINFO: {
1062 struct dioattr da;
1063 xfs_buftarg_t *target =
1064 XFS_IS_REALTIME_INODE(ip) ?
1065 mp->m_rtdev_targp : mp->m_ddev_targp;
1066
1067 da.d_mem = da.d_miniosz = 1 << target->bt_sshift;
1068 da.d_maxiosz = INT_MAX & ~(da.d_miniosz - 1);
1069
1070 if (copy_to_user(arg, &da, sizeof(da)))
1071 return -XFS_ERROR(EFAULT);
1072 return 0;
1073 }
1074
1075 case XFS_IOC_FSBULKSTAT_SINGLE:
1076 case XFS_IOC_FSBULKSTAT:
1077 case XFS_IOC_FSINUMBERS:
1078 return xfs_ioc_bulkstat(mp, cmd, arg);
1079
1080 case XFS_IOC_FSGEOMETRY_V1:
1081 return xfs_ioc_fsgeometry_v1(mp, arg);
1082
1083 case XFS_IOC_FSGEOMETRY:
1084 return xfs_ioc_fsgeometry(mp, arg);
1085
1086 case XFS_IOC_GETVERSION:
1087 return put_user(inode->i_generation, (int __user *)arg);
1088
1089 case XFS_IOC_FSGETXATTR:
1090 return xfs_ioc_fsgetxattr(ip, 0, arg);
1091 case XFS_IOC_FSGETXATTRA:
1092 return xfs_ioc_fsgetxattr(ip, 1, arg);
1093 case XFS_IOC_FSSETXATTR:
1094 return xfs_ioc_fssetxattr(ip, filp, arg);
1095 case XFS_IOC_GETXFLAGS:
1096 return xfs_ioc_getxflags(ip, arg);
1097 case XFS_IOC_SETXFLAGS:
1098 return xfs_ioc_setxflags(ip, filp, arg);
1099
1100 case XFS_IOC_FSSETDM: {
1101 struct fsdmidata dmi;
1102
1103 if (copy_from_user(&dmi, arg, sizeof(dmi)))
1104 return -XFS_ERROR(EFAULT);
1105
1106 error = xfs_set_dmattrs(ip, dmi.fsd_dmevmask,
1107 dmi.fsd_dmstate);
1108 return -error;
1109 }
1110
1111 case XFS_IOC_GETBMAP:
1112 case XFS_IOC_GETBMAPA:
1113 return xfs_ioc_getbmap(ip, ioflags, cmd, arg);
1114
1115 case XFS_IOC_GETBMAPX:
1116 return xfs_ioc_getbmapx(ip, arg);
1117
1118 case XFS_IOC_FD_TO_HANDLE:
1119 case XFS_IOC_PATH_TO_HANDLE:
1120 case XFS_IOC_PATH_TO_FSHANDLE:
1121 return xfs_find_handle(cmd, arg);
1122
1123 case XFS_IOC_OPEN_BY_HANDLE:
1124 return xfs_open_by_handle(mp, arg, filp, inode);
1125
1126 case XFS_IOC_FSSETDM_BY_HANDLE:
1127 return xfs_fssetdm_by_handle(mp, arg, inode);
1128
1129 case XFS_IOC_READLINK_BY_HANDLE:
1130 return xfs_readlink_by_handle(mp, arg, inode);
1131
1132 case XFS_IOC_ATTRLIST_BY_HANDLE:
1133 return xfs_attrlist_by_handle(mp, arg, inode);
1134
1135 case XFS_IOC_ATTRMULTI_BY_HANDLE:
1136 return xfs_attrmulti_by_handle(mp, arg, inode);
1137
1138 case XFS_IOC_SWAPEXT: {
1139 error = xfs_swapext((struct xfs_swapext __user *)arg);
1140 return -error;
1141 }
1142
1143 case XFS_IOC_FSCOUNTS: {
1144 xfs_fsop_counts_t out;
1145
1146 error = xfs_fs_counts(mp, &out);
1147 if (error)
1148 return -error;
1149
1150 if (copy_to_user(arg, &out, sizeof(out)))
1151 return -XFS_ERROR(EFAULT);
1152 return 0;
1153 }
1154
1155 case XFS_IOC_SET_RESBLKS: {
1156 xfs_fsop_resblks_t inout;
1157 __uint64_t in;
1158
1159 if (!capable(CAP_SYS_ADMIN))
1160 return -EPERM;
1161
1162 if (copy_from_user(&inout, arg, sizeof(inout)))
1163 return -XFS_ERROR(EFAULT);
1164
1165 /* input parameter is passed in resblks field of structure */
1166 in = inout.resblks;
1167 error = xfs_reserve_blocks(mp, &in, &inout);
1168 if (error)
1169 return -error;
1170
1171 if (copy_to_user(arg, &inout, sizeof(inout)))
1172 return -XFS_ERROR(EFAULT);
1173 return 0;
1174 }
1175
1176 case XFS_IOC_GET_RESBLKS: {
1177 xfs_fsop_resblks_t out;
1178
1179 if (!capable(CAP_SYS_ADMIN))
1180 return -EPERM;
1181
1182 error = xfs_reserve_blocks(mp, NULL, &out);
1183 if (error)
1184 return -error;
1185
1186 if (copy_to_user(arg, &out, sizeof(out)))
1187 return -XFS_ERROR(EFAULT);
1188
1189 return 0;
1190 }
1191
1192 case XFS_IOC_FSGROWFSDATA: {
1193 xfs_growfs_data_t in;
1194
1195 if (!capable(CAP_SYS_ADMIN))
1196 return -EPERM;
1197
1198 if (copy_from_user(&in, arg, sizeof(in)))
1199 return -XFS_ERROR(EFAULT);
1200
1201 error = xfs_growfs_data(mp, &in);
1202 return -error;
1203 }
1204
1205 case XFS_IOC_FSGROWFSLOG: {
1206 xfs_growfs_log_t in;
1207
1208 if (!capable(CAP_SYS_ADMIN))
1209 return -EPERM;
1210
1211 if (copy_from_user(&in, arg, sizeof(in)))
1212 return -XFS_ERROR(EFAULT);
1213
1214 error = xfs_growfs_log(mp, &in);
1215 return -error;
1216 }
1217
1218 case XFS_IOC_FSGROWFSRT: {
1219 xfs_growfs_rt_t in;
1220
1221 if (!capable(CAP_SYS_ADMIN))
1222 return -EPERM;
1223
1224 if (copy_from_user(&in, arg, sizeof(in)))
1225 return -XFS_ERROR(EFAULT);
1226
1227 error = xfs_growfs_rt(mp, &in);
1228 return -error;
1229 }
1230
1231 case XFS_IOC_FREEZE:
1232 if (!capable(CAP_SYS_ADMIN))
1233 return -EPERM;
1234
1235 if (inode->i_sb->s_frozen == SB_UNFROZEN)
1236 freeze_bdev(inode->i_sb->s_bdev);
1237 return 0;
1238
1239 case XFS_IOC_THAW:
1240 if (!capable(CAP_SYS_ADMIN))
1241 return -EPERM;
1242 if (inode->i_sb->s_frozen != SB_UNFROZEN)
1243 thaw_bdev(inode->i_sb->s_bdev, inode->i_sb);
1244 return 0;
1245
1246 case XFS_IOC_GOINGDOWN: {
1247 __uint32_t in;
1248
1249 if (!capable(CAP_SYS_ADMIN))
1250 return -EPERM;
1251
1252 if (get_user(in, (__uint32_t __user *)arg))
1253 return -XFS_ERROR(EFAULT);
1254
1255 error = xfs_fs_goingdown(mp, in);
1256 return -error;
1257 }
1258
1259 case XFS_IOC_ERROR_INJECTION: {
1260 xfs_error_injection_t in;
1261
1262 if (!capable(CAP_SYS_ADMIN))
1263 return -EPERM;
1264
1265 if (copy_from_user(&in, arg, sizeof(in)))
1266 return -XFS_ERROR(EFAULT);
1267
1268 error = xfs_errortag_add(in.errtag, mp);
1269 return -error;
1270 }
1271
1272 case XFS_IOC_ERROR_CLEARALL:
1273 if (!capable(CAP_SYS_ADMIN))
1274 return -EPERM;
1275
1276 error = xfs_errortag_clearall(mp, 1);
1277 return -error;
1278
1279 default:
1280 return -ENOTTY;
1281 }
1282}