summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDarrick J. Wong <djwong@kernel.org>2021-09-01 11:18:41 -0700
committerDarrick J. Wong <djwong@kernel.org>2021-09-17 18:55:22 -0700
commitb48c4739e75b7d2e12777ae0cab941c1a161fef7 (patch)
tree8e47de95ec1212b47bb00d8a6336374171a274bc
parenta7e3d023ce9ab7ba2438cb0f622b0a729b8a53f5 (diff)
xfs: wire up realtime refcount btree cursors
Wire up realtime refcount btree cursors wherever they're needed throughout the code base. Signed-off-by: Darrick J. Wong <djwong@kernel.org>
-rw-r--r--fs/xfs/libxfs/xfs_refcount.c7
-rw-r--r--fs/xfs/xfs_fsmap.c9
-rw-r--r--fs/xfs/xfs_reflink.c30
-rw-r--r--fs/xfs/xfs_rtalloc.c9
-rw-r--r--fs/xfs/xfs_rtalloc.h4
5 files changed, 44 insertions, 15 deletions
diff --git a/fs/xfs/libxfs/xfs_refcount.c b/fs/xfs/libxfs/xfs_refcount.c
index 32b70f4e9dc8..5f28c9440920 100644
--- a/fs/xfs/libxfs/xfs_refcount.c
+++ b/fs/xfs/libxfs/xfs_refcount.c
@@ -25,6 +25,7 @@
#include "xfs_ag.h"
#include "xfs_health.h"
#include "xfs_rtalloc.h"
+#include "xfs_rtrefcount_btree.h"
/* Allowable refcount adjustment amounts. */
enum xfs_refc_adjust_op {
@@ -1273,9 +1274,9 @@ xfs_refcount_finish_one(
}
if (rcur == NULL) {
if (ri->ri_realtime) {
- /* coming in a later patch */
- ASSERT(0);
- return -EFSCORRUPTED;
+ xfs_rtlock(tp, mp, XFS_RTLOCK_REFCOUNT);
+ rcur = xfs_rtrefcountbt_init_cursor(mp, tp,
+ mp->m_rrefcountip);
} else {
error = xfs_alloc_read_agf(mp, tp, pag->pag_agno,
XFS_ALLOC_FLAG_FREEING, &agbp);
diff --git a/fs/xfs/xfs_fsmap.c b/fs/xfs/xfs_fsmap.c
index dbd296e885ed..a30bd36879ce 100644
--- a/fs/xfs/xfs_fsmap.c
+++ b/fs/xfs/xfs_fsmap.c
@@ -26,6 +26,7 @@
#include "xfs_rtalloc.h"
#include "xfs_ag.h"
#include "xfs_rtrmap_btree.h"
+#include "xfs_rtrefcount_btree.h"
/* Convert an xfs_fsmap to an fsmap. */
static void
@@ -205,14 +206,16 @@ xfs_getfsmap_is_shared(
*stat = false;
if (!xfs_has_reflink(mp))
return 0;
+
/* rt files will have no perag structure */
if (!info->pag)
- return 0;
+ cur = xfs_rtrefcountbt_init_cursor(mp, tp, mp->m_rrefcountip);
+ else
+ cur = xfs_refcountbt_init_cursor(mp, tp, info->agf_bp,
+ info->pag);
/* Are there any shared blocks here? */
flen = 0;
- 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);
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c
index c37682ee749f..133ffaa7a1f9 100644
--- a/fs/xfs/xfs_reflink.c
+++ b/fs/xfs/xfs_reflink.c
@@ -29,6 +29,8 @@
#include "xfs_iomap.h"
#include "xfs_ag.h"
#include "xfs_ag_resv.h"
+#include "xfs_rtrefcount_btree.h"
+#include "xfs_rtalloc.h"
/*
* Copy on Write of Shared Blocks
@@ -135,7 +137,7 @@ xfs_reflink_find_shared(
bool find_end_of_shared)
{
struct xfs_mount *mp = ip->i_mount;
- struct xfs_buf *agbp;
+ struct xfs_buf *agbp = NULL;
struct xfs_btree_cur *cur;
xfs_agnumber_t agno;
xfs_fsblock_t agbno;
@@ -143,24 +145,36 @@ xfs_reflink_find_shared(
xfs_filblks_t shared_len;
int error;
- agno = XFS_FSB_TO_AGNO(mp, irec->br_startblock);
- agbno = XFS_FSB_TO_AGBNO(mp, irec->br_startblock);
+ if (XFS_IS_REALTIME_INODE(ip)) {
+ agno = NULLAGNUMBER;
+ agbno = irec->br_startblock;
+ xfs_rtlock(NULL, mp, XFS_RTLOCK_REFCOUNT);
+ cur = xfs_rtrefcountbt_init_cursor(mp, tp, mp->m_rrefcountip);
+ } else {
+ agno = XFS_FSB_TO_AGNO(mp, irec->br_startblock);
+ agbno = XFS_FSB_TO_AGBNO(mp, irec->br_startblock);
- error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp);
- if (error)
- return error;
+ error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp);
+ if (error)
+ return error;
- cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agbp->b_pag);
+ cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agbp->b_pag);
+ }
error = xfs_refcount_find_shared(cur, agbno, irec->br_blockcount,
&shared_bno, &shared_len, find_end_of_shared);
xfs_btree_del_cursor(cur, error);
- xfs_trans_brelse(tp, agbp);
+ if (agbp)
+ xfs_trans_brelse(tp, agbp);
+ else
+ xfs_rtunlock(mp, XFS_RTLOCK_REFCOUNT);
if (shared_bno == NULLFSBLOCK)
*fbno = NULLFSBLOCK;
+ else if (XFS_IS_REALTIME_INODE(ip))
+ *fbno = shared_bno;
else
*fbno = XFS_AGB_TO_FSB(mp, agno, shared_bno);
*flen = shared_len;
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 394d6b80bcd7..4548d23f60d0 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -1766,6 +1766,12 @@ xfs_rtlock(
if (tp)
xfs_trans_ijoin(tp, mp->m_rrmapip, XFS_ILOCK_EXCL);
}
+
+ if ((lock_flags & XFS_RTLOCK_REFCOUNT) && mp->m_rrefcountip) {
+ xfs_ilock(mp->m_rrefcountip, XFS_ILOCK_EXCL);
+ if (tp)
+ xfs_trans_ijoin(tp, mp->m_rrefcountip, XFS_ILOCK_EXCL);
+ }
}
/* Unlock the realtime metadata inodes. */
@@ -1783,4 +1789,7 @@ xfs_rtunlock(
if ((lock_flags & XFS_RTLOCK_RMAP) && mp->m_rrmapip)
xfs_iunlock(mp->m_rrmapip, XFS_ILOCK_EXCL);
+
+ if ((lock_flags & XFS_RTLOCK_REFCOUNT) && mp->m_rrefcountip)
+ xfs_iunlock(mp->m_rrefcountip, XFS_ILOCK_EXCL);
}
diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h
index 71bf96ec9676..432543b166e4 100644
--- a/fs/xfs/xfs_rtalloc.h
+++ b/fs/xfs/xfs_rtalloc.h
@@ -151,8 +151,10 @@ int xfs_rtfile_convert_unwritten(struct xfs_inode *ip, loff_t pos,
#define XFS_RTLOCK_ALLOC (1 << 0) /* rt allocation */
#define XFS_RTLOCK_RMAP (1 << 1) /* rmap operations */
+#define XFS_RTLOCK_REFCOUNT (1 << 2) /* refcount operations */
#define XFS_RTLOCK_ALL (XFS_RTLOCK_ALLOC | \
- XFS_RTLOCK_RMAP)
+ XFS_RTLOCK_RMAP | \
+ XFS_RTLOCK_REFCOUNT)
void xfs_rtlock(struct xfs_trans *tp, struct xfs_mount *mp,
unsigned int rtlock_flags);