Commit ca29be75 authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

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: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarJan Kara <jack@suse.cz>
parent f991492e
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -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);
+29 −41
Original line number Diff line number Diff line
@@ -1200,21 +1200,15 @@ 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)
@@ -1231,8 +1225,6 @@ xfs_ioctl_setattr_check_extsize(

	if (fa->fsx_extsize % size)
		return -EINVAL;
	} else
		fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE | FS_XFLAG_EXTSZINHERIT);

	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,12 +1260,8 @@ 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))
		return -EINVAL;

	if (fa->fsx_cowextsize != 0) {
		xfs_extlen_t    size;
		xfs_fsblock_t   cowextsize_fsb;
	if (fa->fsx_cowextsize == 0)
		return 0;

	cowextsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_cowextsize);
	if (cowextsize_fsb > MAXEXTLEN)
@@ -1283,8 +1273,6 @@ xfs_ioctl_setattr_check_cowextsize(

	if (fa->fsx_cowextsize % size)
		return -EINVAL;
	} else
		fa->fsx_xflags &= ~FS_XFLAG_COWEXTSIZE;

	return 0;
}