xfs: refactor realtime inode locking

Create helper functions to deal with locking realtime metadata inodes.
This enables us to maintain correct locking order once we start adding
the realtime rmap and refcount btree inodes.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
This commit is contained in:
Christoph Hellwig 2024-04-22 13:20:08 +02:00 committed by Chandan Babu R
parent 330c4f94b0
commit b7e23c0e2e
7 changed files with 87 additions and 23 deletions

View file

@ -5418,12 +5418,9 @@ __xfs_bunmapi(
if (isrt) {
/*
* Synchronize by locking the bitmap inode.
* Synchronize by locking the realtime bitmap.
*/
xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL|XFS_ILOCK_RTBITMAP);
xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL);
xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL|XFS_ILOCK_RTSUM);
xfs_trans_ijoin(tp, mp->m_rsumip, XFS_ILOCK_EXCL);
xfs_rtbitmap_lock(tp, mp);
}
extno = 0;

View file

@ -1168,3 +1168,60 @@ xfs_rtsummary_wordcount(
blocks = xfs_rtsummary_blockcount(mp, rsumlevels, rbmblocks);
return XFS_FSB_TO_B(mp, blocks) >> XFS_WORDLOG;
}
/*
* Lock both realtime free space metadata inodes for a freespace update. If a
* transaction is given, the inodes will be joined to the transaction and the
* ILOCKs will be released on transaction commit.
*/
void
xfs_rtbitmap_lock(
struct xfs_trans *tp,
struct xfs_mount *mp)
{
xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
if (tp)
xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL);
xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM);
if (tp)
xfs_trans_ijoin(tp, mp->m_rsumip, XFS_ILOCK_EXCL);
}
/* Unlock both realtime free space metadata inodes after a freespace update. */
void
xfs_rtbitmap_unlock(
struct xfs_mount *mp)
{
xfs_iunlock(mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM);
xfs_iunlock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
}
/*
* Lock the realtime free space metadata inodes for a freespace scan. Callers
* must walk metadata blocks in order of increasing file offset.
*/
void
xfs_rtbitmap_lock_shared(
struct xfs_mount *mp,
unsigned int rbmlock_flags)
{
if (rbmlock_flags & XFS_RBMLOCK_BITMAP)
xfs_ilock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
if (rbmlock_flags & XFS_RBMLOCK_SUMMARY)
xfs_ilock(mp->m_rsumip, XFS_ILOCK_SHARED | XFS_ILOCK_RTSUM);
}
/* Unlock the realtime free space metadata inodes after a freespace scan. */
void
xfs_rtbitmap_unlock_shared(
struct xfs_mount *mp,
unsigned int rbmlock_flags)
{
if (rbmlock_flags & XFS_RBMLOCK_SUMMARY)
xfs_iunlock(mp->m_rsumip, XFS_ILOCK_SHARED | XFS_ILOCK_RTSUM);
if (rbmlock_flags & XFS_RBMLOCK_BITMAP)
xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
}

View file

@ -360,6 +360,19 @@ xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp,
unsigned int rsumlevels, xfs_extlen_t rbmblocks);
unsigned long long xfs_rtsummary_wordcount(struct xfs_mount *mp,
unsigned int rsumlevels, xfs_extlen_t rbmblocks);
void xfs_rtbitmap_lock(struct xfs_trans *tp, struct xfs_mount *mp);
void xfs_rtbitmap_unlock(struct xfs_mount *mp);
/* Lock the rt bitmap inode in shared mode */
#define XFS_RBMLOCK_BITMAP (1U << 0)
/* Lock the rt summary inode in shared mode */
#define XFS_RBMLOCK_SUMMARY (1U << 1)
void xfs_rtbitmap_lock_shared(struct xfs_mount *mp,
unsigned int rbmlock_flags);
void xfs_rtbitmap_unlock_shared(struct xfs_mount *mp,
unsigned int rbmlock_flags);
#else /* CONFIG_XFS_RT */
# define xfs_rtfree_extent(t,b,l) (-ENOSYS)
# define xfs_rtfree_blocks(t,rb,rl) (-ENOSYS)
@ -378,6 +391,10 @@ xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents)
# define xfs_rtbitmap_wordcount(mp, r) (0)
# define xfs_rtsummary_blockcount(mp, l, b) (0)
# define xfs_rtsummary_wordcount(mp, l, b) (0)
# define xfs_rtbitmap_lock(tp, mp) do { } while (0)
# define xfs_rtbitmap_unlock(mp) do { } while (0)
# define xfs_rtbitmap_lock_shared(mp, lf) do { } while (0)
# define xfs_rtbitmap_unlock_shared(mp, lf) do { } while (0)
#endif /* CONFIG_XFS_RT */
#endif /* __XFS_RTBITMAP_H__ */

