@@ -931,16 +931,15 @@ xfs_ioc_fsgetxattr(
931
931
return 0 ;
932
932
}
933
933
934
- STATIC void
935
- xfs_set_diflags (
934
+ STATIC uint16_t
935
+ xfs_flags2diflags (
936
936
struct xfs_inode * ip ,
937
937
unsigned int xflags )
938
938
{
939
- unsigned int di_flags ;
940
- uint64_t di_flags2 ;
941
-
942
939
/* can't set PREALLOC this way, just preserve it */
943
- di_flags = (ip -> i_d .di_flags & XFS_DIFLAG_PREALLOC );
940
+ uint16_t di_flags =
941
+ (ip -> i_d .di_flags & XFS_DIFLAG_PREALLOC );
942
+
944
943
if (xflags & FS_XFLAG_IMMUTABLE )
945
944
di_flags |= XFS_DIFLAG_IMMUTABLE ;
946
945
if (xflags & FS_XFLAG_APPEND )
@@ -970,19 +969,24 @@ xfs_set_diflags(
970
969
if (xflags & FS_XFLAG_EXTSIZE )
971
970
di_flags |= XFS_DIFLAG_EXTSIZE ;
972
971
}
973
- ip -> i_d .di_flags = di_flags ;
974
972
975
- /* diflags2 only valid for v3 inodes. */
976
- if (ip -> i_d .di_version < 3 )
977
- return ;
973
+ return di_flags ;
974
+ }
975
+
976
+ STATIC uint64_t
977
+ xfs_flags2diflags2 (
978
+ struct xfs_inode * ip ,
979
+ unsigned int xflags )
980
+ {
981
+ uint64_t di_flags2 =
982
+ (ip -> i_d .di_flags2 & XFS_DIFLAG2_REFLINK );
978
983
979
- di_flags2 = (ip -> i_d .di_flags2 & XFS_DIFLAG2_REFLINK );
980
984
if (xflags & FS_XFLAG_DAX )
981
985
di_flags2 |= XFS_DIFLAG2_DAX ;
982
986
if (xflags & FS_XFLAG_COWEXTSIZE )
983
987
di_flags2 |= XFS_DIFLAG2_COWEXTSIZE ;
984
988
985
- ip -> i_d . di_flags2 = di_flags2 ;
989
+ return di_flags2 ;
986
990
}
987
991
988
992
STATIC void
@@ -1023,6 +1027,7 @@ xfs_ioctl_setattr_xflags(
1023
1027
struct fsxattr * fa )
1024
1028
{
1025
1029
struct xfs_mount * mp = ip -> i_mount ;
1030
+ uint64_t di_flags2 ;
1026
1031
1027
1032
/* Can't change realtime flag if any extents are allocated. */
1028
1033
if ((ip -> i_d .di_nextents || ip -> i_delayed_blks ) &&
@@ -1053,7 +1058,14 @@ xfs_ioctl_setattr_xflags(
1053
1058
!capable (CAP_LINUX_IMMUTABLE ))
1054
1059
return - EPERM ;
1055
1060
1056
- xfs_set_diflags (ip , fa -> fsx_xflags );
1061
+ /* diflags2 only valid for v3 inodes. */
1062
+ di_flags2 = xfs_flags2diflags2 (ip , fa -> fsx_xflags );
1063
+ if (di_flags2 && ip -> i_d .di_version < 3 )
1064
+ return - EINVAL ;
1065
+
1066
+ ip -> i_d .di_flags = xfs_flags2diflags (ip , fa -> fsx_xflags );
1067
+ ip -> i_d .di_flags2 = di_flags2 ;
1068
+
1057
1069
xfs_diflags_to_linux (ip );
1058
1070
xfs_trans_ichgtime (tp , ip , XFS_ICHGTIME_CHG );
1059
1071
xfs_trans_log_inode (tp , ip , XFS_ILOG_CORE );
0 commit comments