xfs: convert the ifork reap code to use xreap_state
Convert the file fork reaping code to use struct xreap_state so that we can reuse the dynamic state tracking code. Signed-off-by: "Darrick J. Wong" <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>pull/1354/merge
parent
82e374405e
commit
ef930cc371
|
|
@ -91,9 +91,21 @@
|
|||
struct xreap_state {
|
||||
struct xfs_scrub *sc;
|
||||
|
||||
/* Reverse mapping owner and metadata reservation type. */
|
||||
const struct xfs_owner_info *oinfo;
|
||||
enum xfs_ag_resv_type resv;
|
||||
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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
||||
/*
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -1159,12 +1168,11 @@ out:
|
|||
*/
|
||||
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) {
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
@ -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,
|
||||
|
|
@ -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);
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
@ -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…
Reference in New Issue