On Thu, May 03, 2018 at 11:06:32AM -0700, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@xxxxxxxxxx> > > Replace the quota scrubber's open-coded data fork scrubber with a > redirected call to the bmapbtd scrubber. This strengthens the quota > scrub to include all the cross-referencing that it does. > > Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> > --- FYI, I start to get patch application errors on the previous patch, this patch, and couple or so of the subsequent... (against current for-next). Brian > fs/xfs/scrub/common.c | 57 ++++++++++++++++++++++++++++++++++ > fs/xfs/scrub/common.h | 2 + > fs/xfs/scrub/quota.c | 83 ++++++++++++++++++++++++------------------------- > 3 files changed, 99 insertions(+), 43 deletions(-) > > > diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c > index e9ca5f0802d5..335c7a305e15 100644 > --- a/fs/xfs/scrub/common.c > +++ b/fs/xfs/scrub/common.c > @@ -44,6 +44,8 @@ > #include "xfs_rmap_btree.h" > #include "xfs_log.h" > #include "xfs_trans_priv.h" > +#include "xfs_attr.h" > +#include "xfs_reflink.h" > #include "scrub/xfs_scrub.h" > #include "scrub/scrub.h" > #include "scrub/common.h" > @@ -777,3 +779,58 @@ xfs_scrub_buffer_recheck( > sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT; > trace_xfs_scrub_block_error(sc, bp->b_bn, fa); > } > + > +/* > + * Scrub the attr/data forks of a metadata inode. The metadata inode must be > + * pointed to by sc->ip and the ILOCK must be held. > + */ > +int > +xfs_scrub_metadata_inode_forks( > + struct xfs_scrub_context *sc) > +{ > + __u32 smtype; > + bool shared; > + int error; > + > + if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) > + return 0; > + > + /* Metadata inodes don't live on the rt device. */ > + if (sc->ip->i_d.di_flags & XFS_DIFLAG_REALTIME) { > + xfs_scrub_ino_set_corrupt(sc, sc->ip->i_ino); > + return 0; > + } > + > + /* They should never participate in reflink. */ > + if (xfs_is_reflink_inode(sc->ip)) { > + xfs_scrub_ino_set_corrupt(sc, sc->ip->i_ino); > + return 0; > + } > + > + /* They also should never have extended attributes. */ > + if (xfs_inode_hasattr(sc->ip)) { > + xfs_scrub_ino_set_corrupt(sc, sc->ip->i_ino); > + return 0; > + } > + > + /* Invoke the data fork scrubber. */ > + smtype = sc->sm->sm_type; > + sc->sm->sm_type = XFS_SCRUB_TYPE_BMBTD; > + error = xfs_scrub_bmap_data(sc); > + sc->sm->sm_type = smtype; > + if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) > + return error; > + > + /* Look for incorrect shared blocks. */ > + if (xfs_sb_version_hasreflink(&sc->mp->m_sb)) { > + error = xfs_reflink_inode_has_shared_extents(sc->tp, sc->ip, > + &shared); > + if (!xfs_scrub_fblock_process_error(sc, XFS_DATA_FORK, 0, > + &error)) > + return error; > + if (shared) > + xfs_scrub_ino_set_corrupt(sc, sc->ip->i_ino); > + } > + > + return error; > +} > diff --git a/fs/xfs/scrub/common.h b/fs/xfs/scrub/common.h > index 80fa5a67c265..ad736c411287 100644 > --- a/fs/xfs/scrub/common.h > +++ b/fs/xfs/scrub/common.h > @@ -167,4 +167,6 @@ static inline bool xfs_scrub_skip_xref(struct xfs_scrub_metadata *sm) > XFS_SCRUB_OFLAG_XCORRUPT); > } > > +int xfs_scrub_metadata_inode_forks(struct xfs_scrub_context *sc); > + > #endif /* __XFS_SCRUB_COMMON_H__ */ > diff --git a/fs/xfs/scrub/quota.c b/fs/xfs/scrub/quota.c > index d3d08978f53a..15ae4d23d6ac 100644 > --- a/fs/xfs/scrub/quota.c > +++ b/fs/xfs/scrub/quota.c > @@ -206,65 +206,62 @@ xfs_scrub_quota_item( > return 0; > } > > -/* Scrub all of a quota type's items. */ > -int > -xfs_scrub_quota( > +/* Check the quota's data fork. */ > +STATIC int > +xfs_scrub_quota_data_fork( > struct xfs_scrub_context *sc) > { > struct xfs_bmbt_irec irec = { 0 }; > - struct xfs_scrub_quota_info sqi; > - struct xfs_mount *mp = sc->mp; > - struct xfs_quotainfo *qi = mp->m_quotainfo; > + struct xfs_iext_cursor icur; > + struct xfs_quotainfo *qi = sc->mp->m_quotainfo; > + struct xfs_ifork *ifp; > xfs_fileoff_t max_dqid_off; > - xfs_fileoff_t off = 0; > - uint dqtype; > - int nimaps; > int error = 0; > > - dqtype = xfs_scrub_quota_to_dqtype(sc); > + /* Invoke the fork scrubber. */ > + error = xfs_scrub_metadata_inode_forks(sc); > + if (error || (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)) > + return error; > > - /* Look for problem extents. */ > - if (sc->ip->i_d.di_flags & XFS_DIFLAG_REALTIME) { > - xfs_scrub_ino_set_corrupt(sc, sc->ip->i_ino); > - goto out; > - } > + /* Check for data fork problems that apply only to quota files. */ > max_dqid_off = ((xfs_dqid_t)-1) / qi->qi_dqperchunk; > - while (1) { > + ifp = XFS_IFORK_PTR(sc->ip, XFS_DATA_FORK); > + for_each_xfs_iext(ifp, &icur, &irec) { > if (xfs_scrub_should_terminate(sc, &error)) > break; > - > - off = irec.br_startoff + irec.br_blockcount; > - nimaps = 1; > - error = xfs_bmapi_read(sc->ip, off, -1, &irec, &nimaps, > - XFS_BMAPI_ENTIRE); > - if (!xfs_scrub_fblock_process_error(sc, XFS_DATA_FORK, off, > - &error)) > - goto out; > - if (!nimaps) > - break; > - if (irec.br_startblock == HOLESTARTBLOCK) > - continue; > - > - /* Check the extent record doesn't point to crap. */ > - if (irec.br_startblock + irec.br_blockcount <= > - irec.br_startblock) > - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, > - irec.br_startoff); > - if (!xfs_verify_fsbno(mp, irec.br_startblock) || > - !xfs_verify_fsbno(mp, irec.br_startblock + > - irec.br_blockcount - 1)) > - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, > - irec.br_startoff); > - > /* > - * Unwritten extents or blocks mapped above the highest > + * delalloc extents or blocks mapped above the highest > * quota id shouldn't happen. > */ > if (isnullstartblock(irec.br_startblock) || > irec.br_startoff > max_dqid_off || > - irec.br_startoff + irec.br_blockcount > max_dqid_off + 1) > - xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, off); > + irec.br_startoff + irec.br_blockcount - 1 > max_dqid_off) { > + xfs_scrub_fblock_set_corrupt(sc, XFS_DATA_FORK, > + irec.br_startoff); > + break; > + } > } > + > + return error; > +} > + > +/* Scrub all of a quota type's items. */ > +int > +xfs_scrub_quota( > + struct xfs_scrub_context *sc) > +{ > + struct xfs_scrub_quota_info sqi; > + struct xfs_mount *mp = sc->mp; > + struct xfs_quotainfo *qi = mp->m_quotainfo; > + uint dqtype; > + int error = 0; > + > + dqtype = xfs_scrub_quota_to_dqtype(sc); > + > + /* Look for problem extents. */ > + error = xfs_scrub_quota_data_fork(sc); > + if (error) > + goto out; > if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) > goto out; > > > -- > 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