bcachefs: bch2_check_alloc_key() -> bch2_dev_tryget_noerror()
authorKent Overstreet <kent.overstreet@linux.dev>
Tue, 30 Apr 2024 19:43:20 +0000 (15:43 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Wed, 8 May 2024 21:29:22 +0000 (17:29 -0400)
More elimination of bch2_dev_bkey_exists() usage.

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

index 97d70def49b31680729d4b8dd452c22da4fa99f4..e61f00efe619b77ffcd8546b7f3b1b095211ffb5 100644 (file)
@@ -1024,24 +1024,25 @@ int bch2_check_alloc_key(struct btree_trans *trans,
                         struct btree_iter *bucket_gens_iter)
 {
        struct bch_fs *c = trans->c;
-       struct bch_dev *ca;
        struct bch_alloc_v4 a_convert;
        const struct bch_alloc_v4 *a;
        unsigned discard_key_type, freespace_key_type;
        unsigned gens_offset;
        struct bkey_s_c k;
        struct printbuf buf = PRINTBUF;
-       int ret;
+       int ret = 0;
 
-       if (fsck_err_on(!bch2_dev_bucket_exists(c, alloc_k.k->p), c,
-                       alloc_key_to_missing_dev_bucket,
+       struct bch_dev *ca = bch2_dev_bucket_tryget_noerror(c, alloc_k.k->p);
+       if (fsck_err_on(!ca,
+                       c, alloc_key_to_missing_dev_bucket,
                        "alloc key for invalid device:bucket %llu:%llu",
                        alloc_k.k->p.inode, alloc_k.k->p.offset))
-               return bch2_btree_delete_at(trans, alloc_iter, 0);
+               ret = bch2_btree_delete_at(trans, alloc_iter, 0);
+       if (!ca)
+               return ret;
 
-       ca = bch2_dev_bkey_exists(c, alloc_k.k->p.inode);
        if (!ca->mi.freespace_initialized)
-               return 0;
+               goto out;
 
        a = bch2_alloc_to_v4(alloc_k, &a_convert);
 
@@ -1140,8 +1141,10 @@ int bch2_check_alloc_key(struct btree_trans *trans,
                if (ret)
                        goto err;
        }
+out:
 err:
 fsck_err:
+       bch2_dev_put(ca);
        printbuf_exit(&buf);
        return ret;
 }
index f352d88d9b8e5ee5ee26402abe3cdaedc1d7fda6..95cf3c2907344106e15ac90468e4f736c552e5b8 100644 (file)
@@ -35,11 +35,6 @@ static inline u64 sector_to_bucket_and_offset(const struct bch_dev *ca, sector_t
        return div_u64_rem(s, ca->mi.bucket_size, offset);
 }
 
-static inline bool bucket_valid(const struct bch_dev *ca, u64 b)
-{
-       return b - ca->mi.first_bucket < ca->mi.nbuckets_minus_first;
-}
-
 #define for_each_bucket(_b, _buckets)                          \
        for (_b = (_buckets)->b + (_buckets)->first_bucket;     \
             _b < (_buckets)->b + (_buckets)->nbuckets; _b++)
index 2ca557bffc0e7f5f69372a3b4313f0dc3c7535f5..8f197bb088a06cc30a785e3fe7805859fb44e57d 100644 (file)
@@ -14,6 +14,11 @@ void bch2_dev_missing(struct bch_fs *c, unsigned dev)
        bch2_fs_inconsistent(c, "pointer to nonexistent device %u", dev);
 }
 
+void bch2_dev_bucket_missing(struct bch_fs *c, struct bpos bucket)
+{
+       bch2_fs_inconsistent(c, "pointer to nonexistent bucket %llu:%llu", bucket.inode, bucket.offset);
+}
+
 #define x(t, n, ...) [n] = #t,
 static const char * const bch2_iops_measurements[] = {
        BCH_IOPS_MEASUREMENTS()
index 714559e2ef5938ef0ca715fe40397c5075d37d1a..503b56051d7ebadcf8982f8cceb76c89b7a424bf 100644 (file)
@@ -190,6 +190,11 @@ static inline bool bch2_dev_exists(const struct bch_fs *c, unsigned dev)
        return dev < c->sb.nr_devices && c->devs[dev];
 }
 
+static inline bool bucket_valid(const struct bch_dev *ca, u64 b)
+{
+       return b - ca->mi.first_bucket < ca->mi.nbuckets_minus_first;
+}
+
 /*
  * If a key exists that references a device, the device won't be going away and
  * we can omit rcu_read_lock():
@@ -237,6 +242,26 @@ static inline struct bch_dev *bch2_dev_tryget(struct bch_fs *c, unsigned dev)
        return ca;
 }
 
+static inline struct bch_dev *bch2_dev_bucket_tryget_noerror(struct bch_fs *c, struct bpos bucket)
+{
+       struct bch_dev *ca = bch2_dev_tryget_noerror(c, bucket.inode);
+       if (ca && !bucket_valid(ca, bucket.offset)) {
+               bch2_dev_put(ca);
+               ca = NULL;
+       }
+       return ca;
+}
+
+void bch2_dev_bucket_missing(struct bch_fs *, struct bpos);
+
+static inline struct bch_dev *bch2_dev_bucket_tryget(struct bch_fs *c, struct bpos bucket)
+{
+       struct bch_dev *ca = bch2_dev_bucket_tryget_noerror(c, bucket);
+       if (!ca)
+               bch2_dev_bucket_missing(c, bucket);
+       return ca;
+}
+
 /* XXX kill, move to struct bch_fs */
 static inline struct bch_devs_mask bch2_online_devs(struct bch_fs *c)
 {