@@ -1662,8 +1662,9 @@ xfs_rtalloc_align_minmax(
16621662}
16631663
16641664static 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+
17451818static int
17461819xfs_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