mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
bcachefs: Move nocow unlock to bch2_write_endio()
This fixes a lifetime issue; bch2_nocow_write_unlock() uses PTR_BUCKET_POS(), which needs the device - but we drop our ref to the device in bch2_write_endio(). Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
b6d29b5869
commit
6202569777
@ -434,6 +434,8 @@ void bch2_submit_wbio_replicas(struct bch_write_bio *wbio, struct bch_fs *c,
|
|||||||
n->nocow = nocow;
|
n->nocow = nocow;
|
||||||
n->submit_time = local_clock();
|
n->submit_time = local_clock();
|
||||||
n->inode_offset = bkey_start_offset(&k->k);
|
n->inode_offset = bkey_start_offset(&k->k);
|
||||||
|
if (nocow)
|
||||||
|
n->nocow_bucket = PTR_BUCKET_NR(ca, ptr);
|
||||||
n->bio.bi_iter.bi_sector = ptr->offset;
|
n->bio.bi_iter.bi_sector = ptr->offset;
|
||||||
|
|
||||||
if (likely(n->have_ioref)) {
|
if (likely(n->have_ioref)) {
|
||||||
@ -659,8 +661,12 @@ static void bch2_write_endio(struct bio *bio)
|
|||||||
op->flags |= BCH_WRITE_IO_ERROR;
|
op->flags |= BCH_WRITE_IO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wbio->nocow)
|
if (wbio->nocow) {
|
||||||
|
bch2_bucket_nocow_unlock(&c->nocow_locks,
|
||||||
|
POS(ca->dev_idx, wbio->nocow_bucket),
|
||||||
|
BUCKET_NOCOW_LOCK_UPDATE);
|
||||||
set_bit(wbio->dev, op->devs_need_flush->d);
|
set_bit(wbio->dev, op->devs_need_flush->d);
|
||||||
|
}
|
||||||
|
|
||||||
if (wbio->have_ioref) {
|
if (wbio->have_ioref) {
|
||||||
bch2_latency_acct(ca, wbio->submit_time, WRITE);
|
bch2_latency_acct(ca, wbio->submit_time, WRITE);
|
||||||
@ -1114,22 +1120,6 @@ static bool bch2_extent_is_writeable(struct bch_write_op *op,
|
|||||||
return replicas >= op->opts.data_replicas;
|
return replicas >= op->opts.data_replicas;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void bch2_nocow_write_unlock(struct bch_write_op *op)
|
|
||||||
{
|
|
||||||
struct bch_fs *c = op->c;
|
|
||||||
|
|
||||||
for_each_keylist_key(&op->insert_keys, k) {
|
|
||||||
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(bkey_i_to_s_c(k));
|
|
||||||
|
|
||||||
bkey_for_each_ptr(ptrs, ptr) {
|
|
||||||
struct bch_dev *ca = bch2_dev_bkey_exists(c, ptr->dev);
|
|
||||||
bch2_bucket_nocow_unlock(&c->nocow_locks,
|
|
||||||
PTR_BUCKET_POS(ca, ptr),
|
|
||||||
BUCKET_NOCOW_LOCK_UPDATE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int bch2_nocow_write_convert_one_unwritten(struct btree_trans *trans,
|
static int bch2_nocow_write_convert_one_unwritten(struct btree_trans *trans,
|
||||||
struct btree_iter *iter,
|
struct btree_iter *iter,
|
||||||
struct bkey_i *orig,
|
struct bkey_i *orig,
|
||||||
@ -1200,8 +1190,6 @@ static void bch2_nocow_write_convert_unwritten(struct bch_write_op *op)
|
|||||||
|
|
||||||
static void __bch2_nocow_write_done(struct bch_write_op *op)
|
static void __bch2_nocow_write_done(struct bch_write_op *op)
|
||||||
{
|
{
|
||||||
bch2_nocow_write_unlock(op);
|
|
||||||
|
|
||||||
if (unlikely(op->flags & BCH_WRITE_IO_ERROR)) {
|
if (unlikely(op->flags & BCH_WRITE_IO_ERROR)) {
|
||||||
op->error = -EIO;
|
op->error = -EIO;
|
||||||
} else if (unlikely(op->flags & BCH_WRITE_CONVERT_UNWRITTEN))
|
} else if (unlikely(op->flags & BCH_WRITE_CONVERT_UNWRITTEN))
|
||||||
|
@ -20,6 +20,7 @@ struct bch_write_bio {
|
|||||||
|
|
||||||
u64 submit_time;
|
u64 submit_time;
|
||||||
u64 inode_offset;
|
u64 inode_offset;
|
||||||
|
u64 nocow_bucket;
|
||||||
|
|
||||||
struct bch_devs_list failed;
|
struct bch_devs_list failed;
|
||||||
u8 dev;
|
u8 dev;
|
||||||
|
Loading…
Reference in New Issue
Block a user