]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
bcachefs: EIO cleanup
authorKent Overstreet <kent.overstreet@linux.dev>
Thu, 20 Mar 2025 14:16:48 +0000 (10:16 -0400)
committerKent Overstreet <kent.overstreet@linux.dev>
Mon, 24 Mar 2025 13:50:36 +0000 (09:50 -0400)
Replace these with proper private error codes, so that when we get an
error message we're not sifting through the entire codebase to see where
it came from.

Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
13 files changed:
fs/bcachefs/alloc_background.c
fs/bcachefs/alloc_foreground.c
fs/bcachefs/alloc_foreground.h
fs/bcachefs/checksum.c
fs/bcachefs/compress.c
fs/bcachefs/data_update.c
fs/bcachefs/ec.c
fs/bcachefs/ec.h
fs/bcachefs/errcode.h
fs/bcachefs/inode.c
fs/bcachefs/io_write.c
fs/bcachefs/journal_io.c
fs/bcachefs/journal_reclaim.c

index 54e0cc373bb1bd3ec08c2e8ccf813c0bd7e0b5e5..2828baa9b16230e89ffa6a46d60fe5f95c16add6 100644 (file)
@@ -837,7 +837,7 @@ int bch2_trigger_alloc(struct btree_trans *trans,
 
        struct bch_dev *ca = bch2_dev_bucket_tryget(c, new.k->p);
        if (!ca)
-               return -EIO;
+               return -BCH_ERR_trigger_alloc;
 
        struct bch_alloc_v4 old_a_convert;
        const struct bch_alloc_v4 *old_a = bch2_alloc_to_v4(old, &old_a_convert);
@@ -1031,7 +1031,7 @@ fsck_err:
 invalid_bucket:
        bch2_fs_inconsistent(c, "reference to invalid bucket\n  %s",
                             (bch2_bkey_val_to_text(&buf, c, new.s_c), buf.buf));
-       ret = -EIO;
+       ret = -BCH_ERR_trigger_alloc;
        goto err;
 }
 
index 1759c15a77451bc522d9bc3587cacfac144c9b7e..95aafc232290ac4e0a5863709474f833969996f8 100644 (file)
@@ -127,14 +127,14 @@ void __bch2_open_bucket_put(struct bch_fs *c, struct open_bucket *ob)
 
 void bch2_open_bucket_write_error(struct bch_fs *c,
                                  struct open_buckets *obs,
-                                 unsigned dev)
+                                 unsigned dev, int err)
 {
        struct open_bucket *ob;
        unsigned i;
 
        open_bucket_for_each(c, obs, ob, i)
                if (ob->dev == dev && ob->ec)
-                       bch2_ec_bucket_cancel(c, ob);
+                       bch2_ec_bucket_cancel(c, ob, err);
 }
 
 static struct open_bucket *bch2_open_bucket_alloc(struct bch_fs *c)
index baf5dc163c8ab8ceca554ba4ae602f67da20a809..69ec6a012898e6efeebe7b89a5f28d793cf6761b 100644 (file)
@@ -82,7 +82,7 @@ static inline struct open_bucket *ec_open_bucket(struct bch_fs *c,
 }
 
 void bch2_open_bucket_write_error(struct bch_fs *,
-                       struct open_buckets *, unsigned);
+                       struct open_buckets *, unsigned, int);
 
 void __bch2_open_bucket_put(struct bch_fs *, struct open_bucket *);
 
