@@ -989,6 +989,41 @@ u64 btrfs_find_allocatable_zones(struct btrfs_device *device, u64 hole_start,
989
989
return pos ;
990
990
}
991
991
992
+ static bool btrfs_dev_set_active_zone (struct btrfs_device * device , u64 pos )
993
+ {
994
+ struct btrfs_zoned_device_info * zone_info = device -> zone_info ;
995
+ unsigned int zno = (pos >> zone_info -> zone_size_shift );
996
+
997
+ /* We can use any number of zones */
998
+ if (zone_info -> max_active_zones == 0 )
999
+ return true;
1000
+
1001
+ if (!test_bit (zno , zone_info -> active_zones )) {
1002
+ /* Active zone left? */
1003
+ if (atomic_dec_if_positive (& zone_info -> active_zones_left ) < 0 )
1004
+ return false;
1005
+ if (test_and_set_bit (zno , zone_info -> active_zones )) {
1006
+ /* Someone already set the bit */
1007
+ atomic_inc (& zone_info -> active_zones_left );
1008
+ }
1009
+ }
1010
+
1011
+ return true;
1012
+ }
1013
+
1014
+ static void btrfs_dev_clear_active_zone (struct btrfs_device * device , u64 pos )
1015
+ {
1016
+ struct btrfs_zoned_device_info * zone_info = device -> zone_info ;
1017
+ unsigned int zno = (pos >> zone_info -> zone_size_shift );
1018
+
1019
+ /* We can use any number of zones */
1020
+ if (zone_info -> max_active_zones == 0 )
1021
+ return ;
1022
+
1023
+ if (test_and_clear_bit (zno , zone_info -> active_zones ))
1024
+ atomic_inc (& zone_info -> active_zones_left );
1025
+ }
1026
+
992
1027
int btrfs_reset_device_zone (struct btrfs_device * device , u64 physical ,
993
1028
u64 length , u64 * bytes )
994
1029
{
@@ -1004,6 +1039,7 @@ int btrfs_reset_device_zone(struct btrfs_device *device, u64 physical,
1004
1039
* bytes = length ;
1005
1040
while (length ) {
1006
1041
btrfs_dev_set_zone_empty (device , physical );
1042
+ btrfs_dev_clear_active_zone (device , physical );
1007
1043
physical += device -> zone_info -> zone_size ;
1008
1044
length -= device -> zone_info -> zone_size ;
1009
1045
}
@@ -1656,3 +1692,160 @@ struct btrfs_device *btrfs_zoned_get_device(struct btrfs_fs_info *fs_info,
1656
1692
1657
1693
return device ;
1658
1694
}
1695
+
1696
+ /**
1697
+ * Activate block group and underlying device zones
1698
+ *
1699
+ * @block_group: the block group to activate
1700
+ *
1701
+ * Return: true on success, false otherwise
1702
+ */
1703
+ bool btrfs_zone_activate (struct btrfs_block_group * block_group )
1704
+ {
1705
+ struct btrfs_fs_info * fs_info = block_group -> fs_info ;
1706
+ struct map_lookup * map ;
1707
+ struct btrfs_device * device ;
1708
+ u64 physical ;
1709
+ bool ret ;
1710
+
1711
+ if (!btrfs_is_zoned (block_group -> fs_info ))
1712
+ return true;
1713
+
1714
+ map = block_group -> physical_map ;
1715
+ /* Currently support SINGLE profile only */
1716
+ ASSERT (map -> num_stripes == 1 );
1717
+ device = map -> stripes [0 ].dev ;
1718
+ physical = map -> stripes [0 ].physical ;
1719
+
1720
+ if (device -> zone_info -> max_active_zones == 0 )
1721
+ return true;
1722
+
1723
+ spin_lock (& block_group -> lock );
1724
+
1725
+ if (block_group -> zone_is_active ) {
1726
+ ret = true;
1727
+ goto out_unlock ;
1728
+ }
1729
+
1730
+ /* No space left */
1731
+ if (block_group -> alloc_offset == block_group -> zone_capacity ) {
1732
+ ret = false;
1733
+ goto out_unlock ;
1734
+ }
1735
+
1736
+ if (!btrfs_dev_set_active_zone (device , physical )) {
1737
+ /* Cannot activate the zone */
1738
+ ret = false;
1739
+ goto out_unlock ;
1740
+ }
1741
+
1742
+ /* Successfully activated all the zones */
1743
+ block_group -> zone_is_active = 1 ;
1744
+
1745
+ spin_unlock (& block_group -> lock );
1746
+
1747
+ /* For the active block group list */
1748
+ btrfs_get_block_group (block_group );
1749
+
1750
+ spin_lock (& fs_info -> zone_active_bgs_lock );
1751
+ ASSERT (list_empty (& block_group -> active_bg_list ));
1752
+ list_add_tail (& block_group -> active_bg_list , & fs_info -> zone_active_bgs );
1753
+ spin_unlock (& fs_info -> zone_active_bgs_lock );
1754
+
1755
+ return true;
1756
+
1757
+ out_unlock :
1758
+ spin_unlock (& block_group -> lock );
1759
+ return ret ;
1760
+ }
1761
+
1762
+ int btrfs_zone_finish (struct btrfs_block_group * block_group )
1763
+ {
1764
+ struct btrfs_fs_info * fs_info = block_group -> fs_info ;
1765
+ struct map_lookup * map ;
1766
+ struct btrfs_device * device ;
1767
+ u64 physical ;
1768
+ int ret = 0 ;
1769
+
1770
+ if (!btrfs_is_zoned (fs_info ))
1771
+ return 0 ;
1772
+
1773
+ map = block_group -> physical_map ;
1774
+ /* Currently support SINGLE profile only */
1775
+ ASSERT (map -> num_stripes == 1 );
1776
+
1777
+ device = map -> stripes [0 ].dev ;
1778
+ physical = map -> stripes [0 ].physical ;
1779
+
1780
+ if (device -> zone_info -> max_active_zones == 0 )
1781
+ return 0 ;
1782
+
1783
+ spin_lock (& block_group -> lock );
1784
+ if (!block_group -> zone_is_active ) {
1785
+ spin_unlock (& block_group -> lock );
1786
+ return 0 ;
1787
+ }
1788
+
1789
+ /* Check if we have unwritten allocated space */
1790
+ if ((block_group -> flags &
1791
+ (BTRFS_BLOCK_GROUP_METADATA | BTRFS_BLOCK_GROUP_SYSTEM )) &&
1792
+ block_group -> alloc_offset > block_group -> meta_write_pointer ) {
1793
+ spin_unlock (& block_group -> lock );
1794
+ return - EAGAIN ;
1795
+ }
1796
+ spin_unlock (& block_group -> lock );
1797
+
1798
+ ret = btrfs_inc_block_group_ro (block_group , false);
1799
+ if (ret )
1800
+ return ret ;
1801
+
1802
+ /* Ensure all writes in this block group finish */
1803
+ btrfs_wait_block_group_reservations (block_group );
1804
+ /* No need to wait for NOCOW writers. Zoned mode does not allow that. */
1805
+ btrfs_wait_ordered_roots (fs_info , U64_MAX , block_group -> start ,
1806
+ block_group -> length );
1807
+
1808
+ spin_lock (& block_group -> lock );
1809
+
1810
+ /*
1811
+ * Bail out if someone already deactivated the block group, or
1812
+ * allocated space is left in the block group.
1813
+ */
1814
+ if (!block_group -> zone_is_active ) {
1815
+ spin_unlock (& block_group -> lock );
1816
+ btrfs_dec_block_group_ro (block_group );
1817
+ return 0 ;
1818
+ }
1819
+
1820
+ if (block_group -> reserved ) {
1821
+ spin_unlock (& block_group -> lock );
1822
+ btrfs_dec_block_group_ro (block_group );
1823
+ return - EAGAIN ;
1824
+ }
1825
+
1826
+ block_group -> zone_is_active = 0 ;
1827
+ block_group -> alloc_offset = block_group -> zone_capacity ;
1828
+ block_group -> free_space_ctl -> free_space = 0 ;
1829
+ btrfs_clear_treelog_bg (block_group );
1830
+ spin_unlock (& block_group -> lock );
1831
+
1832
+ ret = blkdev_zone_mgmt (device -> bdev , REQ_OP_ZONE_FINISH ,
1833
+ physical >> SECTOR_SHIFT ,
1834
+ device -> zone_info -> zone_size >> SECTOR_SHIFT ,
1835
+ GFP_NOFS );
1836
+ btrfs_dec_block_group_ro (block_group );
1837
+
1838
+ if (!ret ) {
1839
+ btrfs_dev_clear_active_zone (device , physical );
1840
+
1841
+ spin_lock (& fs_info -> zone_active_bgs_lock );
1842
+ ASSERT (!list_empty (& block_group -> active_bg_list ));
1843
+ list_del_init (& block_group -> active_bg_list );
1844
+ spin_unlock (& fs_info -> zone_active_bgs_lock );
1845
+
1846
+ /* For active_bg_list */
1847
+ btrfs_put_block_group (block_group );
1848
+ }
1849
+
1850
+ return ret ;
1851
+ }
0 commit comments