]> www.infradead.org Git - users/hch/misc.git/commitdiff
bcachefs: bch2_dev_rcu_noerror()
authorKent Overstreet <kent.overstreet@linux.dev>
Sun, 1 Sep 2024 22:12:26 +0000 (18:12 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Sat, 21 Sep 2024 15:39:48 +0000 (11:39 -0400)
bch2_dev_rcu() now properly errors if the device is invalid

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/alloc_background.h
fs/bcachefs/backpointers.c
fs/bcachefs/buckets.c
fs/bcachefs/extents.c
fs/bcachefs/replicas.c
fs/bcachefs/sb-members.h

index 577f823a0207f4078b5f8b1de34dbfcfd5d9cf32..f8e87c6721b1220864132b96d283336f5ae73416 100644 (file)
@@ -16,7 +16,7 @@ enum bch_validate_flags;
 static inline bool bch2_dev_bucket_exists(struct bch_fs *c, struct bpos pos)
 {
        rcu_read_lock();
-       struct bch_dev *ca = bch2_dev_rcu(c, pos.inode);
+       struct bch_dev *ca = bch2_dev_rcu_noerror(c, pos.inode);
        bool ret = ca && bucket_valid(ca, pos.offset);
        rcu_read_unlock();
        return ret;
index 2bdce3185f2977bba01e8e8a73d49546de81c83f..6c395445f60cc678a2c89d7a2ab0441eedd0162a 100644 (file)
@@ -55,7 +55,7 @@ int bch2_backpointer_validate(struct bch_fs *c, struct bkey_s_c k,
        struct bkey_s_c_backpointer bp = bkey_s_c_to_backpointer(k);
 
        rcu_read_lock();
-       struct bch_dev *ca = bch2_dev_rcu(c, bp.k->p.inode);
+       struct bch_dev *ca = bch2_dev_rcu_noerror(c, bp.k->p.inode);
        if (!ca) {
                /* these will be caught by fsck */
                rcu_read_unlock();
@@ -89,7 +89,7 @@ void bch2_backpointer_to_text(struct printbuf *out, const struct bch_backpointer
 void bch2_backpointer_k_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c k)
 {
        rcu_read_lock();
-       struct bch_dev *ca = bch2_dev_rcu(c, k.k->p.inode);
+       struct bch_dev *ca = bch2_dev_rcu_noerror(c, k.k->p.inode);
        if (ca) {
                struct bpos bucket = bp_pos_to_bucket(ca, k.k->p);
                rcu_read_unlock();
@@ -673,7 +673,7 @@ static int check_extent_to_backpointers(struct btree_trans *trans,
                        continue;
 
                rcu_read_lock();
-               struct bch_dev *ca = bch2_dev_rcu(c, p.ptr.dev);
+               struct bch_dev *ca = bch2_dev_rcu_noerror(c, p.ptr.dev);
                if (ca)
                        bch2_extent_ptr_to_bp(c, ca, btree, level, k, p, entry, &bucket_pos, &bp);
                rcu_read_unlock();
index 4abd22d7e3f84b692d077de41461fdfc239e5c21..2d1d4dae631bbc89b7f445310b45dfc6287cb28a 100644 (file)
@@ -281,7 +281,7 @@ int bch2_check_fix_ptrs(struct btree_trans *trans,
                        goto err;
 
                rcu_read_lock();
-               bch2_bkey_drop_ptrs(bkey_i_to_s(new), ptr, !bch2_dev_rcu(c, ptr->dev));
+               bch2_bkey_drop_ptrs(bkey_i_to_s(new), ptr, !bch2_dev_exists(c, ptr->dev));
                rcu_read_unlock();
 
                if (level) {
index 324303bf4353000753bf70e67519c37a98a7e092..ad63445b85e517b70865992b11996808d05077e6 100644 (file)
@@ -1021,7 +1021,7 @@ void bch2_extent_ptr_to_text(struct printbuf *out, struct bch_fs *c, const struc
 {
        out->atomic++;
        rcu_read_lock();
-       struct bch_dev *ca = bch2_dev_rcu(c, ptr->dev);
+       struct bch_dev *ca = bch2_dev_rcu_noerror(c, ptr->dev);
        if (!ca) {
                prt_printf(out, "ptr: %u:%llu gen %u%s", ptr->dev,
                           (u64) ptr->offset, ptr->gen,
@@ -1125,8 +1125,9 @@ static int extent_ptr_validate(struct bch_fs *c,
 {
        int ret = 0;
 
+       /* bad pointers are repaired by check_fix_ptrs(): */
        rcu_read_lock();
-       struct bch_dev *ca = bch2_dev_rcu(c, ptr->dev);
+       struct bch_dev *ca = bch2_dev_rcu_noerror(c, ptr->dev);
        if (!ca) {
                rcu_read_unlock();
                return 0;
index 659ee0516c25ccaef92c6fee2f6e4ea4cc0d172f..226b41baea2f024c9cc88921cc5e40a546080519 100644 (file)
@@ -795,7 +795,7 @@ bool bch2_have_enough_devs(struct bch_fs *c, struct bch_devs_mask devs,
                for (unsigned i = 0; i < e->nr_devs; i++) {
                        nr_online += test_bit(e->devs[i], devs.d);
 
-                       struct bch_dev *ca = bch2_dev_rcu(c, e->devs[i]);
+                       struct bch_dev *ca = bch2_dev_rcu_noerror(c, e->devs[i]);
                        nr_failed += !ca || ca->mi.state == BCH_MEMBER_STATE_failed;
                }
                rcu_read_unlock();
index 1a21d1f15a9c87a1d04985f11a2cff0870323f66..762083b564ee5909071eb4235c3d5cd6e72ee519 100644 (file)
@@ -198,29 +198,37 @@ static inline struct bch_dev *bch2_dev_locked(struct bch_fs *c, unsigned dev)
                                         lockdep_is_held(&c->state_lock));
 }
 
-static inline struct bch_dev *bch2_dev_rcu(struct bch_fs *c, unsigned dev)
+static inline struct bch_dev *bch2_dev_rcu_noerror(struct bch_fs *c, unsigned dev)
 {
        return c && dev < c->sb.nr_devices
                ? rcu_dereference(c->devs[dev])
                : NULL;
 }
 
+void bch2_dev_missing(struct bch_fs *, unsigned);
+
+static inline struct bch_dev *bch2_dev_rcu(struct bch_fs *c, unsigned dev)
+{
+       struct bch_dev *ca = bch2_dev_rcu_noerror(c, dev);
+       if (unlikely(!ca))
+               bch2_dev_missing(c, dev);
+       return ca;
+}
+
 static inline struct bch_dev *bch2_dev_tryget_noerror(struct bch_fs *c, unsigned dev)
 {
        rcu_read_lock();
-       struct bch_dev *ca = bch2_dev_rcu(c, dev);
+       struct bch_dev *ca = bch2_dev_rcu_noerror(c, dev);
        if (ca)
                bch2_dev_get(ca);
        rcu_read_unlock();
        return ca;
 }
 
-void bch2_dev_missing(struct bch_fs *, unsigned);
-
 static inline struct bch_dev *bch2_dev_tryget(struct bch_fs *c, unsigned dev)
 {
        struct bch_dev *ca = bch2_dev_tryget_noerror(c, dev);
-       if (!ca)
+       if (unlikely(!ca))
                bch2_dev_missing(c, dev);
        return ca;
 }