@@ -1662,8 +1662,9 @@ xfs_rtalloc_align_minmax(
1662
1662
}
1663
1663
1664
1664
static int
1665
- xfs_rtallocate (
1665
+ xfs_rtallocate_rtg (
1666
1666
struct xfs_trans * tp ,
1667
+ xfs_rgnumber_t rgno ,
1667
1668
xfs_rtblock_t bno_hint ,
1668
1669
xfs_rtxlen_t minlen ,
1669
1670
xfs_rtxlen_t maxlen ,
@@ -1683,16 +1684,33 @@ xfs_rtallocate(
1683
1684
xfs_rtxlen_t len = 0 ;
1684
1685
int error = 0 ;
1685
1686
1686
- args .rtg = xfs_rtgroup_grab (args .mp , 0 );
1687
+ args .rtg = xfs_rtgroup_grab (args .mp , rgno );
1687
1688
if (!args .rtg )
1688
1689
return - ENOSPC ;
1689
1690
1690
1691
/*
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.
1692
1708
*/
1693
1709
if (!* rtlocked ) {
1694
1710
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 );
1696
1714
* rtlocked = true;
1697
1715
}
1698
1716
@@ -1702,7 +1720,7 @@ xfs_rtallocate(
1702
1720
*/
1703
1721
if (bno_hint )
1704
1722
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 )
1706
1724
start = xfs_rtpick_extent (args .rtg , tp , maxlen );
1707
1725
1708
1726
if (start ) {
@@ -1723,8 +1741,16 @@ xfs_rtallocate(
1723
1741
prod , & rtx );
1724
1742
}
1725
1743
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
+ }
1727
1749
goto out_release ;
1750
+ }
1751
+
1752
+ if (xfs_has_rtgroups (args .mp ))
1753
+ xfs_rtgroup_trans_join (tp , args .rtg , XFS_RTGLOCK_BITMAP );
1728
1754
1729
1755
error = xfs_rtallocate_range (& args , rtx , len );
1730
1756
if (error )
@@ -1742,6 +1768,53 @@ xfs_rtallocate(
1742
1768
return error ;
1743
1769
}
1744
1770
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
+
1745
1818
static int
1746
1819
xfs_rtallocate_align (
1747
1820
struct xfs_bmalloca * ap ,
@@ -1836,9 +1909,16 @@ xfs_bmap_rtalloc(
1836
1909
if (xfs_bmap_adjacent (ap ))
1837
1910
bno_hint = ap -> blkno ;
1838
1911
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
+
1842
1922
if (error == - ENOSPC ) {
1843
1923
if (!noalign ) {
1844
1924
/*
0 commit comments