Commit a81a0621 authored by Dave Chinner's avatar Dave Chinner Committed by Dave Chinner

xfs: convert refcount btree cursor to use perags

Signed-off-by: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
parent fa9c3c19
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "xfs_bit.h" #include "xfs_bit.h"
#include "xfs_refcount.h" #include "xfs_refcount.h"
#include "xfs_rmap.h" #include "xfs_rmap.h"
#include "xfs_ag.h"
/* Allowable refcount adjustment amounts. */ /* Allowable refcount adjustment amounts. */
enum xfs_refc_adjust_op { enum xfs_refc_adjust_op {
...@@ -1142,30 +1143,30 @@ xfs_refcount_finish_one( ...@@ -1142,30 +1143,30 @@ xfs_refcount_finish_one(
struct xfs_btree_cur *rcur; struct xfs_btree_cur *rcur;
struct xfs_buf *agbp = NULL; struct xfs_buf *agbp = NULL;
int error = 0; int error = 0;
xfs_agnumber_t agno;
xfs_agblock_t bno; xfs_agblock_t bno;
xfs_agblock_t new_agbno; xfs_agblock_t new_agbno;
unsigned long nr_ops = 0; unsigned long nr_ops = 0;
int shape_changes = 0; int shape_changes = 0;
struct xfs_perag *pag;
agno = XFS_FSB_TO_AGNO(mp, startblock); pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, startblock));
ASSERT(agno != NULLAGNUMBER);
bno = XFS_FSB_TO_AGBNO(mp, startblock); bno = XFS_FSB_TO_AGBNO(mp, startblock);
trace_xfs_refcount_deferred(mp, XFS_FSB_TO_AGNO(mp, startblock), trace_xfs_refcount_deferred(mp, XFS_FSB_TO_AGNO(mp, startblock),
type, XFS_FSB_TO_AGBNO(mp, startblock), type, XFS_FSB_TO_AGBNO(mp, startblock),
blockcount); blockcount);
if (XFS_TEST_ERROR(false, mp, if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_REFCOUNT_FINISH_ONE)) {
XFS_ERRTAG_REFCOUNT_FINISH_ONE)) error = -EIO;
return -EIO; goto out_drop;
}
/* /*
* If we haven't gotten a cursor or the cursor AG doesn't match * If we haven't gotten a cursor or the cursor AG doesn't match
* the startblock, get one now. * the startblock, get one now.
*/ */
rcur = *pcur; rcur = *pcur;
if (rcur != NULL && rcur->bc_ag.agno != agno) { if (rcur != NULL && rcur->bc_ag.pag != pag) {
nr_ops = rcur->bc_ag.refc.nr_ops; nr_ops = rcur->bc_ag.refc.nr_ops;
shape_changes = rcur->bc_ag.refc.shape_changes; shape_changes = rcur->bc_ag.refc.shape_changes;
xfs_refcount_finish_one_cleanup(tp, rcur, 0); xfs_refcount_finish_one_cleanup(tp, rcur, 0);
...@@ -1173,12 +1174,12 @@ xfs_refcount_finish_one( ...@@ -1173,12 +1174,12 @@ xfs_refcount_finish_one(
*pcur = NULL; *pcur = NULL;
} }
if (rcur == NULL) { if (rcur == NULL) {
error = xfs_alloc_read_agf(tp->t_mountp, tp, agno, error = xfs_alloc_read_agf(tp->t_mountp, tp, pag->pag_agno,
XFS_ALLOC_FLAG_FREEING, &agbp); XFS_ALLOC_FLAG_FREEING, &agbp);
if (error) if (error)
return error; goto out_drop;
rcur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno, NULL); rcur = xfs_refcountbt_init_cursor(mp, tp, agbp, pag);
rcur->bc_ag.refc.nr_ops = nr_ops; rcur->bc_ag.refc.nr_ops = nr_ops;
rcur->bc_ag.refc.shape_changes = shape_changes; rcur->bc_ag.refc.shape_changes = shape_changes;
} }
...@@ -1188,12 +1189,12 @@ xfs_refcount_finish_one( ...@@ -1188,12 +1189,12 @@ xfs_refcount_finish_one(
case XFS_REFCOUNT_INCREASE: case XFS_REFCOUNT_INCREASE:
error = xfs_refcount_adjust(rcur, bno, blockcount, &new_agbno, error = xfs_refcount_adjust(rcur, bno, blockcount, &new_agbno,
new_len, XFS_REFCOUNT_ADJUST_INCREASE, NULL); new_len, XFS_REFCOUNT_ADJUST_INCREASE, NULL);
*new_fsb = XFS_AGB_TO_FSB(mp, agno, new_agbno); *new_fsb = XFS_AGB_TO_FSB(mp, pag->pag_agno, new_agbno);
break; break;
case XFS_REFCOUNT_DECREASE: case XFS_REFCOUNT_DECREASE:
error = xfs_refcount_adjust(rcur, bno, blockcount, &new_agbno, error = xfs_refcount_adjust(rcur, bno, blockcount, &new_agbno,
new_len, XFS_REFCOUNT_ADJUST_DECREASE, NULL); new_len, XFS_REFCOUNT_ADJUST_DECREASE, NULL);
*new_fsb = XFS_AGB_TO_FSB(mp, agno, new_agbno); *new_fsb = XFS_AGB_TO_FSB(mp, pag->pag_agno, new_agbno);
break; break;
case XFS_REFCOUNT_ALLOC_COW: case XFS_REFCOUNT_ALLOC_COW:
*new_fsb = startblock + blockcount; *new_fsb = startblock + blockcount;
...@@ -1210,8 +1211,10 @@ xfs_refcount_finish_one( ...@@ -1210,8 +1211,10 @@ xfs_refcount_finish_one(
error = -EFSCORRUPTED; error = -EFSCORRUPTED;
} }
if (!error && *new_len > 0) if (!error && *new_len > 0)
trace_xfs_refcount_finish_one_leftover(mp, agno, type, trace_xfs_refcount_finish_one_leftover(mp, pag->pag_agno, type,
bno, blockcount, new_agbno, *new_len); bno, blockcount, new_agbno, *new_len);
out_drop:
xfs_perag_put(pag);
return error; return error;
} }
...@@ -1672,7 +1675,7 @@ xfs_refcount_recover_extent( ...@@ -1672,7 +1675,7 @@ xfs_refcount_recover_extent(
int int
xfs_refcount_recover_cow_leftovers( xfs_refcount_recover_cow_leftovers(
struct xfs_mount *mp, struct xfs_mount *mp,
xfs_agnumber_t agno) struct xfs_perag *pag)
{ {
struct xfs_trans *tp; struct xfs_trans *tp;
struct xfs_btree_cur *cur; struct xfs_btree_cur *cur;
...@@ -1704,10 +1707,10 @@ xfs_refcount_recover_cow_leftovers( ...@@ -1704,10 +1707,10 @@ xfs_refcount_recover_cow_leftovers(
if (error) if (error)
return error; return error;
error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp); error = xfs_alloc_read_agf(mp, tp, pag->pag_agno, 0, &agbp);
if (error) if (error)
goto out_trans; goto out_trans;
cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno, NULL); cur = xfs_refcountbt_init_cursor(mp, tp, agbp, pag);
/* Find all the leftover CoW staging extents. */ /* Find all the leftover CoW staging extents. */
memset(&low, 0, sizeof(low)); memset(&low, 0, sizeof(low));
...@@ -1729,11 +1732,12 @@ xfs_refcount_recover_cow_leftovers( ...@@ -1729,11 +1732,12 @@ xfs_refcount_recover_cow_leftovers(
if (error) if (error)
goto out_free; goto out_free;
trace_xfs_refcount_recover_extent(mp, agno, &rr->rr_rrec); trace_xfs_refcount_recover_extent(mp, pag->pag_agno,
&rr->rr_rrec);
/* Free the orphan record */ /* Free the orphan record */
agbno = rr->rr_rrec.rc_startblock - XFS_REFC_COW_START; agbno = rr->rr_rrec.rc_startblock - XFS_REFC_COW_START;
fsb = XFS_AGB_TO_FSB(mp, agno, agbno); fsb = XFS_AGB_TO_FSB(mp, pag->pag_agno, agbno);
xfs_refcount_free_cow_extent(tp, fsb, xfs_refcount_free_cow_extent(tp, fsb,
rr->rr_rrec.rc_blockcount); rr->rr_rrec.rc_blockcount);
......
...@@ -6,6 +6,13 @@ ...@@ -6,6 +6,13 @@
#ifndef __XFS_REFCOUNT_H__ #ifndef __XFS_REFCOUNT_H__
#define __XFS_REFCOUNT_H__ #define __XFS_REFCOUNT_H__
struct xfs_trans;
struct xfs_mount;
struct xfs_perag;
struct xfs_btree_cur;
struct xfs_bmbt_irec;
struct xfs_refcount_irec;
extern int xfs_refcount_lookup_le(struct xfs_btree_cur *cur, extern int xfs_refcount_lookup_le(struct xfs_btree_cur *cur,
xfs_agblock_t bno, int *stat); xfs_agblock_t bno, int *stat);
extern int xfs_refcount_lookup_ge(struct xfs_btree_cur *cur, extern int xfs_refcount_lookup_ge(struct xfs_btree_cur *cur,
...@@ -50,7 +57,7 @@ void xfs_refcount_alloc_cow_extent(struct xfs_trans *tp, xfs_fsblock_t fsb, ...@@ -50,7 +57,7 @@ void xfs_refcount_alloc_cow_extent(struct xfs_trans *tp, xfs_fsblock_t fsb,
void xfs_refcount_free_cow_extent(struct xfs_trans *tp, xfs_fsblock_t fsb, void xfs_refcount_free_cow_extent(struct xfs_trans *tp, xfs_fsblock_t fsb,
xfs_extlen_t len); xfs_extlen_t len);
extern int xfs_refcount_recover_cow_leftovers(struct xfs_mount *mp, extern int xfs_refcount_recover_cow_leftovers(struct xfs_mount *mp,
xfs_agnumber_t agno); struct xfs_perag *pag);
/* /*
* While we're adjusting the refcounts records of an extent, we have * While we're adjusting the refcounts records of an extent, we have
......
...@@ -26,7 +26,7 @@ xfs_refcountbt_dup_cursor( ...@@ -26,7 +26,7 @@ xfs_refcountbt_dup_cursor(
struct xfs_btree_cur *cur) struct xfs_btree_cur *cur)
{ {
return xfs_refcountbt_init_cursor(cur->bc_mp, cur->bc_tp, return xfs_refcountbt_init_cursor(cur->bc_mp, cur->bc_tp,
cur->bc_ag.agbp, cur->bc_ag.agno, cur->bc_ag.pag); cur->bc_ag.agbp, cur->bc_ag.pag);
} }
STATIC void STATIC void
...@@ -316,13 +316,11 @@ static struct xfs_btree_cur * ...@@ -316,13 +316,11 @@ static struct xfs_btree_cur *
xfs_refcountbt_init_common( xfs_refcountbt_init_common(
struct xfs_mount *mp, struct xfs_mount *mp,
struct xfs_trans *tp, struct xfs_trans *tp,
xfs_agnumber_t agno,
struct xfs_perag *pag) struct xfs_perag *pag)
{ {
struct xfs_btree_cur *cur; struct xfs_btree_cur *cur;
ASSERT(agno != NULLAGNUMBER); ASSERT(pag->pag_agno < mp->m_sb.sb_agcount);
ASSERT(agno < mp->m_sb.sb_agcount);
cur = kmem_cache_zalloc(xfs_btree_cur_zone, GFP_NOFS | __GFP_NOFAIL); cur = kmem_cache_zalloc(xfs_btree_cur_zone, GFP_NOFS | __GFP_NOFAIL);
cur->bc_tp = tp; cur->bc_tp = tp;
...@@ -331,13 +329,12 @@ xfs_refcountbt_init_common( ...@@ -331,13 +329,12 @@ xfs_refcountbt_init_common(
cur->bc_blocklog = mp->m_sb.sb_blocklog; cur->bc_blocklog = mp->m_sb.sb_blocklog;
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_refcbt_2); cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_refcbt_2);
cur->bc_ag.agno = agno;
cur->bc_flags |= XFS_BTREE_CRC_BLOCKS; cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
if (pag) {
/* take a reference for the cursor */ /* take a reference for the cursor */
atomic_inc(&pag->pag_ref); atomic_inc(&pag->pag_ref);
}
cur->bc_ag.pag = pag; cur->bc_ag.pag = pag;
cur->bc_ag.agno = pag->pag_agno;
cur->bc_ag.refc.nr_ops = 0; cur->bc_ag.refc.nr_ops = 0;
cur->bc_ag.refc.shape_changes = 0; cur->bc_ag.refc.shape_changes = 0;
...@@ -351,13 +348,12 @@ xfs_refcountbt_init_cursor( ...@@ -351,13 +348,12 @@ xfs_refcountbt_init_cursor(
struct xfs_mount *mp, struct xfs_mount *mp,
struct xfs_trans *tp, struct xfs_trans *tp,
struct xfs_buf *agbp, struct xfs_buf *agbp,
xfs_agnumber_t agno,
struct xfs_perag *pag) struct xfs_perag *pag)
{ {
struct xfs_agf *agf = agbp->b_addr; struct xfs_agf *agf = agbp->b_addr;
struct xfs_btree_cur *cur; struct xfs_btree_cur *cur;
cur = xfs_refcountbt_init_common(mp, tp, agno, pag); cur = xfs_refcountbt_init_common(mp, tp, pag);
cur->bc_nlevels = be32_to_cpu(agf->agf_refcount_level); cur->bc_nlevels = be32_to_cpu(agf->agf_refcount_level);
cur->bc_ag.agbp = agbp; cur->bc_ag.agbp = agbp;
return cur; return cur;
...@@ -368,11 +364,11 @@ struct xfs_btree_cur * ...@@ -368,11 +364,11 @@ struct xfs_btree_cur *
xfs_refcountbt_stage_cursor( xfs_refcountbt_stage_cursor(
struct xfs_mount *mp, struct xfs_mount *mp,
struct xbtree_afakeroot *afake, struct xbtree_afakeroot *afake,
xfs_agnumber_t agno) struct xfs_perag *pag)
{ {
struct xfs_btree_cur *cur; struct xfs_btree_cur *cur;
cur = xfs_refcountbt_init_common(mp, NULL, agno, NULL); cur = xfs_refcountbt_init_common(mp, NULL, pag);
xfs_btree_stage_afakeroot(cur, afake); xfs_btree_stage_afakeroot(cur, afake);
return cur; return cur;
} }
......
...@@ -47,9 +47,9 @@ struct xbtree_afakeroot; ...@@ -47,9 +47,9 @@ struct xbtree_afakeroot;
extern struct xfs_btree_cur *xfs_refcountbt_init_cursor(struct xfs_mount *mp, extern struct xfs_btree_cur *xfs_refcountbt_init_cursor(struct xfs_mount *mp,
struct xfs_trans *tp, struct xfs_buf *agbp, struct xfs_trans *tp, struct xfs_buf *agbp,
xfs_agnumber_t agno, struct xfs_perag *pag); struct xfs_perag *pag);
struct xfs_btree_cur *xfs_refcountbt_stage_cursor(struct xfs_mount *mp, struct xfs_btree_cur *xfs_refcountbt_stage_cursor(struct xfs_mount *mp,
struct xbtree_afakeroot *afake, xfs_agnumber_t agno); struct xbtree_afakeroot *afake, struct xfs_perag *pag);
extern int xfs_refcountbt_maxrecs(int blocklen, bool leaf); extern int xfs_refcountbt_maxrecs(int blocklen, bool leaf);
extern void xfs_refcountbt_compute_maxlevels(struct xfs_mount *mp); extern void xfs_refcountbt_compute_maxlevels(struct xfs_mount *mp);
......
...@@ -282,7 +282,7 @@ xrep_agf_calc_from_btrees( ...@@ -282,7 +282,7 @@ xrep_agf_calc_from_btrees(
/* Update the AGF counters from the refcountbt. */ /* Update the AGF counters from the refcountbt. */
if (xfs_sb_version_hasreflink(&mp->m_sb)) { if (xfs_sb_version_hasreflink(&mp->m_sb)) {
cur = xfs_refcountbt_init_cursor(mp, sc->tp, agf_bp, cur = xfs_refcountbt_init_cursor(mp, sc->tp, agf_bp,
sc->sa.agno, sc->sa.pag); sc->sa.pag);
error = xfs_btree_count_blocks(cur, &blocks); error = xfs_btree_count_blocks(cur, &blocks);
if (error) if (error)
goto err; goto err;
......
...@@ -545,18 +545,18 @@ STATIC int ...@@ -545,18 +545,18 @@ STATIC int
xchk_bmap_check_ag_rmaps( xchk_bmap_check_ag_rmaps(
struct xfs_scrub *sc, struct xfs_scrub *sc,
int whichfork, int whichfork,
xfs_agnumber_t agno) struct xfs_perag *pag)
{ {
struct xchk_bmap_check_rmap_info sbcri; struct xchk_bmap_check_rmap_info sbcri;
struct xfs_btree_cur *cur; struct xfs_btree_cur *cur;
struct xfs_buf *agf; struct xfs_buf *agf;
int error; int error;
error = xfs_alloc_read_agf(sc->mp, sc->tp, agno, 0, &agf); error = xfs_alloc_read_agf(sc->mp, sc->tp, pag->pag_agno, 0, &agf);
if (error) if (error)
return error; return error;
cur = xfs_rmapbt_init_cursor(sc->mp, sc->tp, agf, sc->sa.pag); cur = xfs_rmapbt_init_cursor(sc->mp, sc->tp, agf, pag);
sbcri.sc = sc; sbcri.sc = sc;
sbcri.whichfork = whichfork; sbcri.whichfork = whichfork;
...@@ -610,7 +610,7 @@ xchk_bmap_check_rmaps( ...@@ -610,7 +610,7 @@ xchk_bmap_check_rmaps(
return 0; return 0;
for_each_perag(sc->mp, agno, pag) { for_each_perag(sc->mp, agno, pag) {
error = xchk_bmap_check_ag_rmaps(sc, whichfork, pag->pag_agno); error = xchk_bmap_check_ag_rmaps(sc, whichfork, pag);
if (error) if (error)
break; break;
if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT) if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
......
...@@ -500,7 +500,7 @@ xchk_ag_btcur_init( ...@@ -500,7 +500,7 @@ xchk_ag_btcur_init(
if (sa->agf_bp && xfs_sb_version_hasreflink(&mp->m_sb) && if (sa->agf_bp && xfs_sb_version_hasreflink(&mp->m_sb) &&
xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_REFC)) { xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_REFC)) {
sa->refc_cur = xfs_refcountbt_init_cursor(mp, sc->tp, sa->refc_cur = xfs_refcountbt_init_cursor(mp, sc->tp,
sa->agf_bp, agno, sa->pag); sa->agf_bp, sa->pag);
} }
} }
......
...@@ -210,8 +210,7 @@ xfs_getfsmap_is_shared( ...@@ -210,8 +210,7 @@ xfs_getfsmap_is_shared(
/* Are there any shared blocks here? */ /* Are there any shared blocks here? */
flen = 0; flen = 0;
cur = xfs_refcountbt_init_cursor(mp, tp, info->agf_bp, cur = xfs_refcountbt_init_cursor(mp, tp, info->agf_bp, info->pag);
info->pag->pag_agno, info->pag);
error = xfs_refcount_find_shared(cur, rec->rm_startblock, error = xfs_refcount_find_shared(cur, rec->rm_startblock,
rec->rm_blockcount, &fbno, &flen, false); rec->rm_blockcount, &fbno, &flen, false);
......
...@@ -144,7 +144,7 @@ xfs_reflink_find_shared( ...@@ -144,7 +144,7 @@ xfs_reflink_find_shared(
if (error) if (error)
return error; return error;
cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno, NULL); cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agbp->b_pag);
error = xfs_refcount_find_shared(cur, agbno, aglen, fbno, flen, error = xfs_refcount_find_shared(cur, agbno, aglen, fbno, flen,
find_end_of_shared); find_end_of_shared);
...@@ -763,7 +763,7 @@ xfs_reflink_recover_cow( ...@@ -763,7 +763,7 @@ xfs_reflink_recover_cow(
return 0; return 0;
for_each_perag(mp, agno, pag) { for_each_perag(mp, agno, pag) {
error = xfs_refcount_recover_cow_leftovers(mp, pag->pag_agno); error = xfs_refcount_recover_cow_leftovers(mp, pag);
if (error) { if (error) {
xfs_perag_put(pag); xfs_perag_put(pag);
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment