diff options
author | Darrick J. Wong <djwong@kernel.org> | 2021-09-01 11:18:41 -0700 |
---|---|---|
committer | Darrick J. Wong <djwong@kernel.org> | 2021-09-17 18:55:22 -0700 |
commit | b48c4739e75b7d2e12777ae0cab941c1a161fef7 (patch) | |
tree | 8e47de95ec1212b47bb00d8a6336374171a274bc | |
parent | a7e3d023ce9ab7ba2438cb0f622b0a729b8a53f5 (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.c | 7 | ||||
-rw-r--r-- | fs/xfs/xfs_fsmap.c | 9 | ||||
-rw-r--r-- | fs/xfs/xfs_reflink.c | 30 | ||||
-rw-r--r-- | fs/xfs/xfs_rtalloc.c | 9 | ||||
-rw-r--r-- | fs/xfs/xfs_rtalloc.h | 4 |
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); |