diff options
| author | Darrick J. Wong <darrick.wong@oracle.com> | 2019-07-01 11:25:36 -0400 |
|---|---|---|
| committer | Darrick J. Wong <darrick.wong@oracle.com> | 2019-07-01 11:25:36 -0400 |
| commit | ca29be753445450799958e7d2e5d797d1153389e (patch) | |
| tree | bc4450ee81982ec4429ff7d4bbeaa799789e9f79 | |
| parent | f991492ed11055934f1b35615cb1b435325939bf (diff) | |
vfs: teach vfs_ioc_fssetxattr_check to check extent size hints
Move the extent size hint checks that aren't xfs-specific to the vfs.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Jan Kara <jack@suse.cz>
| -rw-r--r-- | fs/inode.c | 18 | ||||
| -rw-r--r-- | fs/xfs/xfs_ioctl.c | 70 |
2 files changed, 47 insertions, 41 deletions
diff --git a/fs/inode.c b/fs/inode.c index 30b720cffd9c..0cbce5a0a23c 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
| @@ -2227,6 +2227,24 @@ int vfs_ioc_fssetxattr_check(struct inode *inode, const struct fsxattr *old_fa, | |||
| 2227 | return -EINVAL; | 2227 | return -EINVAL; |
| 2228 | } | 2228 | } |
| 2229 | 2229 | ||
| 2230 | /* Check extent size hints. */ | ||
| 2231 | if ((fa->fsx_xflags & FS_XFLAG_EXTSIZE) && !S_ISREG(inode->i_mode)) | ||
| 2232 | return -EINVAL; | ||
| 2233 | |||
| 2234 | if ((fa->fsx_xflags & FS_XFLAG_EXTSZINHERIT) && | ||
| 2235 | !S_ISDIR(inode->i_mode)) | ||
| 2236 | return -EINVAL; | ||
| 2237 | |||
| 2238 | if ((fa->fsx_xflags & FS_XFLAG_COWEXTSIZE) && | ||
| 2239 | !S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) | ||
| 2240 | return -EINVAL; | ||
| 2241 | |||
| 2242 | /* Extent size hints of zero turn off the flags. */ | ||
| 2243 | if (fa->fsx_extsize == 0) | ||
| 2244 | fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE | FS_XFLAG_EXTSZINHERIT); | ||
| 2245 | if (fa->fsx_cowextsize == 0) | ||
| 2246 | fa->fsx_xflags &= ~FS_XFLAG_COWEXTSIZE; | ||
| 2247 | |||
| 2230 | return 0; | 2248 | return 0; |
| 2231 | } | 2249 | } |
| 2232 | EXPORT_SYMBOL(vfs_ioc_fssetxattr_check); | 2250 | EXPORT_SYMBOL(vfs_ioc_fssetxattr_check); |
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index f494c01342c6..fe29aa61293c 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c | |||
| @@ -1200,39 +1200,31 @@ xfs_ioctl_setattr_check_extsize( | |||
| 1200 | struct fsxattr *fa) | 1200 | struct fsxattr *fa) |
| 1201 | { | 1201 | { |
| 1202 | struct xfs_mount *mp = ip->i_mount; | 1202 | struct xfs_mount *mp = ip->i_mount; |
| 1203 | 1203 | xfs_extlen_t size; | |
| 1204 | if ((fa->fsx_xflags & FS_XFLAG_EXTSIZE) && !S_ISREG(VFS_I(ip)->i_mode)) | 1204 | xfs_fsblock_t extsize_fsb; |
| 1205 | return -EINVAL; | ||
| 1206 | |||
| 1207 | if ((fa->fsx_xflags & FS_XFLAG_EXTSZINHERIT) && | ||
| 1208 | !S_ISDIR(VFS_I(ip)->i_mode)) | ||
| 1209 | return -EINVAL; | ||
| 1210 | 1205 | ||
| 1211 | if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_d.di_nextents && | 1206 | if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_d.di_nextents && |
| 1212 | ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) != fa->fsx_extsize)) | 1207 | ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) != fa->fsx_extsize)) |
| 1213 | return -EINVAL; | 1208 | return -EINVAL; |
| 1214 | 1209 | ||
| 1215 | if (fa->fsx_extsize != 0) { | 1210 | if (fa->fsx_extsize == 0) |
| 1216 | xfs_extlen_t size; | 1211 | return 0; |
| 1217 | xfs_fsblock_t extsize_fsb; | ||
| 1218 | |||
| 1219 | extsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_extsize); | ||
| 1220 | if (extsize_fsb > MAXEXTLEN) | ||
| 1221 | return -EINVAL; | ||
| 1222 | 1212 | ||
| 1223 | if (XFS_IS_REALTIME_INODE(ip) || | 1213 | extsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_extsize); |
| 1224 | (fa->fsx_xflags & FS_XFLAG_REALTIME)) { | 1214 | if (extsize_fsb > MAXEXTLEN) |
| 1225 | size = mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog; | 1215 | return -EINVAL; |
| 1226 | } else { | ||
| 1227 | size = mp->m_sb.sb_blocksize; | ||
| 1228 | if (extsize_fsb > mp->m_sb.sb_agblocks / 2) | ||
| 1229 | return -EINVAL; | ||
| 1230 | } | ||
| 1231 | 1216 | ||
| 1232 | if (fa->fsx_extsize % size) | 1217 | if (XFS_IS_REALTIME_INODE(ip) || |
| 1218 | (fa->fsx_xflags & FS_XFLAG_REALTIME)) { | ||
| 1219 | size = mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog; | ||
| 1220 | } else { | ||
| 1221 | size = mp->m_sb.sb_blocksize; | ||
| 1222 | if (extsize_fsb > mp->m_sb.sb_agblocks / 2) | ||
| 1233 | return -EINVAL; | 1223 | return -EINVAL; |
| 1234 | } else | 1224 | } |
| 1235 | fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE | FS_XFLAG_EXTSZINHERIT); | 1225 | |
| 1226 | if (fa->fsx_extsize % size) | ||
| 1227 | return -EINVAL; | ||
| 1236 | 1228 | ||
| 1237 | return 0; | 1229 | return 0; |
| 1238 | } | 1230 | } |
| @@ -1258,6 +1250,8 @@ xfs_ioctl_setattr_check_cowextsize( | |||
| 1258 | struct fsxattr *fa) | 1250 | struct fsxattr *fa) |
| 1259 | { | 1251 | { |
| 1260 | struct xfs_mount *mp = ip->i_mount; | 1252 | struct xfs_mount *mp = ip->i_mount; |
| 1253 | xfs_extlen_t size; | ||
| 1254 | xfs_fsblock_t cowextsize_fsb; | ||
| 1261 | 1255 | ||
| 1262 | if (!(fa->fsx_xflags & FS_XFLAG_COWEXTSIZE)) | 1256 | if (!(fa->fsx_xflags & FS_XFLAG_COWEXTSIZE)) |
| 1263 | return 0; | 1257 | return 0; |
| @@ -1266,25 +1260,19 @@ xfs_ioctl_setattr_check_cowextsize( | |||
| 1266 | ip->i_d.di_version != 3) | 1260 | ip->i_d.di_version != 3) |
| 1267 | return -EINVAL; | 1261 | return -EINVAL; |
| 1268 | 1262 | ||
| 1269 | if (!S_ISREG(VFS_I(ip)->i_mode) && !S_ISDIR(VFS_I(ip)->i_mode)) | 1263 | if (fa->fsx_cowextsize == 0) |
| 1270 | return -EINVAL; | 1264 | return 0; |
| 1271 | |||
| 1272 | if (fa->fsx_cowextsize != 0) { | ||
| 1273 | xfs_extlen_t size; | ||
| 1274 | xfs_fsblock_t cowextsize_fsb; | ||
| 1275 | 1265 | ||
| 1276 | cowextsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_cowextsize); | 1266 | cowextsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_cowextsize); |
| 1277 | if (cowextsize_fsb > MAXEXTLEN) | 1267 | if (cowextsize_fsb > MAXEXTLEN) |
| 1278 | return -EINVAL; | 1268 | return -EINVAL; |
| 1279 | 1269 | ||
| 1280 | size = mp->m_sb.sb_blocksize; | 1270 | size = mp->m_sb.sb_blocksize; |
| 1281 | if (cowextsize_fsb > mp->m_sb.sb_agblocks / 2) | 1271 | if (cowextsize_fsb > mp->m_sb.sb_agblocks / 2) |
| 1282 | return -EINVAL; | 1272 | return -EINVAL; |
| 1283 | 1273 | ||
| 1284 | if (fa->fsx_cowextsize % size) | 1274 | if (fa->fsx_cowextsize % size) |
| 1285 | return -EINVAL; | 1275 | return -EINVAL; |
| 1286 | } else | ||
| 1287 | fa->fsx_xflags &= ~FS_XFLAG_COWEXTSIZE; | ||
| 1288 | 1276 | ||
| 1289 | return 0; | 1277 | return 0; |
| 1290 | } | 1278 | } |
