mirror of
https://github.com/torvalds/linux.git
synced 2026-08-01 03:59:40 +02:00
bcachefs: cleanup redundant code around data_update_op initialization
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
536d789781
commit
6f7111f820
|
|
@ -20,6 +20,8 @@
|
|||
#include "subvolume.h"
|
||||
#include "trace.h"
|
||||
|
||||
#include <linux/ioprio.h>
|
||||
|
||||
static void bkey_put_dev_refs(struct bch_fs *c, struct bkey_s_c k)
|
||||
{
|
||||
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
|
||||
|
|
@ -427,16 +429,15 @@ int bch2_data_update_index_update(struct bch_write_op *op)
|
|||
return bch2_trans_run(op->c, __bch2_data_update_index_update(trans, op));
|
||||
}
|
||||
|
||||
void bch2_data_update_read_done(struct data_update *m,
|
||||
struct bch_extent_crc_unpacked crc)
|
||||
void bch2_data_update_read_done(struct data_update *m)
|
||||
{
|
||||
m->read_done = true;
|
||||
|
||||
/* write bio must own pages: */
|
||||
BUG_ON(!m->op.wbio.bio.bi_vcnt);
|
||||
|
||||
m->op.crc = crc;
|
||||
m->op.wbio.bio.bi_iter.bi_size = crc.compressed_size << 9;
|
||||
m->op.crc = m->rbio.pick.crc;
|
||||
m->op.wbio.bio.bi_iter.bi_size = m->op.crc.compressed_size << 9;
|
||||
|
||||
this_cpu_add(m->op.c->counters[BCH_COUNTER_move_extent_write], m->k.k->k.size);
|
||||
|
||||
|
|
@ -454,6 +455,8 @@ void bch2_data_update_exit(struct data_update *update)
|
|||
bch2_bkey_buf_exit(&update->k, c);
|
||||
bch2_disk_reservation_put(c, &update->op.res);
|
||||
bch2_bio_free_pages_pool(c, &update->op.wbio.bio);
|
||||
kfree(update->bvecs);
|
||||
update->bvecs = NULL;
|
||||
}
|
||||
|
||||
static int bch2_update_unwritten_extent(struct btree_trans *trans,
|
||||
|
|
@ -779,7 +782,31 @@ int bch2_data_update_init(struct btree_trans *trans,
|
|||
goto out;
|
||||
}
|
||||
|
||||
/* write path might have to decompress data: */
|
||||
unsigned buf_bytes = 0;
|
||||
bkey_for_each_ptr_decode(k.k, ptrs, p, entry)
|
||||
buf_bytes = max_t(unsigned, buf_bytes, p.crc.uncompressed_size << 9);
|
||||
|
||||
unsigned nr_vecs = DIV_ROUND_UP(buf_bytes, PAGE_SIZE);
|
||||
|
||||
m->bvecs = kmalloc_array(nr_vecs, sizeof*(m->bvecs), GFP_KERNEL);
|
||||
if (!m->bvecs)
|
||||
goto enomem;
|
||||
|
||||
bio_init(&m->rbio.bio, NULL, m->bvecs, nr_vecs, REQ_OP_READ);
|
||||
bio_init(&m->op.wbio.bio, NULL, m->bvecs, nr_vecs, 0);
|
||||
|
||||
if (bch2_bio_alloc_pages(&m->op.wbio.bio, buf_bytes, GFP_KERNEL))
|
||||
goto enomem;
|
||||
|
||||
rbio_init(&m->rbio.bio, c, io_opts, NULL);
|
||||
m->rbio.bio.bi_iter.bi_size = buf_bytes;
|
||||
m->rbio.bio.bi_iter.bi_sector = bkey_start_offset(k.k);
|
||||
m->op.wbio.bio.bi_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0);
|
||||
|
||||
return 0;
|
||||
enomem:
|
||||
ret = -ENOMEM;
|
||||
out:
|
||||
bch2_data_update_exit(m);
|
||||
return ret ?: -BCH_ERR_data_update_done;
|
||||
|
|
|
|||
|
|
@ -32,8 +32,7 @@ struct data_update {
|
|||
|
||||
struct bch_read_bio rbio;
|
||||
struct bch_write_op op;
|
||||
/* Must be last since it is variable size */
|
||||
struct bio_vec bi_inline_vecs[];
|
||||
struct bio_vec *bvecs;
|
||||
};
|
||||
|
||||
void bch2_data_update_to_text(struct printbuf *, struct data_update *);
|
||||
|
|
@ -41,8 +40,7 @@ void bch2_data_update_inflight_to_text(struct printbuf *, struct data_update *);
|
|||
|
||||
int bch2_data_update_index_update(struct bch_write_op *);
|
||||
|
||||
void bch2_data_update_read_done(struct data_update *,
|
||||
struct bch_extent_crc_unpacked);
|
||||
void bch2_data_update_read_done(struct data_update *);
|
||||
|
||||
int bch2_extent_drop_ptrs(struct btree_trans *,
|
||||
struct btree_iter *,
|
||||
|
|
|
|||
|
|
@ -125,45 +125,37 @@ static inline int should_promote(struct bch_fs *c, struct bkey_s_c k,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void promote_free(struct bch_fs *c, struct promote_op *op)
|
||||
static noinline void promote_free(struct bch_read_bio *rbio)
|
||||
{
|
||||
int ret;
|
||||
struct promote_op *op = container_of(rbio, struct promote_op, write.rbio);
|
||||
struct bch_fs *c = rbio->c;
|
||||
|
||||
int ret = rhashtable_remove_fast(&c->promote_table, &op->hash,
|
||||
bch_promote_params);
|
||||
BUG_ON(ret);
|
||||
|
||||
bch2_data_update_exit(&op->write);
|
||||
|
||||
ret = rhashtable_remove_fast(&c->promote_table, &op->hash,
|
||||
bch_promote_params);
|
||||
BUG_ON(ret);
|
||||
bch2_write_ref_put(c, BCH_WRITE_REF_promote);
|
||||
kfree_rcu(op, rcu);
|
||||
}
|
||||
|
||||
static void promote_done(struct bch_write_op *wop)
|
||||
{
|
||||
struct promote_op *op =
|
||||
container_of(wop, struct promote_op, write.op);
|
||||
struct bch_fs *c = op->write.op.c;
|
||||
struct promote_op *op = container_of(wop, struct promote_op, write.op);
|
||||
struct bch_fs *c = op->write.rbio.c;
|
||||
|
||||
bch2_time_stats_update(&c->times[BCH_TIME_data_promote],
|
||||
op->start_time);
|
||||
promote_free(c, op);
|
||||
bch2_time_stats_update(&c->times[BCH_TIME_data_promote], op->start_time);
|
||||
promote_free(&op->write.rbio);
|
||||
}
|
||||
|
||||
static void promote_start(struct promote_op *op, struct bch_read_bio *rbio)
|
||||
static noinline void promote_start(struct bch_read_bio *rbio)
|
||||
{
|
||||
struct bio *bio = &op->write.op.wbio.bio;
|
||||
struct promote_op *op = container_of(rbio, struct promote_op, write.rbio);
|
||||
|
||||
trace_and_count(op->write.op.c, read_promote, &rbio->bio);
|
||||
|
||||
/* we now own pages: */
|
||||
BUG_ON(!rbio->bounce);
|
||||
BUG_ON(rbio->bio.bi_vcnt > bio->bi_max_vecs);
|
||||
|
||||
memcpy(bio->bi_io_vec, rbio->bio.bi_io_vec,
|
||||
sizeof(struct bio_vec) * rbio->bio.bi_vcnt);
|
||||
swap(bio->bi_vcnt, rbio->bio.bi_vcnt);
|
||||
|
||||
bch2_data_update_read_done(&op->write, rbio->pick.crc);
|
||||
bch2_data_update_read_done(&op->write);
|
||||
}
|
||||
|
||||
static struct bch_read_bio *__promote_alloc(struct btree_trans *trans,
|
||||
|
|
@ -176,15 +168,12 @@ static struct bch_read_bio *__promote_alloc(struct btree_trans *trans,
|
|||
struct bch_io_failures *failed)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct promote_op *op = NULL;
|
||||
struct bio *bio;
|
||||
unsigned pages = DIV_ROUND_UP(sectors, PAGE_SECTORS);
|
||||
int ret;
|
||||
|
||||
if (!bch2_write_ref_tryget(c, BCH_WRITE_REF_promote))
|
||||
return ERR_PTR(-BCH_ERR_nopromote_no_writes);
|
||||
|
||||
op = kzalloc(struct_size(op, bi_inline_vecs, pages), GFP_KERNEL);
|
||||
struct promote_op *op = kzalloc(sizeof(*op), GFP_KERNEL);
|
||||
if (!op) {
|
||||
ret = -BCH_ERR_nopromote_enomem;
|
||||
goto err_put;
|
||||
|
|
@ -193,29 +182,12 @@ static struct bch_read_bio *__promote_alloc(struct btree_trans *trans,
|
|||
op->start_time = local_clock();
|
||||
op->pos = pos;
|
||||
|
||||
rbio_init_fragment(&op->write.rbio.bio, orig);
|
||||
bio_init(&op->write.rbio.bio,
|
||||
NULL,
|
||||
op->write.bi_inline_vecs,
|
||||
pages, 0);
|
||||
|
||||
if (bch2_bio_alloc_pages(&op->write.rbio.bio, sectors << 9, GFP_KERNEL)) {
|
||||
ret = -BCH_ERR_nopromote_enomem;
|
||||
goto err;
|
||||
}
|
||||
|
||||
op->write.rbio.bounce = true;
|
||||
op->write.rbio.promote = true;
|
||||
|
||||
if (rhashtable_lookup_insert_fast(&c->promote_table, &op->hash,
|
||||
bch_promote_params)) {
|
||||
ret = -BCH_ERR_nopromote_in_flight;
|
||||
goto err;
|
||||
}
|
||||
|
||||
bio = &op->write.op.wbio.bio;
|
||||
bio_init(bio, NULL, bio->bi_inline_vecs, pages, 0);
|
||||
|
||||
struct data_update_opts update_opts = {};
|
||||
|
||||
if (!have_io_error(failed)) {
|
||||
|
|
@ -243,16 +215,20 @@ static struct bch_read_bio *__promote_alloc(struct btree_trans *trans,
|
|||
* possible errors: -BCH_ERR_nocow_lock_blocked,
|
||||
* -BCH_ERR_ENOSPC_disk_reservation:
|
||||
*/
|
||||
if (ret) {
|
||||
BUG_ON(rhashtable_remove_fast(&c->promote_table, &op->hash,
|
||||
bch_promote_params));
|
||||
goto err;
|
||||
}
|
||||
if (ret)
|
||||
goto err_remove_hash;
|
||||
|
||||
rbio_init_fragment(&op->write.rbio.bio, orig);
|
||||
op->write.rbio.bounce = true;
|
||||
op->write.rbio.promote = true;
|
||||
op->write.op.end_io = promote_done;
|
||||
|
||||
return &op->write.rbio;
|
||||
err_remove_hash:
|
||||
BUG_ON(rhashtable_remove_fast(&c->promote_table, &op->hash,
|
||||
bch_promote_params));
|
||||
err:
|
||||
bio_free_pages(&op->write.rbio.bio);
|
||||
bio_free_pages(&op->write.op.wbio.bio);
|
||||
/* We may have added to the rhashtable and thus need rcu freeing: */
|
||||
kfree_rcu(op, rcu);
|
||||
err_put:
|
||||
|
|
@ -363,15 +339,11 @@ static inline struct bch_read_bio *bch2_rbio_free(struct bch_read_bio *rbio)
|
|||
if (rbio->split) {
|
||||
struct bch_read_bio *parent = rbio->parent;
|
||||
|
||||
if (rbio->promote) {
|
||||
struct promote_op *op = container_of(rbio, struct promote_op, write.rbio);
|
||||
|
||||
if (!rbio->bio.bi_status) {
|
||||
promote_start(op, rbio);
|
||||
} else {
|
||||
bch2_bio_free_pages_pool(rbio->c, &rbio->bio);
|
||||
promote_free(rbio->c, op);
|
||||
}
|
||||
if (unlikely(rbio->promote)) {
|
||||
if (!rbio->bio.bi_status)
|
||||
promote_start(rbio);
|
||||
else
|
||||
promote_free(rbio);
|
||||
} else {
|
||||
if (rbio->bounce)
|
||||
bch2_bio_free_pages_pool(rbio->c, &rbio->bio);
|
||||
|
|
@ -938,11 +910,13 @@ int __bch2_read_extent(struct btree_trans *trans, struct bch_read_bio *orig,
|
|||
}
|
||||
|
||||
if (flags & BCH_READ_data_update) {
|
||||
struct data_update *u = container_of(orig, struct data_update, rbio);
|
||||
|
||||
/*
|
||||
* can happen if we retry, and the extent we were going to read
|
||||
* has been merged in the meantime:
|
||||
*/
|
||||
if (pick.crc.compressed_size > orig->bio.bi_vcnt * PAGE_SECTORS) {
|
||||
if (pick.crc.compressed_size > u->op.wbio.bio.bi_iter.bi_size) {
|
||||
if (ca)
|
||||
percpu_ref_put(&ca->io_ref);
|
||||
goto hole;
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ static void move_write(struct moving_io *io)
|
|||
atomic_add(io->write_sectors, &io->write.ctxt->write_sectors);
|
||||
atomic_inc(&io->write.ctxt->write_ios);
|
||||
|
||||
bch2_data_update_read_done(&io->write, io->write.rbio.pick.crc);
|
||||
bch2_data_update_read_done(&io->write);
|
||||
}
|
||||
|
||||
struct moving_io *bch2_moving_ctxt_next_pending_write(struct moving_context *ctxt)
|
||||
|
|
@ -253,11 +253,6 @@ int bch2_move_extent(struct moving_context *ctxt,
|
|||
{
|
||||
struct btree_trans *trans = ctxt->trans;
|
||||
struct bch_fs *c = trans->c;
|
||||
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
|
||||
struct moving_io *io;
|
||||
const union bch_extent_entry *entry;
|
||||
struct extent_ptr_decoded p;
|
||||
unsigned sectors = k.k->size, pages;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
trace_move_extent2(c, k, &io_opts, &data_opts);
|
||||
|
|
@ -280,13 +275,7 @@ int bch2_move_extent(struct moving_context *ctxt,
|
|||
*/
|
||||
bch2_trans_unlock(trans);
|
||||
|
||||
/* write path might have to decompress data: */
|
||||
bkey_for_each_ptr_decode(k.k, ptrs, p, entry)
|
||||
sectors = max_t(unsigned, sectors, p.crc.uncompressed_size);
|
||||
|
||||
pages = DIV_ROUND_UP(sectors, PAGE_SECTORS);
|
||||
io = kzalloc(sizeof(struct moving_io) +
|
||||
sizeof(struct bio_vec) * pages, GFP_KERNEL);
|
||||
struct moving_io *io = kzalloc(sizeof(struct moving_io), GFP_KERNEL);
|
||||
if (!io)
|
||||
goto err;
|
||||
|
||||
|
|
@ -295,31 +284,13 @@ int bch2_move_extent(struct moving_context *ctxt,
|
|||
io->read_sectors = k.k->size;
|
||||
io->write_sectors = k.k->size;
|
||||
|
||||
bio_init(&io->write.op.wbio.bio, NULL, io->write.bi_inline_vecs, pages, 0);
|
||||
io->write.op.wbio.bio.bi_ioprio =
|
||||
IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0);
|
||||
|
||||
if (bch2_bio_alloc_pages(&io->write.op.wbio.bio, sectors << 9,
|
||||
GFP_KERNEL))
|
||||
goto err_free;
|
||||
|
||||
bio_init(&io->write.rbio.bio, NULL, io->write.bi_inline_vecs, pages, 0);
|
||||
io->write.rbio.bio.bi_vcnt = pages;
|
||||
io->write.rbio.bio.bi_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0);
|
||||
io->write.rbio.bio.bi_iter.bi_size = sectors << 9;
|
||||
|
||||
io->write.rbio.bio.bi_opf = REQ_OP_READ;
|
||||
io->write.rbio.bio.bi_iter.bi_sector = bkey_start_offset(k.k);
|
||||
|
||||
rbio_init(&io->write.rbio.bio,
|
||||
c,
|
||||
io_opts,
|
||||
move_read_endio);
|
||||
|
||||
ret = bch2_data_update_init(trans, iter, ctxt, &io->write, ctxt->wp,
|
||||
io_opts, data_opts, iter->btree_id, k);
|
||||
if (ret)
|
||||
goto err_free_pages;
|
||||
goto err_free;
|
||||
|
||||
io->write.rbio.bio.bi_end_io = move_read_endio;
|
||||
io->write.rbio.bio.bi_ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0);
|
||||
|
||||
io->write.op.end_io = move_write_done;
|
||||
|
||||
|
|
@ -359,8 +330,6 @@ int bch2_move_extent(struct moving_context *ctxt,
|
|||
BCH_READ_data_update|
|
||||
BCH_READ_last_fragment);
|
||||
return 0;
|
||||
err_free_pages:
|
||||
bio_free_pages(&io->write.op.wbio.bio);
|
||||
err_free:
|
||||
kfree(io);
|
||||
err:
|
||||
|
|
@ -624,7 +593,7 @@ static int bch2_move_data_btree(struct moving_context *ctxt,
|
|||
if (bch2_err_matches(ret2, BCH_ERR_transaction_restart))
|
||||
continue;
|
||||
|
||||
if (ret2 == -ENOMEM) {
|
||||
if (bch2_err_matches(ret2, ENOMEM)) {
|
||||
/* memory allocation failure, wait for some IO to finish */
|
||||
bch2_move_ctxt_wait_for_io(ctxt);
|
||||
continue;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user