Merge tag 'net-6.9-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
[linux-block.git] / fs / bcachefs / btree_write_buffer.c
index 5cbad8445782c4006074365c13551b1c38b57849..36a6f42aba5e6fc5a36418c1d7565e07e8f90420 100644 (file)
@@ -11,6 +11,7 @@
 #include "journal_reclaim.h"
 
 #include <linux/prefetch.h>
+#include <linux/sort.h>
 
 static int bch2_btree_write_buffer_journal_flush(struct journal *,
                                struct journal_entry_pin *, u64);
@@ -46,6 +47,14 @@ static inline bool wb_key_ref_cmp(const struct wb_key_ref *l, const struct wb_ke
 #endif
 }
 
+static int wb_key_seq_cmp(const void *_l, const void *_r)
+{
+       const struct btree_write_buffered_key *l = _l;
+       const struct btree_write_buffered_key *r = _r;
+
+       return cmp_int(l->journal_seq, r->journal_seq);
+}
+
 /* Compare excluding idx, the low 24 bits: */
 static inline bool wb_key_eq(const void *_l, const void *_r)
 {
@@ -307,6 +316,16 @@ static int bch2_btree_write_buffer_flush_locked(struct btree_trans *trans)
                            bpos_gt(k->k.k.p, path->l[0].b->key.k.p)) {
                                bch2_btree_node_unlock_write(trans, path, path->l[0].b);
                                write_locked = false;
+
+                               ret = lockrestart_do(trans,
+                                       bch2_btree_iter_traverse(&iter) ?:
+                                       bch2_foreground_maybe_merge(trans, iter.path, 0,
+                                                       BCH_WATERMARK_reclaim|
+                                                       BCH_TRANS_COMMIT_journal_reclaim|
+                                                       BCH_TRANS_COMMIT_no_check_rw|
+                                                       BCH_TRANS_COMMIT_no_enospc));
+                               if (ret)
+                                       goto err;
                        }
                }
 
@@ -357,6 +376,11 @@ static int bch2_btree_write_buffer_flush_locked(struct btree_trans *trans)
                 */
                trace_and_count(c, write_buffer_flush_slowpath, trans, slowpath, wb->flushing.keys.nr);
 
+               sort(wb->flushing.keys.data,
+                    wb->flushing.keys.nr,
+                    sizeof(wb->flushing.keys.data[0]),
+                    wb_key_seq_cmp, NULL);
+
                darray_for_each(wb->flushing.keys, i) {
                        if (!i->journal_seq)
                                continue;
@@ -368,10 +392,10 @@ static int bch2_btree_write_buffer_flush_locked(struct btree_trans *trans)
 
                        ret = commit_do(trans, NULL, NULL,
                                        BCH_WATERMARK_reclaim|
+                                       BCH_TRANS_COMMIT_journal_reclaim|
                                        BCH_TRANS_COMMIT_no_check_rw|
                                        BCH_TRANS_COMMIT_no_enospc|
-                                       BCH_TRANS_COMMIT_no_journal_res|
-                                       BCH_TRANS_COMMIT_journal_reclaim,
+                                       BCH_TRANS_COMMIT_no_journal_res ,
                                        btree_write_buffered_insert(trans, i));
                        if (ret)
                                goto err;