aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2015-02-01 18:14:25 -0500
committerDave Chinner <david@fromorbit.com>2015-02-01 18:14:25 -0500
commit29a17c00d4b1b8eab61b85b71cb5a83455a7dc5e (patch)
tree7133ee7e4cf2b3b54a22a96c8155e638ea3f4953 /fs/xfs
parent817b6c480e330a5325ed9acb0cef8143923a52de (diff)
xfs: separate xflags from xfs_ioctl_setattr
The setting of the extended flags is down through two separate interfaces, but they are munged together into xfs_ioctl_setattr and make that function far more complex than it needs to be. Separate it out into a helper function along with all the other common inode changes and transaction manipulations in xfs_ioctl_setattr(). Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_ioctl.c89
1 files changed, 41 insertions, 48 deletions
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 0c0e74f314a6..b0064bdb7a6e 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -1013,6 +1013,44 @@ xfs_diflags_to_linux(
1013 inode->i_flags &= ~S_NOATIME; 1013 inode->i_flags &= ~S_NOATIME;
1014} 1014}
1015 1015
1016static int
1017xfs_ioctl_setattr_xflags(
1018 struct xfs_trans *tp,
1019 struct xfs_inode *ip,
1020 struct fsxattr *fa)
1021{
1022 struct xfs_mount *mp = ip->i_mount;
1023
1024 /* Can't change realtime flag if any extents are allocated. */
1025 if ((ip->i_d.di_nextents || ip->i_delayed_blks) &&
1026 XFS_IS_REALTIME_INODE(ip) != (fa->fsx_xflags & XFS_XFLAG_REALTIME))
1027 return -EINVAL;
1028
1029 /* If realtime flag is set then must have realtime device */
1030 if (fa->fsx_xflags & XFS_XFLAG_REALTIME) {
1031 if (mp->m_sb.sb_rblocks == 0 || mp->m_sb.sb_rextsize == 0 ||
1032 (ip->i_d.di_extsize % mp->m_sb.sb_rextsize))
1033 return -EINVAL;
1034 }
1035
1036 /*
1037 * Can't modify an immutable/append-only file unless
1038 * we have appropriate permission.
1039 */
1040 if (((ip->i_d.di_flags & (XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_APPEND)) ||
1041 (fa->fsx_xflags & (XFS_XFLAG_IMMUTABLE | XFS_XFLAG_APPEND))) &&
1042 !capable(CAP_LINUX_IMMUTABLE))
1043 return -EPERM;
1044
1045 xfs_trans_ijoin(tp, ip, 0);
1046 xfs_set_diflags(ip, fa->fsx_xflags);
1047 xfs_diflags_to_linux(ip);
1048 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
1049 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1050 XFS_STATS_INC(xs_ig_attrchg);
1051 return 0;
1052}
1053
1016#define FSX_PROJID 1 1054#define FSX_PROJID 1
1017#define FSX_EXTSIZE 2 1055#define FSX_EXTSIZE 2
1018#define FSX_XFLAGS 4 1056#define FSX_XFLAGS 4
@@ -1159,44 +1197,9 @@ xfs_ioctl_setattr(
1159 } 1197 }
1160 1198
1161 1199
1162 if (mask & FSX_XFLAGS) { 1200 code = xfs_ioctl_setattr_xflags(tp, ip, fa);
1163 /* 1201 if (code)
1164 * Can't change realtime flag if any extents are allocated. 1202 goto error_return;
1165 */
1166 if ((ip->i_d.di_nextents || ip->i_delayed_blks) &&
1167 (XFS_IS_REALTIME_INODE(ip)) !=
1168 (fa->fsx_xflags & XFS_XFLAG_REALTIME)) {
1169 code = -EINVAL; /* EFBIG? */
1170 goto error_return;
1171 }
1172
1173 /*
1174 * If realtime flag is set then must have realtime data.
1175 */
1176 if ((fa->fsx_xflags & XFS_XFLAG_REALTIME)) {
1177 if ((mp->m_sb.sb_rblocks == 0) ||
1178 (mp->m_sb.sb_rextsize == 0) ||
1179 (ip->i_d.di_extsize % mp->m_sb.sb_rextsize)) {
1180 code = -EINVAL;
1181 goto error_return;
1182 }
1183 }
1184
1185 /*
1186 * Can't modify an immutable/append-only file unless
1187 * we have appropriate permission.
1188 */
1189 if ((ip->i_d.di_flags &
1190 (XFS_DIFLAG_IMMUTABLE|XFS_DIFLAG_APPEND) ||
1191 (fa->fsx_xflags &
1192 (XFS_XFLAG_IMMUTABLE | XFS_XFLAG_APPEND))) &&
1193 !capable(CAP_LINUX_IMMUTABLE)) {
1194 code = -EPERM;
1195 goto error_return;
1196 }
1197 }
1198
1199 xfs_trans_ijoin(tp, ip, 0);
1200 1203
1201 /* 1204 /*
1202 * Change file ownership. Must be the owner or privileged. 1205 * Change file ownership. Must be the owner or privileged.
@@ -1227,11 +1230,6 @@ xfs_ioctl_setattr(
1227 1230
1228 } 1231 }
1229 1232
1230 if (mask & FSX_XFLAGS) {
1231 xfs_set_diflags(ip, fa->fsx_xflags);
1232 xfs_diflags_to_linux(ip);
1233 }
1234
1235 /* 1233 /*
1236 * Only set the extent size hint if we've already determined that the 1234 * Only set the extent size hint if we've already determined that the
1237 * extent size hint should be set on the inode. If no extent size flags 1235 * extent size hint should be set on the inode. If no extent size flags
@@ -1246,11 +1244,6 @@ xfs_ioctl_setattr(
1246 ip->i_d.di_extsize = extsize; 1244 ip->i_d.di_extsize = extsize;
1247 } 1245 }
1248 1246
1249 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);
1250 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
1251
1252 XFS_STATS_INC(xs_ig_attrchg);
1253
1254 /* 1247 /*
1255 * If this is a synchronous mount, make sure that the 1248 * If this is a synchronous mount, make sure that the
1256 * transaction goes to disk before returning to the user. 1249 * transaction goes to disk before returning to the user.