@@ -1604,13 +1604,36 @@ int bch2_check_alloc_to_lru_refs(struct bch_fs *c)
1604
1604
return ret ;
1605
1605
}
1606
1606
1607
+ struct discard_buckets_state {
1608
+ u64 seen ;
1609
+ u64 open ;
1610
+ u64 need_journal_commit ;
1611
+ u64 discarded ;
1612
+ struct bch_dev * ca ;
1613
+ u64 need_journal_commit_this_dev ;
1614
+ };
1615
+
1616
+ static void discard_buckets_next_dev (struct bch_fs * c , struct discard_buckets_state * s , struct bch_dev * ca )
1617
+ {
1618
+ if (s -> ca == ca )
1619
+ return ;
1620
+
1621
+ if (s -> ca && s -> need_journal_commit_this_dev >
1622
+ bch2_dev_usage_read (s -> ca ).d [BCH_DATA_free ].buckets )
1623
+ bch2_journal_flush_async (& c -> journal , NULL );
1624
+
1625
+ if (s -> ca )
1626
+ percpu_ref_put (& s -> ca -> ref );
1627
+ if (ca )
1628
+ percpu_ref_get (& ca -> ref );
1629
+ s -> ca = ca ;
1630
+ s -> need_journal_commit_this_dev = 0 ;
1631
+ }
1632
+
1607
1633
static int bch2_discard_one_bucket (struct btree_trans * trans ,
1608
1634
struct btree_iter * need_discard_iter ,
1609
1635
struct bpos * discard_pos_done ,
1610
- u64 * seen ,
1611
- u64 * open ,
1612
- u64 * need_journal_commit ,
1613
- u64 * discarded )
1636
+ struct discard_buckets_state * s )
1614
1637
{
1615
1638
struct bch_fs * c = trans -> c ;
1616
1639
struct bpos pos = need_discard_iter -> pos ;
@@ -1622,20 +1645,24 @@ static int bch2_discard_one_bucket(struct btree_trans *trans,
1622
1645
int ret = 0 ;
1623
1646
1624
1647
ca = bch_dev_bkey_exists (c , pos .inode );
1648
+
1625
1649
if (!percpu_ref_tryget (& ca -> io_ref )) {
1626
1650
bch2_btree_iter_set_pos (need_discard_iter , POS (pos .inode + 1 , 0 ));
1627
1651
return 0 ;
1628
1652
}
1629
1653
1654
+ discard_buckets_next_dev (c , s , ca );
1655
+
1630
1656
if (bch2_bucket_is_open_safe (c , pos .inode , pos .offset )) {
1631
- ( * open ) ++ ;
1657
+ s -> open ++ ;
1632
1658
goto out ;
1633
1659
}
1634
1660
1635
1661
if (bch2_bucket_needs_journal_commit (& c -> buckets_waiting_for_journal ,
1636
1662
c -> journal .flushed_seq_ondisk ,
1637
1663
pos .inode , pos .offset )) {
1638
- (* need_journal_commit )++ ;
1664
+ s -> need_journal_commit ++ ;
1665
+ s -> need_journal_commit_this_dev ++ ;
1639
1666
goto out ;
1640
1667
}
1641
1668
@@ -1711,9 +1738,9 @@ static int bch2_discard_one_bucket(struct btree_trans *trans,
1711
1738
goto out ;
1712
1739
1713
1740
count_event (c , bucket_discard );
1714
- ( * discarded ) ++ ;
1741
+ s -> discarded ++ ;
1715
1742
out :
1716
- ( * seen ) ++ ;
1743
+ s -> seen ++ ;
1717
1744
bch2_trans_iter_exit (trans , & iter );
1718
1745
percpu_ref_put (& ca -> io_ref );
1719
1746
printbuf_exit (& buf );
@@ -1723,7 +1750,7 @@ static int bch2_discard_one_bucket(struct btree_trans *trans,
1723
1750
static void bch2_do_discards_work (struct work_struct * work )
1724
1751
{
1725
1752
struct bch_fs * c = container_of (work , struct bch_fs , discard_work );
1726
- u64 seen = 0 , open = 0 , need_journal_commit = 0 , discarded = 0 ;
1753
+ struct discard_buckets_state s = {} ;
1727
1754
struct bpos discard_pos_done = POS_MAX ;
1728
1755
int ret ;
1729
1756
@@ -1735,19 +1762,14 @@ static void bch2_do_discards_work(struct work_struct *work)
1735
1762
ret = bch2_trans_run (c ,
1736
1763
for_each_btree_key (trans , iter ,
1737
1764
BTREE_ID_need_discard , POS_MIN , 0 , k ,
1738
- bch2_discard_one_bucket (trans , & iter , & discard_pos_done ,
1739
- & seen ,
1740
- & open ,
1741
- & need_journal_commit ,
1742
- & discarded )));
1743
-
1744
- if (need_journal_commit * 2 > seen )
1745
- bch2_journal_flush_async (& c -> journal , NULL );
1765
+ bch2_discard_one_bucket (trans , & iter , & discard_pos_done , & s )));
1746
1766
1747
- bch2_write_ref_put (c , BCH_WRITE_REF_discard );
1767
+ discard_buckets_next_dev (c , & s , NULL );
1748
1768
1749
- trace_discard_buckets (c , seen , open , need_journal_commit , discarded ,
1769
+ trace_discard_buckets (c , s . seen , s . open , s . need_journal_commit , s . discarded ,
1750
1770
bch2_err_str (ret ));
1771
+
1772
+ bch2_write_ref_put (c , BCH_WRITE_REF_discard );
1751
1773
}
1752
1774
1753
1775
void bch2_do_discards (struct bch_fs * c )
0 commit comments