mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
bcachefs: Split extents if necessary in bch2_trans_update()
Currently, we handle multiple overlapping extents in the same transaction commit by doing fixups in bch2_trans_update() - this patch extents that to split updates when necessary. The next patch that changes the reflink code to not fragment extents when making them indirect will require this. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
This commit is contained in:
parent
ef1b20924b
commit
d6462f494d
@ -1099,9 +1099,30 @@ int bch2_trans_update(struct btree_trans *trans, struct btree_iter *iter,
|
||||
if (i < trans->updates + trans->nr_updates &&
|
||||
i->btree_id == n.btree_id &&
|
||||
bkey_cmp(n.k->k.p, bkey_start_pos(&i->k->k)) > 0) {
|
||||
/* We don't handle splitting extents here: */
|
||||
BUG_ON(bkey_cmp(bkey_start_pos(&n.k->k),
|
||||
bkey_start_pos(&i->k->k)) > 0);
|
||||
if (bkey_cmp(bkey_start_pos(&n.k->k),
|
||||
bkey_start_pos(&i->k->k)) > 0) {
|
||||
struct btree_insert_entry split = *i;
|
||||
int ret;
|
||||
|
||||
BUG_ON(trans->nr_updates + 1 >= BTREE_ITER_MAX);
|
||||
|
||||
split.k = bch2_trans_kmalloc(trans, bkey_bytes(&i->k->k));
|
||||
ret = PTR_ERR_OR_ZERO(split.k);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
bkey_copy(split.k, i->k);
|
||||
bch2_cut_back(bkey_start_pos(&n.k->k), split.k);
|
||||
|
||||
split.iter = bch2_trans_get_iter(trans, split.btree_id,
|
||||
bkey_start_pos(&split.k->k),
|
||||
BTREE_ITER_INTENT);
|
||||
split.iter->flags |= BTREE_ITER_KEEP_UNTIL_COMMIT;
|
||||
bch2_trans_iter_put(trans, split.iter);
|
||||
array_insert_item(trans->updates, trans->nr_updates,
|
||||
i - trans->updates, split);
|
||||
i++;
|
||||
}
|
||||
|
||||
/*
|
||||
* When we have an extent that overwrites the start of another
|
||||
|
@ -342,9 +342,8 @@ int bch2_extent_update(struct btree_trans *trans,
|
||||
bch2_trans_iter_put(trans, inode_iter);
|
||||
}
|
||||
|
||||
bch2_trans_update(trans, iter, k, 0);
|
||||
|
||||
ret = bch2_trans_commit(trans, disk_res, journal_seq,
|
||||
ret = bch2_trans_update(trans, iter, k, 0) ?:
|
||||
bch2_trans_commit(trans, disk_res, journal_seq,
|
||||
BTREE_INSERT_NOCHECK_RW|
|
||||
BTREE_INSERT_NOFAIL);
|
||||
if (ret)
|
||||
|
@ -155,7 +155,9 @@ static int bch2_make_extent_indirect(struct btree_trans *trans,
|
||||
*refcount = 0;
|
||||
memcpy(refcount + 1, &orig->v, bkey_val_bytes(&orig->k));
|
||||
|
||||
bch2_trans_update(trans, reflink_iter, r_v, 0);
|
||||
ret = bch2_trans_update(trans, reflink_iter, r_v, 0);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
r_p = bch2_trans_kmalloc(trans, sizeof(*r_p));
|
||||
if (IS_ERR(r_p)) {
|
||||
@ -168,7 +170,7 @@ static int bch2_make_extent_indirect(struct btree_trans *trans,
|
||||
set_bkey_val_bytes(&r_p->k, sizeof(r_p->v));
|
||||
r_p->v.idx = cpu_to_le64(bkey_start_offset(&r_v->k));
|
||||
|
||||
bch2_trans_update(trans, extent_iter, &r_p->k_i, 0);
|
||||
ret = bch2_trans_update(trans, extent_iter, &r_p->k_i, 0);
|
||||
err:
|
||||
if (!IS_ERR(reflink_iter))
|
||||
c->reflink_hint = reflink_iter->pos.offset;
|
||||
|
Loading…
Reference in New Issue
Block a user