Loading fs/xfs/scrub/reap.c +46 −32 Original line number Diff line number Diff line Loading @@ -91,9 +91,21 @@ struct xreap_state { struct xfs_scrub *sc; /* Reverse mapping owner and metadata reservation type. */ union { struct { /* * For AG blocks, this is reverse mapping owner and * metadata reservation type. */ const struct xfs_owner_info *oinfo; enum xfs_ag_resv_type resv; }; struct { /* For file blocks, this is the inode and fork. */ struct xfs_inode *ip; int whichfork; }; }; /* Number of invalidated buffers logged to the current transaction. */ unsigned int nr_binval; Loading Loading @@ -965,13 +977,12 @@ xrep_reap_metadir_fsblocks( */ STATIC int xreap_bmapi_select( struct xfs_scrub *sc, struct xfs_inode *ip, int whichfork, struct xreap_state *rs, struct xfs_bmbt_irec *imap, bool *crosslinked) { struct xfs_owner_info oinfo; struct xfs_scrub *sc = rs->sc; struct xfs_btree_cur *cur; xfs_filblks_t len = 1; xfs_agblock_t bno; Loading @@ -985,7 +996,8 @@ xreap_bmapi_select( cur = xfs_rmapbt_init_cursor(sc->mp, sc->tp, sc->sa.agf_bp, sc->sa.pag); xfs_rmap_ino_owner(&oinfo, ip->i_ino, whichfork, imap->br_startoff); xfs_rmap_ino_owner(&oinfo, rs->ip->i_ino, rs->whichfork, imap->br_startoff); error = xfs_rmap_has_other_keys(cur, agbno, 1, &oinfo, crosslinked); if (error) goto out_cur; Loading Loading @@ -1048,21 +1060,19 @@ xreap_buf_loggable( */ STATIC int xreap_bmapi_binval( struct xfs_scrub *sc, struct xfs_inode *ip, int whichfork, struct xreap_state *rs, struct xfs_bmbt_irec *imap) { struct xfs_scrub *sc = rs->sc; struct xfs_mount *mp = sc->mp; struct xfs_perag *pag = sc->sa.pag; int bmap_flags = xfs_bmapi_aflag(whichfork); int bmap_flags = xfs_bmapi_aflag(rs->whichfork); xfs_fileoff_t off; xfs_fileoff_t max_off; xfs_extlen_t scan_blocks; xfs_agblock_t bno; xfs_agblock_t agbno; xfs_agblock_t agbno_next; unsigned int invalidated = 0; int error; /* Loading @@ -1089,7 +1099,7 @@ xreap_bmapi_binval( struct xfs_bmbt_irec hmap; int nhmaps = 1; error = xfs_bmapi_read(ip, off, max_off - off, &hmap, error = xfs_bmapi_read(rs->ip, off, max_off - off, &hmap, &nhmaps, bmap_flags); if (error) return error; Loading Loading @@ -1130,14 +1140,13 @@ xreap_bmapi_binval( xfs_buf_stale(bp); xfs_buf_relse(bp); } invalidated++; /* * Stop invalidating if we've hit the limit; we should * still have enough reservation left to free however * much of the mapping we've seen so far. * far we've gotten. */ if (invalidated > XREAP_MAX_BINVAL) { if (!xreap_inc_binval(rs)) { imap->br_blockcount = agbno_next - bno; goto out; } Loading @@ -1159,12 +1168,11 @@ xreap_bmapi_binval( */ STATIC int xrep_reap_bmapi_iter( struct xfs_scrub *sc, struct xfs_inode *ip, int whichfork, struct xreap_state *rs, struct xfs_bmbt_irec *imap, bool crosslinked) { struct xfs_scrub *sc = rs->sc; int error; if (crosslinked) { Loading @@ -1185,10 +1193,10 @@ xrep_reap_bmapi_iter( * deferred log intents in this function to control the exact * sequence of metadata updates. */ xfs_bmap_unmap_extent(sc->tp, ip, whichfork, imap); xfs_trans_mod_dquot_byino(sc->tp, ip, XFS_TRANS_DQ_BCOUNT, xfs_bmap_unmap_extent(sc->tp, rs->ip, rs->whichfork, imap); xfs_trans_mod_dquot_byino(sc->tp, rs->ip, XFS_TRANS_DQ_BCOUNT, -(int64_t)imap->br_blockcount); xfs_rmap_unmap_extent(sc->tp, ip, whichfork, imap); xfs_rmap_unmap_extent(sc->tp, rs->ip, rs->whichfork, imap); return 0; } Loading @@ -1209,7 +1217,7 @@ xrep_reap_bmapi_iter( * transaction is full of logged buffer invalidations, so we need to * return early so that we can roll and retry. */ error = xreap_bmapi_binval(sc, ip, whichfork, imap); error = xreap_bmapi_binval(rs, imap); if (error || imap->br_blockcount == 0) return error; Loading @@ -1218,8 +1226,8 @@ xrep_reap_bmapi_iter( * intents in this function to control the exact sequence of metadata * updates. */ xfs_bmap_unmap_extent(sc->tp, ip, whichfork, imap); xfs_trans_mod_dquot_byino(sc->tp, ip, XFS_TRANS_DQ_BCOUNT, xfs_bmap_unmap_extent(sc->tp, rs->ip, rs->whichfork, imap); xfs_trans_mod_dquot_byino(sc->tp, rs->ip, XFS_TRANS_DQ_BCOUNT, -(int64_t)imap->br_blockcount); return xfs_free_extent_later(sc->tp, imap->br_startblock, imap->br_blockcount, NULL, XFS_AG_RESV_NONE, Loading @@ -1232,18 +1240,17 @@ xrep_reap_bmapi_iter( */ STATIC int xreap_ifork_extent( struct xfs_scrub *sc, struct xfs_inode *ip, int whichfork, struct xreap_state *rs, struct xfs_bmbt_irec *imap) { struct xfs_scrub *sc = rs->sc; xfs_agnumber_t agno; bool crosslinked; int error; ASSERT(sc->sa.pag == NULL); trace_xreap_ifork_extent(sc, ip, whichfork, imap); trace_xreap_ifork_extent(sc, rs->ip, rs->whichfork, imap); agno = XFS_FSB_TO_AGNO(sc->mp, imap->br_startblock); sc->sa.pag = xfs_perag_get(sc->mp, agno); Loading @@ -1258,11 +1265,11 @@ xreap_ifork_extent( * Decide the fate of the blocks at the beginning of the mapping, then * update the mapping to use it with the unmap calls. */ error = xreap_bmapi_select(sc, ip, whichfork, imap, &crosslinked); error = xreap_bmapi_select(rs, imap, &crosslinked); if (error) goto out_agf; error = xrep_reap_bmapi_iter(sc, ip, whichfork, imap, crosslinked); error = xrep_reap_bmapi_iter(rs, imap, crosslinked); if (error) goto out_agf; Loading @@ -1286,6 +1293,12 @@ xrep_reap_ifork( struct xfs_inode *ip, int whichfork) { struct xreap_state rs = { .sc = sc, .ip = ip, .whichfork = whichfork, .max_binval = XREAP_MAX_BINVAL, }; xfs_fileoff_t off = 0; int bmap_flags = xfs_bmapi_aflag(whichfork); int error; Loading Loading @@ -1313,13 +1326,14 @@ xrep_reap_ifork( * can in a single transaction. */ if (xfs_bmap_is_real_extent(&imap)) { error = xreap_ifork_extent(sc, ip, whichfork, &imap); error = xreap_ifork_extent(&rs, &imap); if (error) return error; error = xfs_defer_finish(&sc->tp); if (error) return error; xreap_defer_finish_reset(&rs); } off = imap.br_startoff + imap.br_blockcount; Loading Loading
fs/xfs/scrub/reap.c +46 −32 Original line number Diff line number Diff line Loading @@ -91,9 +91,21 @@ struct xreap_state { struct xfs_scrub *sc; /* Reverse mapping owner and metadata reservation type. */ union { struct { /* * For AG blocks, this is reverse mapping owner and * metadata reservation type. */ const struct xfs_owner_info *oinfo; enum xfs_ag_resv_type resv; }; struct { /* For file blocks, this is the inode and fork. */ struct xfs_inode *ip; int whichfork; }; }; /* Number of invalidated buffers logged to the current transaction. */ unsigned int nr_binval; Loading Loading @@ -965,13 +977,12 @@ xrep_reap_metadir_fsblocks( */ STATIC int xreap_bmapi_select( struct xfs_scrub *sc, struct xfs_inode *ip, int whichfork, struct xreap_state *rs, struct xfs_bmbt_irec *imap, bool *crosslinked) { struct xfs_owner_info oinfo; struct xfs_scrub *sc = rs->sc; struct xfs_btree_cur *cur; xfs_filblks_t len = 1; xfs_agblock_t bno; Loading @@ -985,7 +996,8 @@ xreap_bmapi_select( cur = xfs_rmapbt_init_cursor(sc->mp, sc->tp, sc->sa.agf_bp, sc->sa.pag); xfs_rmap_ino_owner(&oinfo, ip->i_ino, whichfork, imap->br_startoff); xfs_rmap_ino_owner(&oinfo, rs->ip->i_ino, rs->whichfork, imap->br_startoff); error = xfs_rmap_has_other_keys(cur, agbno, 1, &oinfo, crosslinked); if (error) goto out_cur; Loading Loading @@ -1048,21 +1060,19 @@ xreap_buf_loggable( */ STATIC int xreap_bmapi_binval( struct xfs_scrub *sc, struct xfs_inode *ip, int whichfork, struct xreap_state *rs, struct xfs_bmbt_irec *imap) { struct xfs_scrub *sc = rs->sc; struct xfs_mount *mp = sc->mp; struct xfs_perag *pag = sc->sa.pag; int bmap_flags = xfs_bmapi_aflag(whichfork); int bmap_flags = xfs_bmapi_aflag(rs->whichfork); xfs_fileoff_t off; xfs_fileoff_t max_off; xfs_extlen_t scan_blocks; xfs_agblock_t bno; xfs_agblock_t agbno; xfs_agblock_t agbno_next; unsigned int invalidated = 0; int error; /* Loading @@ -1089,7 +1099,7 @@ xreap_bmapi_binval( struct xfs_bmbt_irec hmap; int nhmaps = 1; error = xfs_bmapi_read(ip, off, max_off - off, &hmap, error = xfs_bmapi_read(rs->ip, off, max_off - off, &hmap, &nhmaps, bmap_flags); if (error) return error; Loading Loading @@ -1130,14 +1140,13 @@ xreap_bmapi_binval( xfs_buf_stale(bp); xfs_buf_relse(bp); } invalidated++; /* * Stop invalidating if we've hit the limit; we should * still have enough reservation left to free however * much of the mapping we've seen so far. * far we've gotten. */ if (invalidated > XREAP_MAX_BINVAL) { if (!xreap_inc_binval(rs)) { imap->br_blockcount = agbno_next - bno; goto out; } Loading @@ -1159,12 +1168,11 @@ xreap_bmapi_binval( */ STATIC int xrep_reap_bmapi_iter( struct xfs_scrub *sc, struct xfs_inode *ip, int whichfork, struct xreap_state *rs, struct xfs_bmbt_irec *imap, bool crosslinked) { struct xfs_scrub *sc = rs->sc; int error; if (crosslinked) { Loading @@ -1185,10 +1193,10 @@ xrep_reap_bmapi_iter( * deferred log intents in this function to control the exact * sequence of metadata updates. */ xfs_bmap_unmap_extent(sc->tp, ip, whichfork, imap); xfs_trans_mod_dquot_byino(sc->tp, ip, XFS_TRANS_DQ_BCOUNT, xfs_bmap_unmap_extent(sc->tp, rs->ip, rs->whichfork, imap); xfs_trans_mod_dquot_byino(sc->tp, rs->ip, XFS_TRANS_DQ_BCOUNT, -(int64_t)imap->br_blockcount); xfs_rmap_unmap_extent(sc->tp, ip, whichfork, imap); xfs_rmap_unmap_extent(sc->tp, rs->ip, rs->whichfork, imap); return 0; } Loading @@ -1209,7 +1217,7 @@ xrep_reap_bmapi_iter( * transaction is full of logged buffer invalidations, so we need to * return early so that we can roll and retry. */ error = xreap_bmapi_binval(sc, ip, whichfork, imap); error = xreap_bmapi_binval(rs, imap); if (error || imap->br_blockcount == 0) return error; Loading @@ -1218,8 +1226,8 @@ xrep_reap_bmapi_iter( * intents in this function to control the exact sequence of metadata * updates. */ xfs_bmap_unmap_extent(sc->tp, ip, whichfork, imap); xfs_trans_mod_dquot_byino(sc->tp, ip, XFS_TRANS_DQ_BCOUNT, xfs_bmap_unmap_extent(sc->tp, rs->ip, rs->whichfork, imap); xfs_trans_mod_dquot_byino(sc->tp, rs->ip, XFS_TRANS_DQ_BCOUNT, -(int64_t)imap->br_blockcount); return xfs_free_extent_later(sc->tp, imap->br_startblock, imap->br_blockcount, NULL, XFS_AG_RESV_NONE, Loading @@ -1232,18 +1240,17 @@ xrep_reap_bmapi_iter( */ STATIC int xreap_ifork_extent( struct xfs_scrub *sc, struct xfs_inode *ip, int whichfork, struct xreap_state *rs, struct xfs_bmbt_irec *imap) { struct xfs_scrub *sc = rs->sc; xfs_agnumber_t agno; bool crosslinked; int error; ASSERT(sc->sa.pag == NULL); trace_xreap_ifork_extent(sc, ip, whichfork, imap); trace_xreap_ifork_extent(sc, rs->ip, rs->whichfork, imap); agno = XFS_FSB_TO_AGNO(sc->mp, imap->br_startblock); sc->sa.pag = xfs_perag_get(sc->mp, agno); Loading @@ -1258,11 +1265,11 @@ xreap_ifork_extent( * Decide the fate of the blocks at the beginning of the mapping, then * update the mapping to use it with the unmap calls. */ error = xreap_bmapi_select(sc, ip, whichfork, imap, &crosslinked); error = xreap_bmapi_select(rs, imap, &crosslinked); if (error) goto out_agf; error = xrep_reap_bmapi_iter(sc, ip, whichfork, imap, crosslinked); error = xrep_reap_bmapi_iter(rs, imap, crosslinked); if (error) goto out_agf; Loading @@ -1286,6 +1293,12 @@ xrep_reap_ifork( struct xfs_inode *ip, int whichfork) { struct xreap_state rs = { .sc = sc, .ip = ip, .whichfork = whichfork, .max_binval = XREAP_MAX_BINVAL, }; xfs_fileoff_t off = 0; int bmap_flags = xfs_bmapi_aflag(whichfork); int error; Loading Loading @@ -1313,13 +1326,14 @@ xrep_reap_ifork( * can in a single transaction. */ if (xfs_bmap_is_real_extent(&imap)) { error = xreap_ifork_extent(sc, ip, whichfork, &imap); error = xreap_ifork_extent(&rs, &imap); if (error) return error; error = xfs_defer_finish(&sc->tp); if (error) return error; xreap_defer_finish_reset(&rs); } off = imap.br_startoff + imap.br_blockcount; Loading