]> www.infradead.org Git - users/hch/block.git/commitdiff
bcachefs: Fix disk accounting attempting to mark invalid replicas entry
authorKent Overstreet <kent.overstreet@linux.dev>
Wed, 25 Sep 2024 22:17:52 +0000 (18:17 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sat, 28 Sep 2024 01:46:35 +0000 (21:46 -0400)
This fixes the following bug, where a disk accounting key has an invalid
replicas entry, and we attempt to add it to the superblock:

bcachefs (3c0860e8-07ca-4276-8954-11c1774be868): starting version 1.12: rebalance_work_acct_fix opts=metadata_replicas=2,data_replicas=2,foreground_target=ssd,background_target=hdd,nopromote_whole_extents,verbose,fsck,fix_errors=yes
bcachefs (3c0860e8-07ca-4276-8954-11c1774be868): recovering from clean shutdown, journal seq 15211644
bcachefs (3c0860e8-07ca-4276-8954-11c1774be868): accounting_read...
accounting not marked in superblock replicas
  replicas cached: 1/1 [0], fixing
bcachefs (3c0860e8-07ca-4276-8954-11c1774be868): sb invalid before write: Invalid superblock section replicas_v0: invalid device 0 in entry cached: 1/1 [0]
replicas_v0 (size 88):
user: 2 [3 5] user: 2 [1 4] cached: 1 [2] btree: 2 [1 2] user: 2 [2 5] cached: 1 [0] cached: 1 [4] journal: 2 [1 5] user: 2 [1 2] user: 2 [2 3] user: 2 [3 4] user: 2 [4 5] cached: 1 [1] cached: 1 [3] cached: 1 [5] journal: 2 [1 2] journal: 2 [2 5] btree: 2 [2 5] user: 2 [1 3] user: 2 [1 5] user: 2 [2 4]

bcachefs (3c0860e8-07ca-4276-8954-11c1774be868): inconsistency detected - emergency read only at journal seq 15211644
accounting not marked in superblock replicas
  replicas user: 1/1 [3], fixing
bcachefs (3c0860e8-07ca-4276-8954-11c1774be868): sb invalid before write: Invalid superblock section replicas_v0: invalid device 0 in entry cached: 1/1 [0]
replicas_v0 (size 96):
user: 2 [3 5] user: 2 [1 3] cached: 1 [2] btree: 2 [1 2] user: 2 [2 4] cached: 1 [0] cached: 1 [4] journal: 2 [1 5] user: 1 [3] user: 2 [1 5] user: 2 [3 4] user: 2 [4 5] cached: 1 [1] cached: 1 [3] cached: 1 [5] journal: 2 [1 2] journal: 2 [2 5] btree: 2 [2 5] user: 2 [1 2] user: 2 [1 4] user: 2 [2 3] user: 2 [2 5]

accounting not marked in superblock replicas
  replicas user: 1/2 [3 7], fixing
bcachefs (3c0860e8-07ca-4276-8954-11c1774be868): sb invalid before write: Invalid superblock section replicas_v0: invalid device 7 in entry user: 1/2 [3 7]
replicas_v0 (size 96):
user: 2 [3 7] user: 2 [1 3] cached: 1 [2] btree: 2 [1 2] user: 2 [2 4] cached: 1 [0] cached: 1 [4] journal: 2 [1 5] user: 1 [3] user: 2 [1 5] user: 2 [3 4] user: 2 [4 5] cached: 1 [1] cached: 1 [3] cached: 1 [5] journal: 2 [1 2] journal: 2 [2 5] btree: 2 [2 5] user: 2 [1 2] user: 2 [1 4] user: 2 [2 3] user: 2 [2 5] user: 2 [3 5]

 done
bcachefs (3c0860e8-07ca-4276-8954-11c1774be868): alloc_read... done
bcachefs (3c0860e8-07ca-4276-8954-11c1774be868): stripes_read... done
bcachefs (3c0860e8-07ca-4276-8954-11c1774be868): snapshots_read... done

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

index 6e5e8b6f718227d96902b3636c68c874977acf52..669214127c16a3f7d0b36f4c21e2593b6ed0e274 100644 (file)
@@ -671,10 +671,16 @@ int bch2_accounting_read(struct bch_fs *c)
                        continue;
 
                struct bch_replicas_padded r;
-
                if (!accounting_to_replicas(&r.e, acc->k.data[i].pos))
                        continue;
 
+               /*
+                * If the replicas entry is invalid it'll get cleaned up by
+                * check_allocations:
+                */
+               if (bch2_replicas_entry_validate(&r.e, c, &buf))
+                       continue;
+
                struct disk_accounting_pos k;
                bpos_to_disk_accounting_pos(&k, acc->k.data[i].pos);
 
@@ -683,8 +689,17 @@ int bch2_accounting_read(struct bch_fs *c)
                                "accounting not marked in superblock replicas\n  %s",
                                (printbuf_reset(&buf),
                                 bch2_accounting_key_to_text(&buf, &k),
-                                buf.buf)))
-                       ret = bch2_accounting_update_sb_one(c, acc->k.data[i].pos);
+                                buf.buf))) {
+                       /*
+                        * We're not RW yet and still single threaded, dropping
+                        * and retaking lock is ok:
+                        */
+                       percpu_up_read(&c->mark_lock);
+                       ret = bch2_mark_replicas(c, &r.e);
+                       if (ret)
+                               goto fsck_err;
+                       percpu_down_read(&c->mark_lock);
+               }
        }
 
        preempt_disable();