xfs: convert refcount btree cursor to use perags
Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org>
This commit is contained in:
Родитель
fa9c3c1973
Коммит
a81a06211f
|
@ -22,6 +22,7 @@
|
|||
#include "xfs_bit.h"
|
||||
#include "xfs_refcount.h"
|
||||
#include "xfs_rmap.h"
|
||||
#include "xfs_ag.h"
|
||||
|
||||
/* Allowable refcount adjustment amounts. */
|
||||
enum xfs_refc_adjust_op {
|
||||
|
@ -1142,30 +1143,30 @@ xfs_refcount_finish_one(
|
|||
struct xfs_btree_cur *rcur;
|
||||
struct xfs_buf *agbp = NULL;
|
||||
int error = 0;
|
||||
xfs_agnumber_t agno;
|
||||
xfs_agblock_t bno;
|
||||
xfs_agblock_t new_agbno;
|
||||
unsigned long nr_ops = 0;
|
||||
int shape_changes = 0;
|
||||
struct xfs_perag *pag;
|
||||
|
||||
agno = XFS_FSB_TO_AGNO(mp, startblock);
|
||||
ASSERT(agno != NULLAGNUMBER);
|
||||
pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, startblock));
|
||||
bno = XFS_FSB_TO_AGBNO(mp, startblock);
|
||||
|
||||
trace_xfs_refcount_deferred(mp, XFS_FSB_TO_AGNO(mp, startblock),
|
||||
type, XFS_FSB_TO_AGBNO(mp, startblock),
|
||||
blockcount);
|
||||
|
||||
if (XFS_TEST_ERROR(false, mp,
|
||||
XFS_ERRTAG_REFCOUNT_FINISH_ONE))
|
||||
return -EIO;
|
||||
if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_REFCOUNT_FINISH_ONE)) {
|
||||
error = -EIO;
|
||||
goto out_drop;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we haven't gotten a cursor or the cursor AG doesn't match
|
||||
* the startblock, get one now.
|
||||
*/
|
||||
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;
|
||||
shape_changes = rcur->bc_ag.refc.shape_changes;
|
||||
xfs_refcount_finish_one_cleanup(tp, rcur, 0);
|
||||
|
@ -1173,12 +1174,12 @@ xfs_refcount_finish_one(
|
|||
*pcur = 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);
|
||||
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.shape_changes = shape_changes;
|
||||
}
|
||||
|
@ -1188,12 +1189,12 @@ xfs_refcount_finish_one(
|
|||
case XFS_REFCOUNT_INCREASE:
|
||||
error = xfs_refcount_adjust(rcur, bno, blockcount, &new_agbno,
|
||||
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;
|
||||
case XFS_REFCOUNT_DECREASE:
|
||||
error = xfs_refcount_adjust(rcur, bno, blockcount, &new_agbno,
|
||||
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;
|
||||
case XFS_REFCOUNT_ALLOC_COW:
|
||||
*new_fsb = startblock + blockcount;
|
||||
|
@ -1210,8 +1211,10 @@ xfs_refcount_finish_one(
|
|||
error = -EFSCORRUPTED;
|
||||
}
|
||||
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);
|
||||
out_drop:
|
||||
xfs_perag_put(pag);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -1672,7 +1675,7 @@ xfs_refcount_recover_extent(
|
|||
int
|
||||
xfs_refcount_recover_cow_leftovers(
|
||||
struct xfs_mount *mp,
|
||||
xfs_agnumber_t agno)
|
||||
struct xfs_perag *pag)
|
||||
{
|
||||
struct xfs_trans *tp;
|
||||
struct xfs_btree_cur *cur;
|
||||
|
@ -1704,10 +1707,10 @@ xfs_refcount_recover_cow_leftovers(
|
|||
if (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)
|
||||
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. */
|
||||
memset(&low, 0, sizeof(low));
|
||||
|
@ -1729,11 +1732,12 @@ xfs_refcount_recover_cow_leftovers(
|
|||
if (error)
|
||||
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 */
|
||||
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,
|
||||
rr->rr_rrec.rc_blockcount);
|
||||
|
||||
|
|
|
@ -6,6 +6,13 @@
|
|||
#ifndef __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,
|
||||
xfs_agblock_t bno, int *stat);
|
||||
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,
|
|||
void xfs_refcount_free_cow_extent(struct xfs_trans *tp, xfs_fsblock_t fsb,
|
||||
xfs_extlen_t len);
|
||||
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
|
||||
|
|
|
@ -26,7 +26,7 @@ xfs_refcountbt_dup_cursor(
|
|||
struct xfs_btree_cur *cur)
|
||||
{
|
||||
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
|
||||
|
@ -316,13 +316,11 @@ static struct xfs_btree_cur *
|
|||
xfs_refcountbt_init_common(
|
||||
struct xfs_mount *mp,
|
||||
struct xfs_trans *tp,
|
||||
xfs_agnumber_t agno,
|
||||
struct xfs_perag *pag)
|
||||
{
|
||||
struct xfs_btree_cur *cur;
|
||||
|
||||
ASSERT(agno != NULLAGNUMBER);
|
||||
ASSERT(agno < mp->m_sb.sb_agcount);
|
||||
ASSERT(pag->pag_agno < mp->m_sb.sb_agcount);
|
||||
|
||||
cur = kmem_cache_zalloc(xfs_btree_cur_zone, GFP_NOFS | __GFP_NOFAIL);
|
||||
cur->bc_tp = tp;
|
||||
|
@ -331,13 +329,12 @@ xfs_refcountbt_init_common(
|
|||
cur->bc_blocklog = mp->m_sb.sb_blocklog;
|
||||
cur->bc_statoff = XFS_STATS_CALC_INDEX(xs_refcbt_2);
|
||||
|
||||
cur->bc_ag.agno = agno;
|
||||
cur->bc_flags |= XFS_BTREE_CRC_BLOCKS;
|
||||
if (pag) {
|
||||
/* take a reference for the cursor */
|
||||
atomic_inc(&pag->pag_ref);
|
||||
}
|
||||
|
||||
/* take a reference for the cursor */
|
||||
atomic_inc(&pag->pag_ref);
|
||||
cur->bc_ag.pag = pag;
|
||||
cur->bc_ag.agno = pag->pag_agno;
|
||||
|
||||
cur->bc_ag.refc.nr_ops = 0;
|
||||
cur->bc_ag.refc.shape_changes = 0;
|
||||
|
@ -351,13 +348,12 @@ xfs_refcountbt_init_cursor(
|
|||
struct xfs_mount *mp,
|
||||
struct xfs_trans *tp,
|
||||
struct xfs_buf *agbp,
|
||||
xfs_agnumber_t agno,
|
||||
struct xfs_perag *pag)
|
||||
{
|
||||
struct xfs_agf *agf = agbp->b_addr;
|
||||
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_ag.agbp = agbp;
|
||||
return cur;
|
||||
|
@ -368,11 +364,11 @@ struct xfs_btree_cur *
|
|||
xfs_refcountbt_stage_cursor(
|
||||
struct xfs_mount *mp,
|
||||
struct xbtree_afakeroot *afake,
|
||||
xfs_agnumber_t agno)
|
||||
struct xfs_perag *pag)
|
||||
{
|
||||
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);
|
||||
return cur;
|
||||
}
|
||||
|
|
|
@ -47,9 +47,9 @@ struct xbtree_afakeroot;
|
|||
|
||||
extern struct xfs_btree_cur *xfs_refcountbt_init_cursor(struct xfs_mount *mp,
|
||||
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 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 void xfs_refcountbt_compute_maxlevels(struct xfs_mount *mp);
|
||||
|
||||
|
|
|
@ -282,7 +282,7 @@ xrep_agf_calc_from_btrees(
|
|||
/* Update the AGF counters from the refcountbt. */
|
||||
if (xfs_sb_version_hasreflink(&mp->m_sb)) {
|
||||
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);
|
||||
if (error)
|
||||
goto err;
|
||||
|
|
|
@ -545,18 +545,18 @@ STATIC int
|
|||
xchk_bmap_check_ag_rmaps(
|
||||
struct xfs_scrub *sc,
|
||||
int whichfork,
|
||||
xfs_agnumber_t agno)
|
||||
struct xfs_perag *pag)
|
||||
{
|
||||
struct xchk_bmap_check_rmap_info sbcri;
|
||||
struct xfs_btree_cur *cur;
|
||||
struct xfs_buf *agf;
|
||||
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)
|
||||
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.whichfork = whichfork;
|
||||
|
@ -610,7 +610,7 @@ xchk_bmap_check_rmaps(
|
|||
return 0;
|
||||
|
||||
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)
|
||||
break;
|
||||
if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
|
||||
|
|
|
@ -500,7 +500,7 @@ xchk_ag_btcur_init(
|
|||
if (sa->agf_bp && xfs_sb_version_hasreflink(&mp->m_sb) &&
|
||||
xchk_ag_btree_healthy_enough(sc, sa->pag, XFS_BTNUM_REFC)) {
|
||||
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(
|
|||
|
||||
/* Are there any shared blocks here? */
|
||||
flen = 0;
|
||||
cur = xfs_refcountbt_init_cursor(mp, tp, info->agf_bp,
|
||||
info->pag->pag_agno, info->pag);
|
||||
cur = xfs_refcountbt_init_cursor(mp, tp, info->agf_bp, info->pag);
|
||||
|
||||
error = xfs_refcount_find_shared(cur, rec->rm_startblock,
|
||||
rec->rm_blockcount, &fbno, &flen, false);
|
||||
|
|
|
@ -144,7 +144,7 @@ xfs_reflink_find_shared(
|
|||
if (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,
|
||||
find_end_of_shared);
|
||||
|
@ -763,7 +763,7 @@ xfs_reflink_recover_cow(
|
|||
return 0;
|
||||
|
||||
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) {
|
||||
xfs_perag_put(pag);
|
||||
break;
|
||||
|
|
Загрузка…
Ссылка в новой задаче