@@ -1572,10 +1572,12 @@ void bch2_ec_do_stripe_creates(struct bch_fs *c)
1572
1572
bch2_write_ref_put (c , BCH_WRITE_REF_stripe_create );
1573
1573
}
1574
1574
1575
- static void ec_stripe_set_pending (struct bch_fs * c , struct ec_stripe_head * h )
1575
+ static void ec_stripe_new_set_pending (struct bch_fs * c , struct ec_stripe_head * h )
1576
1576
{
1577
1577
struct ec_stripe_new * s = h -> s ;
1578
1578
1579
+ lockdep_assert_held (& h -> lock );
1580
+
1579
1581
BUG_ON (!s -> allocated && !s -> err );
1580
1582
1581
1583
h -> s = NULL ;
@@ -1588,6 +1590,12 @@ static void ec_stripe_set_pending(struct bch_fs *c, struct ec_stripe_head *h)
1588
1590
ec_stripe_new_put (c , s , STRIPE_REF_io );
1589
1591
}
1590
1592
1593
+ static void ec_stripe_new_cancel (struct bch_fs * c , struct ec_stripe_head * h , int err )
1594
+ {
1595
+ h -> s -> err = err ;
1596
+ ec_stripe_new_set_pending (c , h );
1597
+ }
1598
+
1591
1599
void bch2_ec_bucket_cancel (struct bch_fs * c , struct open_bucket * ob )
1592
1600
{
1593
1601
struct ec_stripe_new * s = ob -> ec ;
@@ -1711,27 +1719,14 @@ static int ec_new_stripe_alloc(struct bch_fs *c, struct ec_stripe_head *h)
1711
1719
return 0 ;
1712
1720
}
1713
1721
1714
- static struct ec_stripe_head *
1715
- ec_new_stripe_head_alloc (struct bch_fs * c , unsigned disk_label ,
1716
- unsigned algo , unsigned redundancy ,
1717
- enum bch_watermark watermark )
1722
+ static void ec_stripe_head_devs_update (struct bch_fs * c , struct ec_stripe_head * h )
1718
1723
{
1719
- struct ec_stripe_head * h ;
1720
-
1721
- h = kzalloc (sizeof (* h ), GFP_KERNEL );
1722
- if (!h )
1723
- return NULL ;
1724
-
1725
- mutex_init (& h -> lock );
1726
- BUG_ON (!mutex_trylock (& h -> lock ));
1727
-
1728
- h -> disk_label = disk_label ;
1729
- h -> algo = algo ;
1730
- h -> redundancy = redundancy ;
1731
- h -> watermark = watermark ;
1724
+ struct bch_devs_mask devs = h -> devs ;
1732
1725
1733
1726
rcu_read_lock ();
1734
- h -> devs = target_rw_devs (c , BCH_DATA_user , disk_label ? group_to_target (disk_label - 1 ) : 0 );
1727
+ h -> devs = target_rw_devs (c , BCH_DATA_user , h -> disk_label
1728
+ ? group_to_target (h -> disk_label - 1 )
1729
+ : 0 );
1735
1730
unsigned nr_devs = dev_mask_nr (& h -> devs );
1736
1731
1737
1732
for_each_member_device_rcu (c , ca , & h -> devs )
@@ -1741,6 +1736,7 @@ ec_new_stripe_head_alloc(struct bch_fs *c, unsigned disk_label,
1741
1736
1742
1737
h -> blocksize = pick_blocksize (c , & h -> devs );
1743
1738
1739
+ h -> nr_active_devs = 0 ;
1744
1740
for_each_member_device_rcu (c , ca , & h -> devs )
1745
1741
if (ca -> mi .bucket_size == h -> blocksize )
1746
1742
h -> nr_active_devs ++ ;
@@ -1751,7 +1747,9 @@ ec_new_stripe_head_alloc(struct bch_fs *c, unsigned disk_label,
1751
1747
* If we only have redundancy + 1 devices, we're better off with just
1752
1748
* replication:
1753
1749
*/
1754
- if (h -> nr_active_devs < h -> redundancy + 2 ) {
1750
+ h -> insufficient_devs = h -> nr_active_devs < h -> redundancy + 2 ;
1751
+
1752
+ if (h -> insufficient_devs ) {
1755
1753
const char * err ;
1756
1754
1757
1755
if (nr_devs < h -> redundancy + 2 )
@@ -1766,6 +1764,34 @@ ec_new_stripe_head_alloc(struct bch_fs *c, unsigned disk_label,
1766
1764
h -> nr_active_devs , h -> redundancy + 2 , err );
1767
1765
}
1768
1766
1767
+ struct bch_devs_mask devs_leaving ;
1768
+ bitmap_andnot (devs_leaving .d , devs .d , h -> devs .d , BCH_SB_MEMBERS_MAX );
1769
+
1770
+ if (h -> s && !h -> s -> allocated && dev_mask_nr (& devs_leaving ))
1771
+ ec_stripe_new_cancel (c , h , - EINTR );
1772
+
1773
+ h -> rw_devs_change_count = c -> rw_devs_change_count ;
1774
+ }
1775
+
1776
+ static struct ec_stripe_head *
1777
+ ec_new_stripe_head_alloc (struct bch_fs * c , unsigned disk_label ,
1778
+ unsigned algo , unsigned redundancy ,
1779
+ enum bch_watermark watermark )
1780
+ {
1781
+ struct ec_stripe_head * h ;
1782
+
1783
+ h = kzalloc (sizeof (* h ), GFP_KERNEL );
1784
+ if (!h )
1785
+ return NULL ;
1786
+
1787
+ mutex_init (& h -> lock );
1788
+ BUG_ON (!mutex_trylock (& h -> lock ));
1789
+
1790
+ h -> disk_label = disk_label ;
1791
+ h -> algo = algo ;
1792
+ h -> redundancy = redundancy ;
1793
+ h -> watermark = watermark ;
1794
+
1769
1795
list_add (& h -> list , & c -> ec_stripe_head_list );
1770
1796
return h ;
1771
1797
}
@@ -1776,7 +1802,7 @@ void bch2_ec_stripe_head_put(struct bch_fs *c, struct ec_stripe_head *h)
1776
1802
h -> s -> allocated &&
1777
1803
bitmap_weight (h -> s -> blocks_allocated ,
1778
1804
h -> s -> nr_data ) == h -> s -> nr_data )
1779
- ec_stripe_set_pending (c , h );
1805
+ ec_stripe_new_set_pending (c , h );
1780
1806
1781
1807
mutex_unlock (& h -> lock );
1782
1808
}
@@ -1801,7 +1827,7 @@ __bch2_ec_stripe_head_get(struct btree_trans *trans,
1801
1827
1802
1828
if (test_bit (BCH_FS_going_ro , & c -> flags )) {
1803
1829
h = ERR_PTR (- BCH_ERR_erofs_no_writes );
1804
- goto found ;
1830
+ goto err ;
1805
1831
}
1806
1832
1807
1833
list_for_each_entry (h , & c -> ec_stripe_head_list , list )
@@ -1810,18 +1836,23 @@ __bch2_ec_stripe_head_get(struct btree_trans *trans,
1810
1836
h -> redundancy == redundancy &&
1811
1837
h -> watermark == watermark ) {
1812
1838
ret = bch2_trans_mutex_lock (trans , & h -> lock );
1813
- if (ret )
1839
+ if (ret ) {
1814
1840
h = ERR_PTR (ret );
1841
+ goto err ;
1842
+ }
1815
1843
goto found ;
1816
1844
}
1817
1845
1818
1846
h = ec_new_stripe_head_alloc (c , disk_label , algo , redundancy , watermark );
1819
1847
found :
1820
- if (!IS_ERR_OR_NULL (h ) &&
1821
- h -> nr_active_devs < h -> redundancy + 2 ) {
1848
+ if (h -> rw_devs_change_count != c -> rw_devs_change_count )
1849
+ ec_stripe_head_devs_update (c , h );
1850
+
1851
+ if (h -> insufficient_devs ) {
1822
1852
mutex_unlock (& h -> lock );
1823
1853
h = NULL ;
1824
1854
}
1855
+ err :
1825
1856
mutex_unlock (& c -> ec_stripe_head_lock );
1826
1857
return h ;
1827
1858
}
@@ -2261,8 +2292,7 @@ static void __bch2_ec_stop(struct bch_fs *c, struct bch_dev *ca)
2261
2292
}
2262
2293
goto unlock ;
2263
2294
found :
2264
- h -> s -> err = - BCH_ERR_erofs_no_writes ;
2265
- ec_stripe_set_pending (c , h );
2295
+ ec_stripe_new_cancel (c , h , - BCH_ERR_erofs_no_writes );
2266
2296
unlock :
2267
2297
mutex_unlock (& h -> lock );
2268
2298
}
0 commit comments