On Wed, Mar 14, 2018 at 05:30:28PM -0700, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@xxxxxxxxxx> > > Extent size hint validation is used by scrub to decide if there's an > error, and it will be used by repair to decide to remove the hint. > Since these use the same validation functions, move them to libxfs. > > Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> > --- Reviewed-by: Brian Foster <bfoster@xxxxxxxxxx> > fs/xfs/libxfs/xfs_inode_buf.c | 105 +++++++++++++++++++++++++++++++++++++++++ > fs/xfs/libxfs/xfs_inode_buf.h | 5 ++ > fs/xfs/scrub/inode.c | 100 +++++---------------------------------- > 3 files changed, 122 insertions(+), 88 deletions(-) > > > diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c > index 51019e5..cdd4c1d 100644 > --- a/fs/xfs/libxfs/xfs_inode_buf.c > +++ b/fs/xfs/libxfs/xfs_inode_buf.c > @@ -651,3 +651,108 @@ xfs_iread( > xfs_trans_brelse(tp, bp); > return error; > } > + > +/* > + * Validate di_extsize hint. > + * > + * The rules are documented at xfs_ioctl_setattr_check_extsize(). > + * These functions must be kept in sync with each other. > + */ > +xfs_failaddr_t > +xfs_inode_validate_extsize( > + struct xfs_mount *mp, > + uint32_t extsize, > + uint16_t mode, > + uint16_t flags) > +{ > + bool rt_flag; > + bool hint_flag; > + bool inherit_flag; > + uint32_t extsize_bytes; > + uint32_t blocksize_bytes; > + > + rt_flag = (flags & XFS_DIFLAG_REALTIME); > + hint_flag = (flags & XFS_DIFLAG_EXTSIZE); > + inherit_flag = (flags & XFS_DIFLAG_EXTSZINHERIT); > + extsize_bytes = XFS_FSB_TO_B(mp, extsize); > + > + if (rt_flag) > + blocksize_bytes = mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog; > + else > + blocksize_bytes = mp->m_sb.sb_blocksize; > + > + if ((hint_flag || inherit_flag) && !(S_ISDIR(mode) || S_ISREG(mode))) > + return __this_address; > + > + if (hint_flag && !S_ISREG(mode)) > + return __this_address; > + > + if (inherit_flag && !S_ISDIR(mode)) > + return __this_address; > + > + if ((hint_flag || inherit_flag) && extsize == 0) > + return __this_address; > + > + if (!(hint_flag || inherit_flag) && extsize != 0) > + return __this_address; > + > + if (extsize_bytes % blocksize_bytes) > + return __this_address; > + > + if (extsize > MAXEXTLEN) > + return __this_address; > + > + if (!rt_flag && extsize > mp->m_sb.sb_agblocks / 2) > + return __this_address; > + > + return NULL; > +} > + > +/* > + * Validate di_cowextsize hint. > + * > + * The rules are documented at xfs_ioctl_setattr_check_cowextsize(). > + * These functions must be kept in sync with each other. > + */ > +xfs_failaddr_t > +xfs_inode_validate_cowextsize( > + struct xfs_mount *mp, > + uint32_t cowextsize, > + uint16_t mode, > + uint16_t flags, > + uint64_t flags2) > +{ > + bool rt_flag; > + bool hint_flag; > + uint32_t cowextsize_bytes; > + > + rt_flag = (flags & XFS_DIFLAG_REALTIME); > + hint_flag = (flags2 & XFS_DIFLAG2_COWEXTSIZE); > + cowextsize_bytes = XFS_FSB_TO_B(mp, cowextsize); > + > + if (hint_flag && !xfs_sb_version_hasreflink(&mp->m_sb)) > + return __this_address; > + > + if (hint_flag && !(S_ISDIR(mode) || S_ISREG(mode))) > + return __this_address; > + > + if (hint_flag && cowextsize == 0) > + return __this_address; > + > + if (!hint_flag && cowextsize != 0) > + return __this_address; > + > + if (hint_flag && rt_flag) > + return __this_address; > + > + if (cowextsize_bytes % mp->m_sb.sb_blocksize) > + return __this_address; > + > + if (cowextsize > MAXEXTLEN) > + return __this_address; > + > + if (cowextsize > mp->m_sb.sb_agblocks / 2) > + return __this_address; > + > + return NULL; > +} > diff --git a/fs/xfs/libxfs/xfs_inode_buf.h b/fs/xfs/libxfs/xfs_inode_buf.h > index 8a5e1da..d9a376a 100644 > --- a/fs/xfs/libxfs/xfs_inode_buf.h > +++ b/fs/xfs/libxfs/xfs_inode_buf.h > @@ -84,5 +84,10 @@ void xfs_inobp_check(struct xfs_mount *, struct xfs_buf *); > > xfs_failaddr_t xfs_dinode_verify(struct xfs_mount *mp, xfs_ino_t ino, > struct xfs_dinode *dip); > +xfs_failaddr_t xfs_inode_validate_extsize(struct xfs_mount *mp, > + uint32_t extsize, uint16_t mode, uint16_t flags); > +xfs_failaddr_t xfs_inode_validate_cowextsize(struct xfs_mount *mp, > + uint32_t cowextsize, uint16_t mode, uint16_t flags, > + uint64_t flags2); > > #endif /* __XFS_INODE_BUF_H__ */ > diff --git a/fs/xfs/scrub/inode.c b/fs/xfs/scrub/inode.c > index 9eadca9..25bca48 100644 > --- a/fs/xfs/scrub/inode.c > +++ b/fs/xfs/scrub/inode.c > @@ -89,12 +89,7 @@ xfs_scrub_setup_inode( > > /* Inode core */ > > -/* > - * Validate di_extsize hint. > - * > - * The rules are documented at xfs_ioctl_setattr_check_extsize(). > - * These functions must be kept in sync with each other. > - */ > +/* Validate di_extsize hint. */ > STATIC void > xfs_scrub_inode_extsize( > struct xfs_scrub_context *sc, > @@ -103,52 +98,12 @@ xfs_scrub_inode_extsize( > uint16_t mode, > uint16_t flags) > { > - struct xfs_mount *mp = sc->mp; > - bool rt_flag; > - bool hint_flag; > - bool inherit_flag; > - uint32_t extsize; > - uint32_t extsize_bytes; > - uint32_t blocksize_bytes; > - > - rt_flag = (flags & XFS_DIFLAG_REALTIME); > - hint_flag = (flags & XFS_DIFLAG_EXTSIZE); > - inherit_flag = (flags & XFS_DIFLAG_EXTSZINHERIT); > - extsize = be32_to_cpu(dip->di_extsize); > - extsize_bytes = XFS_FSB_TO_B(sc->mp, extsize); > - > - if (rt_flag) > - blocksize_bytes = mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog; > - else > - blocksize_bytes = mp->m_sb.sb_blocksize; > - > - if ((hint_flag || inherit_flag) && !(S_ISDIR(mode) || S_ISREG(mode))) > - goto bad; > - > - if (hint_flag && !S_ISREG(mode)) > - goto bad; > - > - if (inherit_flag && !S_ISDIR(mode)) > - goto bad; > + xfs_failaddr_t fa; > > - if ((hint_flag || inherit_flag) && extsize == 0) > - goto bad; > - > - if (!(hint_flag || inherit_flag) && extsize != 0) > - goto bad; > - > - if (extsize_bytes % blocksize_bytes) > - goto bad; > - > - if (extsize > MAXEXTLEN) > - goto bad; > - > - if (!rt_flag && extsize > mp->m_sb.sb_agblocks / 2) > - goto bad; > - > - return; > -bad: > - xfs_scrub_ino_set_corrupt(sc, ino); > + fa = xfs_inode_validate_extsize(sc->mp, be32_to_cpu(dip->di_extsize), > + mode, flags); > + if (fa) > + xfs_scrub_ino_set_corrupt(sc, ino); > } > > /* > @@ -166,44 +121,13 @@ xfs_scrub_inode_cowextsize( > uint16_t flags, > uint64_t flags2) > { > - struct xfs_mount *mp = sc->mp; > - bool rt_flag; > - bool hint_flag; > - uint32_t extsize; > - uint32_t extsize_bytes; > - > - rt_flag = (flags & XFS_DIFLAG_REALTIME); > - hint_flag = (flags2 & XFS_DIFLAG2_COWEXTSIZE); > - extsize = be32_to_cpu(dip->di_cowextsize); > - extsize_bytes = XFS_FSB_TO_B(sc->mp, extsize); > - > - if (hint_flag && !xfs_sb_version_hasreflink(&mp->m_sb)) > - goto bad; > - > - if (hint_flag && !(S_ISDIR(mode) || S_ISREG(mode))) > - goto bad; > - > - if (hint_flag && extsize == 0) > - goto bad; > - > - if (!hint_flag && extsize != 0) > - goto bad; > + xfs_failaddr_t fa; > > - if (hint_flag && rt_flag) > - goto bad; > - > - if (extsize_bytes % mp->m_sb.sb_blocksize) > - goto bad; > - > - if (extsize > MAXEXTLEN) > - goto bad; > - > - if (extsize > mp->m_sb.sb_agblocks / 2) > - goto bad; > - > - return; > -bad: > - xfs_scrub_ino_set_corrupt(sc, ino); > + fa = xfs_inode_validate_cowextsize(sc->mp, > + be32_to_cpu(dip->di_cowextsize), mode, flags, > + flags2); > + if (fa) > + xfs_scrub_ino_set_corrupt(sc, ino); > } > > /* Make sure the di_flags make sense for the inode. */ > > -- > To unsubscribe from this list: send the line "unsubscribe linux-xfs" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html