diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2022-09-28 00:17:23 +0300 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-23 00:09:42 +0300 |
commit | e0eaf8625974d91b4e50a0911b11af5d46c811c9 (patch) | |
tree | 9dbef3cf2a33da8af42d1b9fee9e089890c124e4 | |
parent | 99e2146bea04d092d9fe2825c4dcd1fb19994bce (diff) | |
download | linux-e0eaf8625974d91b4e50a0911b11af5d46c811c9.tar.xz |
bcachefs: Factor out bch2_write_drop_io_error_ptrs()
Move slowpath code to a separate, non-inline function.
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/io.c | 39 | ||||
-rw-r--r-- | fs/bcachefs/io.h | 2 |
2 files changed, 28 insertions, 13 deletions
diff --git a/fs/bcachefs/io.c b/fs/bcachefs/io.c index ed78cb8d90a2..648e4a0a21a9 100644 --- a/fs/bcachefs/io.c +++ b/fs/bcachefs/io.c @@ -615,17 +615,11 @@ static void bch2_write_done(struct closure *cl) op->end_io(op); } -/** - * bch_write_index - after a write, update index to point to new data - */ -static void __bch2_write_index(struct bch_write_op *op) +static noinline int bch2_write_drop_io_error_ptrs(struct bch_write_op *op) { - struct bch_fs *c = op->c; struct keylist *keys = &op->insert_keys; struct bch_extent_ptr *ptr; - struct bkey_i *src, *dst = keys->keys, *n, *k; - unsigned dev; - int ret = 0; + struct bkey_i *src, *dst = keys->keys, *n; for (src = keys->keys; src != keys->top; src = n) { n = bkey_next(src); @@ -634,10 +628,8 @@ static void __bch2_write_index(struct bch_write_op *op) bch2_bkey_drop_ptrs(bkey_i_to_s(src), ptr, test_bit(ptr->dev, op->failed.d)); - if (!bch2_bkey_nr_ptrs(bkey_i_to_s_c(src))) { - ret = -EIO; - goto err; - } + if (!bch2_bkey_nr_ptrs(bkey_i_to_s_c(src))) + return -EIO; } if (dst != src) @@ -646,6 +638,25 @@ static void __bch2_write_index(struct bch_write_op *op) } keys->top = dst; + return 0; +} + +/** + * bch_write_index - after a write, update index to point to new data + */ +static void __bch2_write_index(struct bch_write_op *op) +{ + struct bch_fs *c = op->c; + struct keylist *keys = &op->insert_keys; + struct bkey_i *k; + unsigned dev; + int ret = 0; + + if (unlikely(op->flags & BCH_WRITE_IO_ERROR)) { + ret = bch2_write_drop_io_error_ptrs(op); + if (ret) + goto err; + } /* * probably not the ideal place to hook this in, but I don't @@ -787,8 +798,10 @@ static void bch2_write_endio(struct bio *bio) op->pos.inode, op->pos.offset - bio_sectors(bio), /* XXX definitely wrong */ "data write error: %s", - bch2_blk_status_to_str(bio->bi_status))) + bch2_blk_status_to_str(bio->bi_status))) { set_bit(wbio->dev, op->failed.d); + op->flags |= BCH_WRITE_IO_ERROR; + } if (wbio->have_ioref) { bch2_latency_acct(ca, wbio->submit_time, WRITE); diff --git a/fs/bcachefs/io.h b/fs/bcachefs/io.h index b484d3387968..a3505762b68d 100644 --- a/fs/bcachefs/io.h +++ b/fs/bcachefs/io.h @@ -43,6 +43,7 @@ enum bch_write_flags { __BCH_WRITE_JOURNAL_SEQ_PTR, __BCH_WRITE_IN_WORKER, __BCH_WRITE_DONE, + __BCH_WRITE_IO_ERROR, }; #define BCH_WRITE_ALLOC_NOWAIT (1U << __BCH_WRITE_ALLOC_NOWAIT) @@ -61,6 +62,7 @@ enum bch_write_flags { #define BCH_WRITE_JOURNAL_SEQ_PTR (1U << __BCH_WRITE_JOURNAL_SEQ_PTR) #define BCH_WRITE_IN_WORKER (1U << __BCH_WRITE_IN_WORKER) #define BCH_WRITE_DONE (1U << __BCH_WRITE_DONE) +#define BCH_WRITE_IO_ERROR (1U << __BCH_WRITE_IO_ERROR) static inline u64 *op_journal_seq(struct bch_write_op *op) { |