bcachefs: Fix locking in __bch2_set_nr_journal_buckets()
authorKent Overstreet <kent.overstreet@gmail.com>
Mon, 17 May 2021 03:46:08 +0000 (23:46 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sun, 22 Oct 2023 21:09:03 +0000 (17:09 -0400)
We weren't holding mark_lock correctly - it's needed for the new_fs
path.

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

index a7cc0b1670722a3b7e2050f4ac372e9dce93b18b..7cbea06f57fd732ab7e9adaa000e1852c32d90a1 100644 (file)
@@ -804,8 +804,11 @@ static int __bch2_set_nr_journal_buckets(struct bch_dev *ca, unsigned nr,
                long b;
 
                if (new_fs) {
+                       if (c)
+                               percpu_down_read(&c->mark_lock);
                        b = bch2_bucket_alloc_new_fs(ca);
                        if (b < 0) {
+                               percpu_up_read(&c->mark_lock);
                                ret = -ENOSPC;
                                goto err;
                        }
@@ -820,10 +823,10 @@ static int __bch2_set_nr_journal_buckets(struct bch_dev *ca, unsigned nr,
                        }
 
                        b = sector_to_bucket(ca, ob->ptr.offset);
+               }
 
-                       percpu_down_read(&c->mark_lock);
+               if (c)
                        spin_lock(&c->journal.lock);
-               }
 
                /*
                 * XXX
@@ -850,15 +853,17 @@ static int __bch2_set_nr_journal_buckets(struct bch_dev *ca, unsigned nr,
                if (pos <= ja->cur_idx)
                        ja->cur_idx = (ja->cur_idx + 1) % ja->nr;
 
+               if (c)
+                       spin_unlock(&c->journal.lock);
+
                if (new_fs) {
                        bch2_mark_metadata_bucket(c, ca, b, BCH_DATA_journal,
                                                  ca->mi.bucket_size,
                                                  gc_phase(GC_PHASE_SB),
                                                  0);
+                       if (c)
+                               percpu_up_read(&c->mark_lock);
                } else {
-                       spin_unlock(&c->journal.lock);
-                       percpu_up_read(&c->mark_lock);
-
                        ret = bch2_trans_do(c, NULL, NULL, BTREE_INSERT_NOFAIL,
                                bch2_trans_mark_metadata_bucket(&trans, ca,
                                                b, BCH_DATA_journal,