forked from Minki/linux
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>
This commit is contained in:
parent
f991492ed1
commit
ca29be7534
18
fs/inode.c
18
fs/inode.c
@ -2227,6 +2227,24 @@ int vfs_ioc_fssetxattr_check(struct inode *inode, const struct fsxattr *old_fa,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Check extent size hints. */
|
||||
if ((fa->fsx_xflags & FS_XFLAG_EXTSIZE) && !S_ISREG(inode->i_mode))
|
||||
return -EINVAL;
|
||||
|
||||
if ((fa->fsx_xflags & FS_XFLAG_EXTSZINHERIT) &&
|
||||
!S_ISDIR(inode->i_mode))
|
||||
return -EINVAL;
|
||||
|
||||
if ((fa->fsx_xflags & FS_XFLAG_COWEXTSIZE) &&
|
||||
!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode))
|
||||
return -EINVAL;
|
||||
|
||||
/* Extent size hints of zero turn off the flags. */
|
||||
if (fa->fsx_extsize == 0)
|
||||
fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE | FS_XFLAG_EXTSZINHERIT);
|
||||
if (fa->fsx_cowextsize == 0)
|
||||
fa->fsx_xflags &= ~FS_XFLAG_COWEXTSIZE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(vfs_ioc_fssetxattr_check);
|
||||
|
@ -1200,39 +1200,31 @@ xfs_ioctl_setattr_check_extsize(
|
||||
struct fsxattr *fa)
|
||||
{
|
||||
struct xfs_mount *mp = ip->i_mount;
|
||||
|
||||
if ((fa->fsx_xflags & FS_XFLAG_EXTSIZE) && !S_ISREG(VFS_I(ip)->i_mode))
|
||||
return -EINVAL;
|
||||
|
||||
if ((fa->fsx_xflags & FS_XFLAG_EXTSZINHERIT) &&
|
||||
!S_ISDIR(VFS_I(ip)->i_mode))
|
||||
return -EINVAL;
|
||||
xfs_extlen_t size;
|
||||
xfs_fsblock_t extsize_fsb;
|
||||
|
||||
if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_d.di_nextents &&
|
||||
((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) != fa->fsx_extsize))
|
||||
return -EINVAL;
|
||||
|
||||
if (fa->fsx_extsize != 0) {
|
||||
xfs_extlen_t size;
|
||||
xfs_fsblock_t extsize_fsb;
|
||||
if (fa->fsx_extsize == 0)
|
||||
return 0;
|
||||
|
||||
extsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_extsize);
|
||||
if (extsize_fsb > MAXEXTLEN)
|
||||
extsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_extsize);
|
||||
if (extsize_fsb > MAXEXTLEN)
|
||||
return -EINVAL;
|
||||
|
||||
if (XFS_IS_REALTIME_INODE(ip) ||
|
||||
(fa->fsx_xflags & FS_XFLAG_REALTIME)) {
|
||||
size = mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog;
|
||||
} else {
|
||||
size = mp->m_sb.sb_blocksize;
|
||||
if (extsize_fsb > mp->m_sb.sb_agblocks / 2)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (XFS_IS_REALTIME_INODE(ip) ||
|
||||
(fa->fsx_xflags & FS_XFLAG_REALTIME)) {
|
||||
size = mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog;
|
||||
} else {
|
||||
size = mp->m_sb.sb_blocksize;
|
||||
if (extsize_fsb > mp->m_sb.sb_agblocks / 2)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (fa->fsx_extsize % size)
|
||||
return -EINVAL;
|
||||
} else
|
||||
fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE | FS_XFLAG_EXTSZINHERIT);
|
||||
if (fa->fsx_extsize % size)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1258,6 +1250,8 @@ xfs_ioctl_setattr_check_cowextsize(
|
||||
struct fsxattr *fa)
|
||||
{
|
||||
struct xfs_mount *mp = ip->i_mount;
|
||||
xfs_extlen_t size;
|
||||
xfs_fsblock_t cowextsize_fsb;
|
||||
|
||||
if (!(fa->fsx_xflags & FS_XFLAG_COWEXTSIZE))
|
||||
return 0;
|
||||
@ -1266,25 +1260,19 @@ xfs_ioctl_setattr_check_cowextsize(
|
||||
ip->i_d.di_version != 3)
|
||||
return -EINVAL;
|
||||
|
||||
if (!S_ISREG(VFS_I(ip)->i_mode) && !S_ISDIR(VFS_I(ip)->i_mode))
|
||||
if (fa->fsx_cowextsize == 0)
|
||||
return 0;
|
||||
|
||||
cowextsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_cowextsize);
|
||||
if (cowextsize_fsb > MAXEXTLEN)
|
||||
return -EINVAL;
|
||||
|
||||
if (fa->fsx_cowextsize != 0) {
|
||||
xfs_extlen_t size;
|
||||
xfs_fsblock_t cowextsize_fsb;
|
||||
size = mp->m_sb.sb_blocksize;
|
||||
if (cowextsize_fsb > mp->m_sb.sb_agblocks / 2)
|
||||
return -EINVAL;
|
||||
|
||||
cowextsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_cowextsize);
|
||||
if (cowextsize_fsb > MAXEXTLEN)
|
||||
return -EINVAL;
|
||||
|
||||
size = mp->m_sb.sb_blocksize;
|
||||
if (cowextsize_fsb > mp->m_sb.sb_agblocks / 2)
|
||||
return -EINVAL;
|
||||
|
||||
if (fa->fsx_cowextsize % size)
|
||||
return -EINVAL;
|
||||
} else
|
||||
fa->fsx_xflags &= ~FS_XFLAG_COWEXTSIZE;
|
||||
if (fa->fsx_cowextsize % size)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user