From: "Darrick J. Wong" <djwong@kernel.org>
To: xfs <linux-xfs@vger.kernel.org>
Cc: Dave Chinner <david@fromorbit.com>
Subject: [PATCH] xfs: keep the active perag reference between finish_one calls
Date: Tue, 13 Jul 2021 17:00:08 -0700 [thread overview]
Message-ID: <20210714000008.GC22402@magnolia> (raw)
From: Darrick J. Wong <djwong@kernel.org>
The refcount and rmap finish_one functions stash a btree cursor when
there are multiple ->finish_one calls to be made in a single
transaction. This mechanism is how we maintain the AGF lock between
operations of a single intent item. Since ag btree cursors now need
active references to perag structures, we must preserve the perag
reference when we save the cursor.
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
---
fs/xfs/libxfs/xfs_refcount.c | 33 ++++++++++++++++++++-------------
fs/xfs/libxfs/xfs_rmap.c | 8 +++++++-
2 files changed, 27 insertions(+), 14 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c
index 860a0c9801ba..cfd98958d38c 100644
--- a/fs/xfs/libxfs/xfs_refcount.c
+++ b/fs/xfs/libxfs/xfs_refcount.c
@@ -1113,13 +1113,16 @@ xfs_refcount_finish_one_cleanup(
int error)
{
struct xfs_buf *agbp;
+ struct xfs_perag *pag;
if (rcur == NULL)
return;
agbp = rcur->bc_ag.agbp;
+ pag = rcur->bc_ag.pag;
xfs_btree_del_cursor(rcur, error);
if (error)
xfs_trans_brelse(tp, agbp);
+ xfs_perag_put(pag);
}
/*
@@ -1142,19 +1145,20 @@ xfs_refcount_finish_one(
struct xfs_mount *mp = tp->t_mountp;
struct xfs_btree_cur *rcur;
struct xfs_buf *agbp = NULL;
- int error = 0;
+ struct xfs_perag *pag;
+ unsigned long nr_ops = 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;
+ int error = 0;
- pag = xfs_perag_get(mp, XFS_FSB_TO_AGNO(mp, startblock));
+ agno = XFS_FSB_TO_AGNO(mp, startblock);
+ pag = xfs_perag_get(mp, agno);
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);
+ trace_xfs_refcount_deferred(mp, agno, type,
+ XFS_FSB_TO_AGBNO(mp, startblock), blockcount);
if (XFS_TEST_ERROR(false, mp, XFS_ERRTAG_REFCOUNT_FINISH_ONE)) {
error = -EIO;
@@ -1174,14 +1178,16 @@ xfs_refcount_finish_one(
*pcur = NULL;
}
if (rcur == NULL) {
- error = xfs_alloc_read_agf(tp->t_mountp, tp, pag->pag_agno,
+ error = xfs_alloc_read_agf(mp, tp, agno,
XFS_ALLOC_FLAG_FREEING, &agbp);
if (error)
goto out_drop;
+ /* The cursor now owns the AGF buf and perag ref */
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;
+ pag = NULL;
}
*pcur = rcur;
@@ -1189,12 +1195,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, pag->pag_agno, new_agbno);
+ *new_fsb = XFS_AGB_TO_FSB(mp, 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, pag->pag_agno, new_agbno);
+ *new_fsb = XFS_AGB_TO_FSB(mp, agno, new_agbno);
break;
case XFS_REFCOUNT_ALLOC_COW:
*new_fsb = startblock + blockcount;
@@ -1211,10 +1217,11 @@ xfs_refcount_finish_one(
error = -EFSCORRUPTED;
}
if (!error && *new_len > 0)
- trace_xfs_refcount_finish_one_leftover(mp, pag->pag_agno, type,
- bno, blockcount, new_agbno, *new_len);
+ trace_xfs_refcount_finish_one_leftover(mp, agno, type, bno,
+ blockcount, new_agbno, *new_len);
out_drop:
- xfs_perag_put(pag);
+ if (pag)
+ xfs_perag_put(pag);
return error;
}
diff --git a/fs/xfs/libxfs/xfs_rmap.c b/fs/xfs/libxfs/xfs_rmap.c
index d1dfad0204e3..003ca71515ac 100644
--- a/fs/xfs/libxfs/xfs_rmap.c
+++ b/fs/xfs/libxfs/xfs_rmap.c
@@ -2335,13 +2335,16 @@ xfs_rmap_finish_one_cleanup(
int error)
{
struct xfs_buf *agbp;
+ struct xfs_perag *pag;
if (rcur == NULL)
return;
agbp = rcur->bc_ag.agbp;
+ pag = rcur->bc_ag.pag;
xfs_btree_del_cursor(rcur, error);
if (error)
xfs_trans_brelse(tp, agbp);
+ xfs_perag_put(pag);
}
/*
@@ -2408,7 +2411,9 @@ xfs_rmap_finish_one(
goto out_drop;
}
+ /* The cursor now owns the AGF buf and perag ref */
rcur = xfs_rmapbt_init_cursor(mp, tp, agbp, pag);
+ pag = NULL;
}
*pcur = rcur;
@@ -2447,7 +2452,8 @@ xfs_rmap_finish_one(
error = -EFSCORRUPTED;
}
out_drop:
- xfs_perag_put(pag);
+ if (pag)
+ xfs_perag_put(pag);
return error;
}
next reply other threads:[~2021-07-14 0:00 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-14 0:00 Darrick J. Wong [this message]
2021-07-14 0:31 ` [PATCH] xfs: keep the active perag reference between finish_one calls Dave Chinner
2021-07-14 0:43 ` Darrick J. Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210714000008.GC22402@magnolia \
--to=djwong@kernel.org \
--cc=david@fromorbit.com \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox