Skip to content

Commit d162491

Browse files
Christoph HellwigDarrick J. Wong
authored andcommitted
xfs: make the RT allocator rtgroup aware
Make the allocator rtgroup aware by either picking a specific group if there is a hint, or loop over all groups otherwise. A simple rotor is provided to pick the placement for initial allocations. Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Darrick J. Wong <[email protected]>
1 parent b91afef commit d162491

File tree

4 files changed

+105
-13
lines changed

4 files changed

+105
-13
lines changed

fs/xfs/libxfs/xfs_bmap.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3151,8 +3151,17 @@ xfs_bmap_adjacent_valid(
31513151
struct xfs_mount *mp = ap->ip->i_mount;
31523152

31533153
if (XFS_IS_REALTIME_INODE(ap->ip) &&
3154-
(ap->datatype & XFS_ALLOC_USERDATA))
3155-
return x < mp->m_sb.sb_rblocks;
3154+
(ap->datatype & XFS_ALLOC_USERDATA)) {
3155+
if (x >= mp->m_sb.sb_rblocks)
3156+
return false;
3157+
if (!xfs_has_rtgroups(mp))
3158+
return true;
3159+
3160+
return xfs_rtb_to_rgno(mp, x) == xfs_rtb_to_rgno(mp, y) &&
3161+
xfs_rtb_to_rgno(mp, x) < mp->m_sb.sb_rgcount &&
3162+
xfs_rtb_to_rtx(mp, x) < mp->m_sb.sb_rgextents;
3163+
3164+
}
31563165

31573166
return XFS_FSB_TO_AGNO(mp, x) == XFS_FSB_TO_AGNO(mp, y) &&
31583167
XFS_FSB_TO_AGNO(mp, x) < mp->m_sb.sb_agcount &&

fs/xfs/libxfs/xfs_rtbitmap.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,11 +1084,13 @@ xfs_rtfree_extent(
10841084
* Mark more blocks free in the superblock.
10851085
*/
10861086
xfs_trans_mod_sb(tp, XFS_TRANS_SB_FREXTENTS, (long)len);
1087+
10871088
/*
10881089
* If we've now freed all the blocks, reset the file sequence
1089-
* number to 0.
1090+
* number to 0 for pre-RTG file systems.
10901091
*/
1091-
if (tp->t_frextents_delta + mp->m_sb.sb_frextents ==
1092+
if (!xfs_has_rtgroups(mp) &&
1093+
tp->t_frextents_delta + mp->m_sb.sb_frextents ==
10921094
mp->m_sb.sb_rextents) {
10931095
if (!(rbmip->i_diflags & XFS_DIFLAG_NEWRTBM))
10941096
rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM;

fs/xfs/xfs_mount.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ typedef struct xfs_mount {
255255
#endif
256256
xfs_agnumber_t m_agfrotor; /* last ag where space found */
257257
atomic_t m_agirotor; /* last ag dir inode alloced */
258+
atomic_t m_rtgrotor; /* last rtgroup rtpicked */
258259

259260
/* Memory shrinker to throttle and reprioritize inodegc */
260261
struct shrinker *m_inodegc_shrinker;

fs/xfs/xfs_rtalloc.c

Lines changed: 89 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,8 +1662,9 @@ xfs_rtalloc_align_minmax(
16621662
}
16631663

16641664
static int
1665-
xfs_rtallocate(
1665+
xfs_rtallocate_rtg(
16661666
struct xfs_trans *tp,
1667+
xfs_rgnumber_t rgno,
16671668
xfs_rtblock_t bno_hint,
16681669
xfs_rtxlen_t minlen,
16691670
xfs_rtxlen_t maxlen,
@@ -1683,16 +1684,33 @@ xfs_rtallocate(
16831684
xfs_rtxlen_t len = 0;
16841685
int error = 0;
16851686

1686-
args.rtg = xfs_rtgroup_grab(args.mp, 0);
1687+
args.rtg = xfs_rtgroup_grab(args.mp, rgno);
16871688
if (!args.rtg)
16881689
return -ENOSPC;
16891690

16901691
/*
1691-
* Lock out modifications to both the RT bitmap and summary inodes.
1692+
* We need to lock out modifications to both the RT bitmap and summary
1693+
* inodes for finding free space in xfs_rtallocate_extent_{near,size}
1694+
* and join the bitmap and summary inodes for the actual allocation
1695+
* down in xfs_rtallocate_range.
1696+
*
1697+
* For RTG-enabled file system we don't want to join the inodes to the
1698+
* transaction until we are committed to allocate to allocate from this
1699+
* RTG so that only one inode of each type is locked at a time.
1700+
*
1701+
* But for pre-RTG file systems we need to already to join the bitmap
1702+
* inode to the transaction for xfs_rtpick_extent, which bumps the
1703+
* sequence number in it, so we'll have to join the inode to the
1704+
* transaction early here.
1705+
*
1706+
* This is all a bit messy, but at least the mess is contained in
1707+
* this function.
16921708
*/
16931709
if (!*rtlocked) {
16941710
xfs_rtgroup_lock(args.rtg, XFS_RTGLOCK_BITMAP);
1695-
xfs_rtgroup_trans_join(tp, args.rtg, XFS_RTGLOCK_BITMAP);
1711+
if (!xfs_has_rtgroups(args.mp))
1712+
xfs_rtgroup_trans_join(tp, args.rtg,
1713+
XFS_RTGLOCK_BITMAP);
16961714
*rtlocked = true;
16971715
}
16981716

@@ -1702,7 +1720,7 @@ xfs_rtallocate(
17021720
*/
17031721
if (bno_hint)
17041722
start = xfs_rtb_to_rtx(args.mp, bno_hint);
1705-
else if (initial_user_data)
1723+
else if (!xfs_has_rtgroups(args.mp) && initial_user_data)
17061724
start = xfs_rtpick_extent(args.rtg, tp, maxlen);
17071725

17081726
if (start) {
@@ -1723,8 +1741,16 @@ xfs_rtallocate(
17231741
prod, &rtx);
17241742
}
17251743

1726-
if (error)
1744+
if (error) {
1745+
if (xfs_has_rtgroups(args.mp)) {
1746+
xfs_rtgroup_unlock(args.rtg, XFS_RTGLOCK_BITMAP);
1747+
*rtlocked = false;
1748+
}
17271749
goto out_release;
1750+
}
1751+
1752+
if (xfs_has_rtgroups(args.mp))
1753+
xfs_rtgroup_trans_join(tp, args.rtg, XFS_RTGLOCK_BITMAP);
17281754

17291755
error = xfs_rtallocate_range(&args, rtx, len);
17301756
if (error)
@@ -1742,6 +1768,53 @@ xfs_rtallocate(
17421768
return error;
17431769
}
17441770

1771+
static int
1772+
xfs_rtallocate_rtgs(
1773+
struct xfs_trans *tp,
1774+
xfs_fsblock_t bno_hint,
1775+
xfs_rtxlen_t minlen,
1776+
xfs_rtxlen_t maxlen,
1777+
xfs_rtxlen_t prod,
1778+
bool wasdel,
1779+
bool initial_user_data,
1780+
xfs_rtblock_t *bno,
1781+
xfs_extlen_t *blen)
1782+
{
1783+
struct xfs_mount *mp = tp->t_mountp;
1784+
xfs_rgnumber_t start_rgno, rgno;
1785+
int error;
1786+
1787+
/*
1788+
* For now this just blindly iterates over the RTGs for an initial
1789+
* allocation. We could try to keep an in-memory rtg_longest member
1790+
* to avoid the locking when just looking for big enough free space,
1791+
* but for now this keeps things simple.
1792+
*/
1793+
if (bno_hint != NULLFSBLOCK)
1794+
start_rgno = xfs_rtb_to_rgno(mp, bno_hint);
1795+
else
1796+
start_rgno = (atomic_inc_return(&mp->m_rtgrotor) - 1) %
1797+
mp->m_sb.sb_rgcount;
1798+
1799+
rgno = start_rgno;
1800+
do {
1801+
bool rtlocked = false;
1802+
1803+
error = xfs_rtallocate_rtg(tp, rgno, bno_hint, minlen, maxlen,
1804+
prod, wasdel, initial_user_data, &rtlocked,
1805+
bno, blen);
1806+
if (error != -ENOSPC)
1807+
return error;
1808+
ASSERT(!rtlocked);
1809+
1810+
if (++rgno == mp->m_sb.sb_rgcount)
1811+
rgno = 0;
1812+
bno_hint = NULLFSBLOCK;
1813+
} while (rgno != start_rgno);
1814+
1815+
return -ENOSPC;
1816+
}
1817+
17451818
static int
17461819
xfs_rtallocate_align(
17471820
struct xfs_bmalloca *ap,
@@ -1836,9 +1909,16 @@ xfs_bmap_rtalloc(
18361909
if (xfs_bmap_adjacent(ap))
18371910
bno_hint = ap->blkno;
18381911

1839-
error = xfs_rtallocate(ap->tp, bno_hint, raminlen, ralen, prod,
1840-
ap->wasdel, initial_user_data, &rtlocked,
1841-
&ap->blkno, &ap->length);
1912+
if (xfs_has_rtgroups(ap->ip->i_mount)) {
1913+
error = xfs_rtallocate_rtgs(ap->tp, bno_hint, raminlen, ralen,
1914+
prod, ap->wasdel, initial_user_data,
1915+
&ap->blkno, &ap->length);
1916+
} else {
1917+
error = xfs_rtallocate_rtg(ap->tp, 0, bno_hint, raminlen, ralen,
1918+
prod, ap->wasdel, initial_user_data,
1919+
&rtlocked, &ap->blkno, &ap->length);
1920+
}
1921+
18421922
if (error == -ENOSPC) {
18431923
if (!noalign) {
18441924
/*

0 commit comments

Comments
 (0)