bcachefs: journal_replay_entry_early() checks for nonexistent device
authorKent Overstreet <kent.overstreet@linux.dev>
Tue, 30 Apr 2024 19:45:26 +0000 (15:45 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Wed, 8 May 2024 21:29:22 +0000 (17:29 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/recovery.c

index a6447ffd336e3dbf691908f0e2a9f965420fdefe..1266916ac03f05600d3b3f049f3ee94458a96281 100644 (file)
@@ -373,14 +373,17 @@ static int journal_replay_entry_early(struct bch_fs *c,
        case BCH_JSET_ENTRY_dev_usage: {
                struct jset_entry_dev_usage *u =
                        container_of(entry, struct jset_entry_dev_usage, entry);
-               struct bch_dev *ca = bch2_dev_bkey_exists(c, le32_to_cpu(u->dev));
-               unsigned i, nr_types = jset_entry_dev_usage_nr_types(u);
-
-               for (i = 0; i < min_t(unsigned, nr_types, BCH_DATA_NR); i++) {
-                       ca->usage_base->d[i].buckets    = le64_to_cpu(u->d[i].buckets);
-                       ca->usage_base->d[i].sectors    = le64_to_cpu(u->d[i].sectors);
-                       ca->usage_base->d[i].fragmented = le64_to_cpu(u->d[i].fragmented);
-               }
+               unsigned nr_types = jset_entry_dev_usage_nr_types(u);
+
+               rcu_read_lock();
+               struct bch_dev *ca = bch2_dev_rcu(c, le32_to_cpu(u->dev));
+               if (ca)
+                       for (unsigned i = 0; i < min_t(unsigned, nr_types, BCH_DATA_NR); i++) {
+                               ca->usage_base->d[i].buckets    = le64_to_cpu(u->d[i].buckets);
+                               ca->usage_base->d[i].sectors    = le64_to_cpu(u->d[i].sectors);
+                               ca->usage_base->d[i].fragmented = le64_to_cpu(u->d[i].fragmented);
+                       }
+               rcu_read_unlock();
 
                break;
        }