]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bcachefs: bch2_dev_get_ioref() checks for device not present
authorKent Overstreet <kent.overstreet@linux.dev>
Tue, 30 Apr 2024 19:37:51 +0000 (15:37 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Thu, 9 May 2024 20:23:36 +0000 (16:23 -0400)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
fs/bcachefs/alloc_background.c
fs/bcachefs/backpointers.c
fs/bcachefs/btree_io.c
fs/bcachefs/debug.c
fs/bcachefs/ec.c
fs/bcachefs/io_read.c
fs/bcachefs/io_write.c
fs/bcachefs/journal_io.c
fs/bcachefs/sb-members.h

index b9ded84d2d94ec3a99036be9a0ffe0920d6e61b9..66a1d57db25d4929571040eaf62fb9918517705e 100644 (file)
@@ -1679,7 +1679,7 @@ static int bch2_discard_one_bucket(struct btree_trans *trans,
 
        struct bch_dev *ca = s->ca && s->ca->dev_idx == pos.inode
                ? s->ca
-               : bch2_dev_get_ioref2(c, pos.inode, WRITE);
+               : bch2_dev_get_ioref(c, pos.inode, WRITE);
        if (!ca) {
                bch2_btree_iter_set_pos(need_discard_iter, POS(pos.inode + 1, 0));
                return 0;
@@ -1860,7 +1860,7 @@ static void bch2_do_discards_fast_work(struct work_struct *work)
                        if (i->snapshot)
                                continue;
 
-                       ca = bch2_dev_get_ioref2(c, i->inode, WRITE);
+                       ca = bch2_dev_get_ioref(c, i->inode, WRITE);
                        if (!ca) {
                                darray_remove_item(&c->discard_buckets_in_flight, i);
                                continue;
index 9ac46f868bb45f555c280f588a53573879968107..921d95c46cf7e2b7b97fe5cb6dd659c3ffa081eb 100644 (file)
@@ -486,7 +486,7 @@ found:
 
        bytes = p.crc.compressed_size << 9;
 
-       struct bch_dev *ca = bch2_dev_get_ioref2(c, dev, READ);
+       struct bch_dev *ca = bch2_dev_get_ioref(c, dev, READ);
        if (!ca)
                return false;
 
index 876a26ae0497cb2c20ad743b76e444a9f21f42ee..cbf8f5d90602115576a4bdb975450cdb9199926d 100644 (file)
@@ -1308,7 +1308,7 @@ static void btree_node_read_work(struct work_struct *work)
        while (1) {
                retry = true;
                bch_info(c, "retrying read");
-               ca = bch2_dev_get_ioref2(c, rb->pick.ptr.dev, READ);
+               ca = bch2_dev_get_ioref(c, rb->pick.ptr.dev, READ);
                rb->have_ioref          = ca != NULL;
                bio_reset(bio, NULL, REQ_OP_READ|REQ_SYNC|REQ_META);
                bio->bi_iter.bi_sector  = rb->pick.ptr.offset;
@@ -1618,7 +1618,7 @@ static int btree_node_read_all_replicas(struct bch_fs *c, struct btree *b, bool
 
        i = 0;
        bkey_for_each_ptr_decode(k.k, ptrs, pick, entry) {
-               struct bch_dev *ca = bch2_dev_get_ioref2(c, pick.ptr.dev, READ);
+               struct bch_dev *ca = bch2_dev_get_ioref(c, pick.ptr.dev, READ);
                struct btree_read_bio *rb =
                        container_of(ra->bio[i], struct btree_read_bio, bio);
                rb->c                   = c;
@@ -1695,7 +1695,7 @@ void bch2_btree_node_read(struct btree_trans *trans, struct btree *b,
                return;
        }
 
-       ca = bch2_dev_get_ioref2(c, pick.ptr.dev, READ);
+       ca = bch2_dev_get_ioref(c, pick.ptr.dev, READ);
 
        bio = bio_alloc_bioset(NULL,
                               buf_pages(b->data, btree_buf_bytes(b)),
index d75735aad27e20ff97af0d3f0680dbb20ec1c964..51cbf39283612c53f8ea3412af97acd6ded3cd7a 100644 (file)
@@ -40,7 +40,7 @@ static bool bch2_btree_verify_replica(struct bch_fs *c, struct btree *b,
        struct bio *bio;
        bool failed = false, saw_error = false;
 
-       struct bch_dev *ca = bch2_dev_get_ioref2(c, pick.ptr.dev, READ);
+       struct bch_dev *ca = bch2_dev_get_ioref(c, pick.ptr.dev, READ);
        if (!ca)
                return false;
 
@@ -194,7 +194,7 @@ void bch2_btree_node_ondisk_to_text(struct printbuf *out, struct bch_fs *c,
                return;
        }
 
-       ca = bch2_dev_get_ioref2(c, pick.ptr.dev, READ);
+       ca = bch2_dev_get_ioref(c, pick.ptr.dev, READ);
        if (!ca) {
                prt_printf(out, "error getting device to read from: not online\n");
                return;
index 99a8c8fe8e3b423d4274d6f5ae2077a5773b3b5c..055be0ca925078e1a1def0e6155c50a9460fe2e4 100644 (file)
@@ -732,12 +732,17 @@ static void ec_block_io(struct bch_fs *c, struct ec_stripe_buf *buf,
        struct bch_stripe *v = &bkey_i_to_stripe(&buf->key)->v;
        unsigned offset = 0, bytes = buf->size << 9;
        struct bch_extent_ptr *ptr = &v->ptrs[idx];
-       struct bch_dev *ca = bch2_dev_bkey_exists(c, ptr->dev);
        enum bch_data_type data_type = idx < v->nr_blocks - v->nr_redundant
                ? BCH_DATA_user
                : BCH_DATA_parity;
        int rw = op_is_write(opf);
 
+       struct bch_dev *ca = bch2_dev_get_ioref(c, ptr->dev, rw);
+       if (!ca) {
+               clear_bit(idx, buf->valid);
+               return;
+       }
+
        if (dev_ptr_stale(ca, ptr)) {
                bch_err_ratelimited(c,
                                    "error %s stripe: stale pointer",
@@ -746,10 +751,6 @@ static void ec_block_io(struct bch_fs *c, struct ec_stripe_buf *buf,
                return;
        }
 
-       if (!bch2_dev_get_ioref(ca, rw)) {
-               clear_bit(idx, buf->valid);
-               return;
-       }
 
        this_cpu_add(ca->io_done->sectors[rw][data_type], buf->size);
 
@@ -1354,20 +1355,18 @@ static void zero_out_rest_of_ec_bucket(struct bch_fs *c,
                                       unsigned block,
                                       struct open_bucket *ob)
 {
-       struct bch_dev *ca = bch2_dev_bkey_exists(c, ob->dev);
-       unsigned offset = ca->mi.bucket_size - ob->sectors_free;
-       int ret;
-
-       if (!bch2_dev_get_ioref(ca, WRITE)) {
+       struct bch_dev *ca = bch2_dev_get_ioref(c, ob->dev, WRITE);
+       if (!ca) {
                s->err = -BCH_ERR_erofs_no_writes;
                return;
        }
 
+       unsigned offset = ca->mi.bucket_size - ob->sectors_free;
        memset(s->new_stripe.data[block] + (offset << 9),
               0,
               ob->sectors_free << 9);
 
-       ret = blkdev_issue_zeroout(ca->disk_sb.bdev,
+       int ret = blkdev_issue_zeroout(ca->disk_sb.bdev,
                        ob->bucket * ca->mi.bucket_size + offset,
                        ob->sectors_free,
                        GFP_KERNEL, 0);
index 4aa7c6d8d6939d15f90a55ea68a5a634810548d6..3e7dceef4cb5a4cd6350bc9080b4db5b88ddbe0d 100644 (file)
@@ -830,7 +830,7 @@ retry_pick:
                goto err;
        }
 
-       struct bch_dev *ca = bch2_dev_get_ioref2(c, pick.ptr.dev, READ);
+       struct bch_dev *ca = bch2_dev_get_ioref(c, pick.ptr.dev, READ);
 
        /*
         * Stale dirty pointers are treated as IO errors, but @failed isn't
index d87c0d2f99021a71a1d36b1c720915a82da8a7ab..9401d13e31bb63cdf0e99977b628a940629325aa 100644 (file)
@@ -409,7 +409,7 @@ void bch2_submit_wbio_replicas(struct bch_write_bio *wbio, struct bch_fs *c,
        bkey_for_each_ptr(ptrs, ptr) {
                struct bch_dev *ca = nocow
                        ? bch2_dev_have_ref(c, ptr->dev)
-                       : bch2_dev_get_ioref2(c, ptr->dev, type == BCH_DATA_btree ? READ : WRITE);
+                       : bch2_dev_get_ioref(c, ptr->dev, type == BCH_DATA_btree ? READ : WRITE);
 
                if (to_entry(ptr + 1) < ptrs.end) {
                        n = to_wbio(bio_alloc_clone(NULL, &wbio->bio, GFP_NOFS, &c->replica_set));
@@ -1265,7 +1265,7 @@ retry:
                /* Get iorefs before dropping btree locks: */
                struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
                bkey_for_each_ptr(ptrs, ptr) {
-                       struct bch_dev *ca = bch2_dev_get_ioref2(c, ptr->dev, WRITE);
+                       struct bch_dev *ca = bch2_dev_get_ioref(c, ptr->dev, WRITE);
                        if (unlikely(!ca))
                                goto err_get_ioref;
 
index f6f9d03bb8a3ac8b62c1ec65ae3ad6620c44ae4e..d3bc5df0f3de5c820ece071140ee849326fa1137 100644 (file)
@@ -1722,7 +1722,7 @@ static CLOSURE_CALLBACK(journal_write_submit)
        unsigned sectors = vstruct_sectors(w->data, c->block_bits);
 
        extent_for_each_ptr(bkey_i_to_s_extent(&w->key), ptr) {
-               struct bch_dev *ca = bch2_dev_get_ioref2(c, ptr->dev, WRITE);
+               struct bch_dev *ca = bch2_dev_get_ioref(c, ptr->dev, WRITE);
                if (!ca) {
                        /* XXX: fix this */
                        bch_err(c, "missing device for journal write\n");
index f2a7794b0b500ee1f0bec27b2f176509d5a5a42d..ae28b5d401e33f4f9aab732b6ef42f1351e3d9ba 100644 (file)
@@ -29,19 +29,6 @@ static inline bool bch2_dev_is_readable(struct bch_dev *ca)
                ca->mi.state != BCH_MEMBER_STATE_failed;
 }
 
-static inline bool bch2_dev_get_ioref(struct bch_dev *ca, int rw)
-{
-       if (!percpu_ref_tryget(&ca->io_ref))
-               return false;
-
-       if (ca->mi.state == BCH_MEMBER_STATE_rw ||
-           (ca->mi.state == BCH_MEMBER_STATE_ro && rw == READ))
-               return true;
-
-       percpu_ref_put(&ca->io_ref);
-       return false;
-}
-
 static inline unsigned dev_mask_nr(const struct bch_devs_mask *devs)
 {
        return bitmap_weight(devs->d, BCH_SB_MEMBERS_MAX);
@@ -285,7 +272,7 @@ static inline struct bch_dev *bch2_dev_iterate(struct bch_fs *c, struct bch_dev
        return bch2_dev_tryget(c, dev_idx);
 }
 
-static inline struct bch_dev *bch2_dev_get_ioref2(struct bch_fs *c, unsigned dev, int rw)
+static inline struct bch_dev *bch2_dev_get_ioref(struct bch_fs *c, unsigned dev, int rw)
 {
        rcu_read_lock();
        struct bch_dev *ca = bch2_dev_rcu(c, dev);