lkml.org 
[lkml]   [2019]   [Jun]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH 4/5] vfs: teach vfs_ioc_fssetxattr_check to check extent size hints
    From
    Date
    From: Darrick J. Wong <darrick.wong@oracle.com>

    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>
    ---
    fs/inode.c | 18 +++++++++++++
    fs/xfs/xfs_ioctl.c | 70 ++++++++++++++++++++++------------------------------
    2 files changed, 47 insertions(+), 41 deletions(-)


    diff --git a/fs/inode.c b/fs/inode.c
    index c4f8fb16f633..670d5408d022 100644
    --- a/fs/inode.c
    +++ b/fs/inode.c
    @@ -2247,6 +2247,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);
    diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
    index d8c02b9905a7..011657bd50ca 100644
    --- a/fs/xfs/xfs_ioctl.c
    +++ b/fs/xfs/xfs_ioctl.c
    @@ -1201,39 +1201,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;
    -
    - extsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_extsize);
    - if (extsize_fsb > MAXEXTLEN)
    - return -EINVAL;
    + if (fa->fsx_extsize == 0)
    + return 0;

    - 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;
    - }
    + extsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_extsize);
    + if (extsize_fsb > MAXEXTLEN)
    + return -EINVAL;

    - if (fa->fsx_extsize % size)
    + 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;
    - } else
    - fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE | FS_XFLAG_EXTSZINHERIT);
    + }
    +
    + if (fa->fsx_extsize % size)
    + return -EINVAL;

    return 0;
    }
    @@ -1259,6 +1251,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;
    @@ -1267,25 +1261,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))
    - 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)
    - 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;
    + 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;
    }
    \
     
     \ /
      Last update: 2019-06-26 04:34    [W:5.241 / U:0.040 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site