]> www.infradead.org Git - linux.git/commitdiff
bcachefs: Annotate bch_replicas_entry_{v0,v1} with __counted_by()
authorThorsten Blum <thorsten.blum@toblux.com>
Mon, 26 Aug 2024 10:11:36 +0000 (12:11 +0200)
committerKent Overstreet <kent.overstreet@linux.dev>
Mon, 9 Sep 2024 13:41:49 +0000 (09:41 -0400)
Add the __counted_by compiler attribute to the flexible array members
devs to improve access bounds-checking via CONFIG_UBSAN_BOUNDS and
CONFIG_FORTIFY_SOURCE.

Increment nr_devs before adding a new device to the devs array and
adjust the array indexes accordingly. Add a helper macro for adding a
new device.

In bch2_journal_read(), explicitly set nr_devs to 0.

Signed-off-by: Thorsten Blum <thorsten.blum@toblux.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/buckets.c
fs/bcachefs/journal_io.c
fs/bcachefs/replicas.c
fs/bcachefs/replicas_format.h

index 721bbe1dffc11af3f5583741ba25abce3cba31b5..4a0f55dc78c4e7281f97016efd4ce7812c4279e6 100644 (file)
@@ -741,7 +741,7 @@ static int __trigger_extent(struct btree_trans *trans,
                                return ret;
                } else if (!p.has_ec) {
                        *replicas_sectors       += disk_sectors;
-                       acc_replicas_key.replicas.devs[acc_replicas_key.replicas.nr_devs++] = p.ptr.dev;
+                       replicas_entry_add_dev(&acc_replicas_key.replicas, p.ptr.dev);
                } else {
                        ret = bch2_trigger_stripe_ptr(trans, k, p, data_type, disk_sectors, flags);
                        if (ret)
index 32b886feb2caded82bb63bc32640de01e17864f5..30460bce04becca0d4262664a5a3e7147d1301b1 100644 (file)
@@ -1353,6 +1353,7 @@ int bch2_journal_read(struct bch_fs *c,
        genradix_for_each(&c->journal_entries, radix_iter, _i) {
                struct bch_replicas_padded replicas = {
                        .e.data_type = BCH_DATA_journal,
+                       .e.nr_devs = 0,
                        .e.nr_required = 1,
                };
 
@@ -1379,7 +1380,7 @@ int bch2_journal_read(struct bch_fs *c,
                        goto err;
 
                darray_for_each(i->ptrs, ptr)
-                       replicas.e.devs[replicas.e.nr_devs++] = ptr->dev;
+                       replicas_entry_add_dev(&replicas.e, ptr->dev);
 
                bch2_replicas_entry_sort(&replicas.e);
 
index 1f34c92a6d11417f61081522630655f975d69571..659ee0516c25ccaef92c6fee2f6e4ea4cc0d172f 100644 (file)
@@ -123,7 +123,7 @@ static void extent_to_replicas(struct bkey_s_c k,
                        continue;
 
                if (!p.has_ec)
-                       r->devs[r->nr_devs++] = p.ptr.dev;
+                       replicas_entry_add_dev(r, p.ptr.dev);
                else
                        r->nr_required = 0;
        }
@@ -140,7 +140,7 @@ static void stripe_to_replicas(struct bkey_s_c k,
        for (ptr = s.v->ptrs;
             ptr < s.v->ptrs + s.v->nr_blocks;
             ptr++)
-               r->devs[r->nr_devs++] = ptr->dev;
+               replicas_entry_add_dev(r, ptr->dev);
 }
 
 void bch2_bkey_to_replicas(struct bch_replicas_entry_v1 *e,
@@ -181,7 +181,7 @@ void bch2_devlist_to_replicas(struct bch_replicas_entry_v1 *e,
        e->nr_required  = 1;
 
        darray_for_each(devs, i)
-               e->devs[e->nr_devs++] = *i;
+               replicas_entry_add_dev(e, *i);
 
        bch2_replicas_entry_sort(e);
 }
index b97208195d064344f8509de7aceb59ef146c6fac..b7eff904acdb7170b6fc1191f101ddb4079ce8cd 100644 (file)
@@ -5,7 +5,7 @@
 struct bch_replicas_entry_v0 {
        __u8                    data_type;
        __u8                    nr_devs;
-       __u8                    devs[];
+       __u8                    devs[] __counted_by(nr_devs);
 } __packed;
 
 struct bch_sb_field_replicas_v0 {
@@ -17,7 +17,7 @@ struct bch_replicas_entry_v1 {
        __u8                    data_type;
        __u8                    nr_devs;
        __u8                    nr_required;
-       __u8                    devs[];
+       __u8                    devs[] __counted_by(nr_devs);
 } __packed;
 
 struct bch_sb_field_replicas {
@@ -28,4 +28,9 @@ struct bch_sb_field_replicas {
 #define replicas_entry_bytes(_i)                                       \
        (offsetof(typeof(*(_i)), devs) + (_i)->nr_devs)
 
+#define replicas_entry_add_dev(e, d) ({                                        \
+       (e)->nr_devs++;                                                 \
+       (e)->devs[(e)->nr_devs - 1] = (d);                              \
+})
+
 #endif /* _BCACHEFS_REPLICAS_FORMAT_H */