View file

@ -32,6 +32,7 @@
#include "xfs_error.h"
#include "xfs_quota.h"
#include "xfs_exchmaps.h"
#include "xfs_rtbitmap.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/trace.h"

View file

@ -415,7 +415,7 @@ xchk_fscount_count_frextents(
if (!xfs_has_realtime(mp))
return 0;
xfs_ilock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
xfs_rtbitmap_lock_shared(sc->mp, XFS_RBMLOCK_BITMAP);
error = xfs_rtalloc_query_all(sc->mp, sc->tp,
xchk_fscount_add_frextent, fsc);
if (error) {
@ -424,7 +424,7 @@ xchk_fscount_count_frextents(
}
out_unlock:
xfs_iunlock(sc->mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
xfs_rtbitmap_unlock_shared(sc->mp, XFS_RBMLOCK_BITMAP);
return error;
}
#else

View file

@ -533,7 +533,7 @@ xfs_getfsmap_rtdev_rtbitmap(
trace_xfs_fsmap_low_key_linear(mp, info->dev, start_rtb);
trace_xfs_fsmap_high_key_linear(mp, info->dev, end_rtb);
xfs_ilock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
xfs_rtbitmap_lock_shared(mp, XFS_RBMLOCK_BITMAP);
/*
* Set up query parameters to return free rtextents covering the range
@ -557,7 +557,7 @@ xfs_getfsmap_rtdev_rtbitmap(
if (error)
goto err;
err:
xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
xfs_rtbitmap_unlock_shared(mp, XFS_RBMLOCK_BITMAP);
return error;
}
#endif /* CONFIG_XFS_RT */

View file

@ -957,10 +957,10 @@ xfs_growfs_rt(
nargs.tp = tp;
/*
* Lock out other callers by grabbing the bitmap inode lock.
* Lock out other callers by grabbing the bitmap and summary
* inode locks and joining them to the transaction.
*/
xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
xfs_trans_ijoin(tp, mp->m_rbmip, XFS_ILOCK_EXCL);
xfs_rtbitmap_lock(tp, mp);
/*
* Update the bitmap inode's size ondisk and incore. We need
* to update the incore size so that inode inactivation won't
@ -970,11 +970,6 @@ xfs_growfs_rt(
nsbp->sb_rbmblocks * nsbp->sb_blocksize;
i_size_write(VFS_I(mp->m_rbmip), mp->m_rbmip->i_disk_size);
xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
/*
* Get the summary inode into the transaction.
*/
xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM);
xfs_trans_ijoin(tp, mp->m_rsumip, XFS_ILOCK_EXCL);
/*
* Update the summary inode's size. We need to update the
* incore size so that inode inactivation won't punch what it
@ -1142,10 +1137,10 @@ xfs_rtalloc_reinit_frextents(
uint64_t val = 0;
int error;
xfs_ilock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
xfs_rtbitmap_lock_shared(mp, XFS_RBMLOCK_BITMAP);
error = xfs_rtalloc_query_all(mp, NULL, xfs_rtalloc_count_frextent,
&val);
xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
xfs_rtbitmap_unlock_shared(mp, XFS_RBMLOCK_BITMAP);
if (error)
return error;
@ -1382,10 +1377,7 @@ xfs_bmap_rtalloc(
* Lock out modifications to both the RT bitmap and summary inodes
*/
if (!rtlocked) {
xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL|XFS_ILOCK_RTBITMAP);
xfs_trans_ijoin(ap->tp, mp->m_rbmip, XFS_ILOCK_EXCL);
xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL|XFS_ILOCK_RTSUM);
xfs_trans_ijoin(ap->tp, mp->m_rsumip, XFS_ILOCK_EXCL);
xfs_rtbitmap_lock(ap->tp, mp);
rtlocked = true;
}