index 7f9e4c59950c365a811e5fabe16b4cf495d5d37f..3726689093e3018fa9b8f9cd900d7e16a61612ea 100644 (file)
@@ -466,7 +466,7 @@ int bch2_rechecksum_bio(struct bch_fs *c, struct bio *bio,
                prt_str(&buf, ")");
                WARN_RATELIMIT(1, "%s", buf.buf);
                printbuf_exit(&buf);
-               return -EIO;
+               return -BCH_ERR_recompute_checksum;
        }
 
        for (i = splits; i < splits + ARRAY_SIZE(splits); i++) {
index 91483f83eb599c746e1ff2dd35ec44a07888b08d..85fc903424928d0a8fd32e3f80d4d90d3e55c335 100644 (file)
@@ -177,7 +177,7 @@ static int __bio_uncompress(struct bch_fs *c, struct bio *src,
        size_t src_len = src->bi_iter.bi_size;
        size_t dst_len = crc.uncompressed_size << 9;
        void *workspace;
-       int ret;
+       int ret = 0, ret2;
 
        enum bch_compression_opts opt = bch2_compression_type_to_opt(crc.compression_type);
        mempool_t *workspace_pool = &c->compress_workspace[opt];
@@ -189,7 +189,7 @@ static int __bio_uncompress(struct bch_fs *c, struct bio *src,
                else
                        ret = -BCH_ERR_compression_workspace_not_initialized;
                if (ret)
-                       goto out;
+                       goto err;
        }
 
        src_data = bio_map_or_bounce(c, src, READ);
@@ -197,10 +197,10 @@ static int __bio_uncompress(struct bch_fs *c, struct bio *src,
        switch (crc.compression_type) {
        case BCH_COMPRESSION_TYPE_lz4_old:
        case BCH_COMPRESSION_TYPE_lz4:
-               ret = LZ4_decompress_safe_partial(src_data.b, dst_data,
-                                                 src_len, dst_len, dst_len);
-               if (ret != dst_len)
-                       goto err;
+               ret2 = LZ4_decompress_safe_partial(src_data.b, dst_data,
+                                                  src_len, dst_len, dst_len);
+               if (ret2 != dst_len)
+                       ret = -BCH_ERR_decompress_lz4;
                break;
        case BCH_COMPRESSION_TYPE_gzip: {
                z_stream strm = {
@@ -214,45 +214,43 @@ static int __bio_uncompress(struct bch_fs *c, struct bio *src,
 
                zlib_set_workspace(&strm, workspace);
                zlib_inflateInit2(&strm, -MAX_WBITS);
-               ret = zlib_inflate(&strm, Z_FINISH);
+               ret2 = zlib_inflate(&strm, Z_FINISH);
 
                mempool_free(workspace, workspace_pool);
 
-               if (ret != Z_STREAM_END)
-                       goto err;
+               if (ret2 != Z_STREAM_END)
+                       ret = -BCH_ERR_decompress_gzip;
                break;
        }
        case BCH_COMPRESSION_TYPE_zstd: {
                ZSTD_DCtx *ctx;
                size_t real_src_len = le32_to_cpup(src_data.b);
 
-               if (real_src_len > src_len - 4)
+               if (real_src_len > src_len - 4) {
+                       ret = -BCH_ERR_decompress_zstd_src_len_bad;
                        goto err;
+               }
 
                workspace = mempool_alloc(workspace_pool, GFP_NOFS);
                ctx = zstd_init_dctx(workspace, zstd_dctx_workspace_bound());
 
-               ret = zstd_decompress_dctx(ctx,
+               ret2 = zstd_decompress_dctx(ctx,
                                dst_data,       dst_len,
                                src_data.b + 4, real_src_len);
 
                mempool_free(workspace, workspace_pool);
 
-               if (ret != dst_len)
-                       goto err;
+               if (ret2 != dst_len)
+                       ret = -BCH_ERR_decompress_zstd;
                break;
        }
        default:
                BUG();
        }
-       ret = 0;
+err:
 fsck_err:
-out:
        bio_unmap_or_unbounce(c, src_data);
        return ret;
-err:
-       ret = -EIO;
-       goto out;
 }
 
 int bch2_bio_uncompress_inplace(struct bch_write_op *op,
@@ -268,18 +266,22 @@ int bch2_bio_uncompress_inplace(struct bch_write_op *op,
        BUG_ON(!bio->bi_vcnt);
        BUG_ON(DIV_ROUND_UP(crc->live_size, PAGE_SECTORS) > bio->bi_max_vecs);
 
-       if (crc->uncompressed_size << 9 > c->opts.encoded_extent_max ||
-           crc->compressed_size << 9   > c->opts.encoded_extent_max) {
-               bch2_write_op_error(op, op->pos.offset, "extent too big to decompress");
-               return -EIO;
+       if (crc->uncompressed_size << 9 > c->opts.encoded_extent_max) {
+               bch2_write_op_error(op, op->pos.offset,
+                                   "extent too big to decompress (%u > %u)",
+                                   crc->uncompressed_size << 9, c->opts.encoded_extent_max);
+               return -BCH_ERR_decompress_exceeded_max_encoded_extent;
        }
 
        data = __bounce_alloc(c, dst_len, WRITE);
 
-       if (__bio_uncompress(c, bio, data.b, *crc)) {
-               if (!c->opts.no_data_io)
-                       bch2_write_op_error(op, op->pos.offset, "decompression error");
-               ret = -EIO;
+       ret = __bio_uncompress(c, bio, data.b, *crc);
+
+       if (c->opts.no_data_io)
+               ret = 0;
+
+       if (ret) {
+               bch2_write_op_error(op, op->pos.offset, "%s", bch2_err_str(ret));
                goto err;
        }
 
@@ -312,7 +314,7 @@ int bch2_bio_uncompress(struct bch_fs *c, struct bio *src,
 
        if (crc.uncompressed_size << 9  > c->opts.encoded_extent_max ||
            crc.compressed_size << 9    > c->opts.encoded_extent_max)
-               return -EIO;
+               return -BCH_ERR_decompress_exceeded_max_encoded_extent;
 
        dst_data = dst_len == dst_iter.bi_size
                ? __bio_map_or_bounce(c, dst, dst_iter, WRITE)
index 08bb7f3019cee40480e51979c6dea3d20354b397..0ec273daccb7d8f6ba0214a3eeb2d02fb7ed0f6f 100644 (file)
@@ -354,7 +354,7 @@ restart_drop_extra_replicas:
                        printbuf_exit(&buf);
 
                        bch2_fatal_error(c);
-                       ret = -EIO;
+                       ret = -BCH_ERR_invalid_bkey;
                        goto out;
                }
 
index c73ba73f6890a7ed693be7d68807db005372fd36..f2b9225fe0bc1b5aa2046a5ec282d826685b5826 100644 (file)
@@ -1124,7 +1124,7 @@ static int ec_stripe_update_extent(struct btree_trans *trans,
 
                bch2_fs_inconsistent(c, "%s", buf.buf);
                printbuf_exit(&buf);
-               return -EIO;
+               return -BCH_ERR_erasure_coding_found_btree_node;
        }
 
        k = bch2_backpointer_get_key(trans, bp, &iter, BTREE_ITER_intent, last_flushed);
@@ -1190,7 +1190,7 @@ static int ec_stripe_update_bucket(struct btree_trans *trans, struct ec_stripe_b
 
        struct bch_dev *ca = bch2_dev_tryget(c, ptr.dev);
        if (!ca)
-               return -EIO;
+               return -BCH_ERR_ENOENT_dev_not_found;
 
        struct bpos bucket_pos = PTR_BUCKET_POS(ca, &ptr);
 
@@ -1227,21 +1227,19 @@ static int ec_stripe_update_extents(struct bch_fs *c, struct ec_stripe_buf *s)
 {
        struct btree_trans *trans = bch2_trans_get(c);
        struct bch_stripe *v = &bkey_i_to_stripe(&s->key)->v;
-       unsigned i, nr_data = v->nr_blocks - v->nr_redundant;
-       int ret = 0;
+       unsigned nr_data = v->nr_blocks - v->nr_redundant;
 
-       ret = bch2_btree_write_buffer_flush_sync(trans);
+       int ret = bch2_btree_write_buffer_flush_sync(trans);
        if (ret)
                goto err;
 
-       for (i = 0; i < nr_data; i++) {
+       for (unsigned i = 0; i < nr_data; i++) {
                ret = ec_stripe_update_bucket(trans, s, i);
                if (ret)
                        break;
        }
 err:
        bch2_trans_put(trans);
-
        return ret;
 }
 
@@ -1451,11 +1449,11 @@ static void ec_stripe_new_cancel(struct bch_fs *c, struct ec_stripe_head *h, int
        ec_stripe_new_set_pending(c, h);
 }
 
-void bch2_ec_bucket_cancel(struct bch_fs *c, struct open_bucket *ob)
+void bch2_ec_bucket_cancel(struct bch_fs *c, struct open_bucket *ob, int err)
 {
        struct ec_stripe_new *s = ob->ec;
 
-       s->err = -EIO;
+       s->err = err;
 }
 
 void *bch2_writepoint_ec_buf(struct bch_fs *c, struct write_point *wp)
index 8f2228e59eda83c3bb61b9e5a126f0b20433a67f..62d27e04d763f53b851aa972938bb913fffc94a6 100644 (file)
@@ -249,7 +249,7 @@ int bch2_ec_read_extent(struct btree_trans *, struct bch_read_bio *, struct bkey
 
 void *bch2_writepoint_ec_buf(struct bch_fs *, struct write_point *);
 
-void bch2_ec_bucket_cancel(struct bch_fs *, struct open_bucket *);
+void bch2_ec_bucket_cancel(struct bch_fs *, struct open_bucket *, int);
 
 int bch2_ec_stripe_new_alloc(struct bch_fs *, struct ec_stripe_head *);
 
index c179954aaf33432385559ef3fcb14e6dccfbbdaf..101806d7ebe1d155db0886697463f130e7e87761 100644 (file)
        x(ENOENT,                       ENOENT_snapshot_tree)                   \
        x(ENOENT,                       ENOENT_dirent_doesnt_match_inode)       \
        x(ENOENT,                       ENOENT_dev_not_found)                   \
+       x(ENOENT,                       ENOENT_dev_bucket_not_found)            \
        x(ENOENT,                       ENOENT_dev_idx_not_found)               \
        x(ENOENT,                       ENOENT_inode_no_backpointer)            \
        x(ENOENT,                       ENOENT_no_snapshot_tree_subvol)         \
        x(EINVAL,                       no_resize_with_buckets_nouse)           \
        x(EINVAL,                       inode_unpack_error)                     \
        x(EINVAL,                       varint_decode_error)                    \
+       x(EINVAL,                       erasure_coding_found_btree_node)        \
        x(EOPNOTSUPP,                   may_not_use_incompat_feature)           \
        x(EROFS,                        erofs_trans_commit)                     \
        x(EROFS,                        erofs_no_writes)                        \
        x(BCH_ERR_operation_blocked,    nocow_lock_blocked)                     \
        x(EIO,                          journal_shutdown)                       \
        x(EIO,                          journal_flush_err)                      \
+       x(EIO,                          journal_write_err)                      \
        x(EIO,                          btree_node_read_err)                    \
        x(BCH_ERR_btree_node_read_err,  btree_node_read_err_cached)             \
        x(EIO,                          sb_not_downgraded)                      \
        x(EIO,                          btree_node_read_validate_error)         \
        x(EIO,                          btree_need_topology_repair)             \
        x(EIO,                          bucket_ref_update)                      \
+       x(EIO,                          trigger_alloc)                          \
        x(EIO,                          trigger_pointer)                        \
        x(EIO,                          trigger_stripe_pointer)                 \
        x(EIO,                          metadata_bucket_inconsistency)          \
        x(EIO,                          EIO_fault_injected)                     \
        x(EIO,                          ec_block_read)                          \
        x(EIO,                          ec_block_write)                         \
-       x(EIO,                          data_read)                              \
+       x(EIO,                          recompute_checksum)                     \
+       x(EIO,                          decompress)                             \
+       x(BCH_ERR_decompress,           decompress_exceeded_max_encoded_extent) \
+       x(BCH_ERR_decompress,           decompress_lz4)                         \
+       x(BCH_ERR_decompress,           decompress_gzip)                        \
+       x(BCH_ERR_decompress,           decompress_zstd_src_len_bad)            \
+       x(BCH_ERR_decompress,           decompress_zstd)                        \
+       x(EIO,                          data_write)                             \
+       x(BCH_ERR_data_write,           data_write_io)                          \
+       x(BCH_ERR_data_write,           data_write_csum)                        \
+       x(BCH_ERR_data_write,           data_write_invalid_ptr)                 \
+       x(BCH_ERR_data_write,           data_write_misaligned)                  \
+       x(BCH_ERR_decompress,           data_read)                              \
        x(BCH_ERR_data_read,            no_device_to_read_from)                 \
        x(BCH_ERR_data_read,            data_read_io_err)                       \
        x(BCH_ERR_data_read,            data_read_csum_err)                     \
index 7aca010e2e1037bf179da2abec4e5b14ffc752b8..1383fdcc42a546945d1613bea47c3e10f5b149ec 100644 (file)
@@ -1079,7 +1079,7 @@ retry:
                bch2_fs_inconsistent(c,
                                     "inode %llu:%u not found when deleting",
                                     inum.inum, snapshot);
-               ret = -EIO;
+               ret = -BCH_ERR_ENOENT_inode;
                goto err;
        }
 
@@ -1243,7 +1243,7 @@ retry:
                bch2_fs_inconsistent(c,
                                     "inode %llu:%u not found when deleting",
                                     inum, snapshot);
-               ret = -EIO;
+               ret = -BCH_ERR_ENOENT_inode;
                goto err;
        }
 
index a861f786c3db775292e88735f0a2977a660cc29b..29671075e3f1d95b8617cdc964e18741fbaf8060 100644 (file)
@@ -535,7 +535,7 @@ static noinline int bch2_write_drop_io_error_ptrs(struct bch_write_op *op)
                                            test_bit(ptr->dev, op->failed.d));
 
                        if (!bch2_bkey_nr_ptrs(bkey_i_to_s_c(src)))
-                               return -EIO;
+                               return -BCH_ERR_data_write_io;
                }
 
                if (dst != src)
@@ -589,7 +589,7 @@ static void __bch2_write_index(struct bch_write_op *op)
 out:
        /* If some a bucket wasn't written, we can't erasure code it: */
        for_each_set_bit(dev, op->failed.d, BCH_SB_MEMBERS_MAX)
-               bch2_open_bucket_write_error(c, &op->open_buckets, dev);
+               bch2_open_bucket_write_error(c, &op->open_buckets, dev, -BCH_ERR_data_write_io);
 
        bch2_open_buckets_put(c, &op->open_buckets);
        return;
@@ -920,7 +920,7 @@ static noinline int bch2_write_prep_encoded_data(struct bch_write_op *op, struct
        return 0;
 csum_err:
        bch2_write_csum_err_msg(op);
-       return -EIO;
+       return -BCH_ERR_data_write_csum;
 }
 
 static int bch2_write_extent(struct bch_write_op *op, struct write_point *wp,
@@ -1127,7 +1127,7 @@ do_write:
        return more;
 csum_err:
        bch2_write_csum_err_msg(op);
-       ret = -EIO;
+       ret = -BCH_ERR_data_write_csum;
 err:
        if (to_wbio(dst)->bounce)
                bch2_bio_free_pages_pool(c, dst);
@@ -1233,7 +1233,7 @@ static void bch2_nocow_write_convert_unwritten(struct bch_write_op *op)
 static void __bch2_nocow_write_done(struct bch_write_op *op)
 {
        if (unlikely(op->flags & BCH_WRITE_io_error)) {
-               op->error = -EIO;
+               op->error = -BCH_ERR_data_write_io;
        } else if (unlikely(op->flags & BCH_WRITE_convert_unwritten))
                bch2_nocow_write_convert_unwritten(op);
 }
@@ -1424,7 +1424,7 @@ err_bucket_stale:
                                    "pointer to invalid bucket in nocow path on device %llu\n  %s",
                                    stale_at->b.inode,
                                    (bch2_bkey_val_to_text(&buf, c, k), buf.buf))) {
-               ret = -EIO;
+               ret = -BCH_ERR_data_write_invalid_ptr;
        } else {
                /* We can retry this: */
                ret = -BCH_ERR_transaction_restart;
@@ -1632,7 +1632,7 @@ CLOSURE_CALLBACK(bch2_write)
 
        if (unlikely(bio->bi_iter.bi_size & (c->opts.block_size - 1))) {
                bch2_write_op_error(op, op->pos.offset, "misaligned write");
-               op->error = -EIO;
+               op->error = -BCH_ERR_data_write_misaligned;
                goto err;
        }
 
index cf2700b06d58f57f557c5855487a452cd2482c6f..4ed6137f04394ee6092752b65d592c347740154f 100644 (file)
@@ -1624,7 +1624,7 @@ static CLOSURE_CALLBACK(journal_write_done)
 
        if (!w->devs_written.nr) {
                bch_err(c, "unable to write journal to sufficient devices");
-               err = -EIO;
+               err = -BCH_ERR_journal_write_err;
        } else {
                bch2_devlist_to_replicas(&replicas.e, BCH_DATA_journal,
                                         w->devs_written);
index 3ed31492e1aa8304a78a7e66d9a89420d0d5e935..5d1547aa118ac841dc49ffa02f756ec2bc6ff454 100644 (file)
@@ -645,7 +645,6 @@ static u64 journal_seq_to_flush(struct journal *j)
  * @j:         journal object
  * @direct:    direct or background reclaim?
  * @kicked:    requested to run since we last ran?
- * Returns:    0 on success, or -EIO if the journal has been shutdown
  *
  * Background journal reclaim writes out btree nodes. It should be run
  * early enough so that we never completely run out of journal buckets.
@@ -685,10 +684,9 @@ static int __bch2_journal_reclaim(struct journal *j, bool direct, bool kicked)
                if (kthread && kthread_should_stop())
                        break;
 
-               if (bch2_journal_error(j)) {
-                       ret = -EIO;
+               ret = bch2_journal_error(j);
+               if (ret)
                        break;
-               }
 
                bch2_journal_do_discards(j);