]> www.infradead.org Git - users/hch/dma-mapping.git/commitdiff
bcachefs: fix restart handling in bch2_alloc_write_key()
authorKent Overstreet <kent.overstreet@linux.dev>
Wed, 16 Oct 2024 07:36:40 +0000 (03:36 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Fri, 18 Oct 2024 04:49:47 +0000 (00:49 -0400)
This is ugly:

We may discover in alloc_write_key that the data type we calculated is
wrong, because BCH_DATA_need_discard is checked/set elsewhere, and the
disk accounting counters we calculated need to be updated.

But bch2_alloc_key_to_dev_counters(..., BTREE_TRIGGER_gc) is not safe
w.r.t. transaction restarts, so we need to propagate the fixup back to
our gc state in case we take a transaction restart.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/btree_gc.c

index 94bbd8505582af45909b3969a84c402f6d45b0b5..0ca3feeb42c808e689fb5ad46b3f9e34da01bfac 100644 (file)
@@ -820,12 +820,22 @@ static int bch2_alloc_write_key(struct btree_trans *trans,
         * fix that here:
         */
        alloc_data_type_set(&gc, gc.data_type);
-
        if (gc.data_type != old_gc.data_type ||
            gc.dirty_sectors != old_gc.dirty_sectors) {
                ret = bch2_alloc_key_to_dev_counters(trans, ca, &old_gc, &gc, BTREE_TRIGGER_gc);
                if (ret)
                        return ret;
+
+               /*
+                * Ugly: alloc_key_to_dev_counters(..., BTREE_TRIGGER_gc) is not
+                * safe w.r.t. transaction restarts, so fixup the gc_bucket so
+                * we don't run it twice:
+                */
+               percpu_down_read(&c->mark_lock);
+               struct bucket *gc_m = gc_bucket(ca, iter->pos.offset);
+               gc_m->data_type = gc.data_type;
+               gc_m->dirty_sectors = gc.dirty_sectors;
+               percpu_up_read(&c->mark_lock);
        }
 
        if (fsck_err_on(new.data_type != gc.data_type,