mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-15 08:14:15 +08:00
bcachefs: bch2_btree_node_rewrite() now returns transaction restarts
We have been getting away from handling transaction restarts locally - convert bch2_btree_node_rewrite() to the newer style. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
This commit is contained in:
parent
979735df98
commit
f3cf0999ac
@ -817,15 +817,13 @@ static int bch2_gc_btree(struct bch_fs *c, enum btree_id btree_id,
|
|||||||
|
|
||||||
if (!initial) {
|
if (!initial) {
|
||||||
if (max_stale > 64)
|
if (max_stale > 64)
|
||||||
bch2_btree_node_rewrite(&trans, &iter,
|
bch2_btree_node_rewrite(&trans, &iter, b,
|
||||||
b->data->keys.seq,
|
|
||||||
BTREE_INSERT_NOWAIT|
|
BTREE_INSERT_NOWAIT|
|
||||||
BTREE_INSERT_GC_LOCK_HELD);
|
BTREE_INSERT_GC_LOCK_HELD);
|
||||||
else if (!bch2_btree_gc_rewrite_disabled &&
|
else if (!bch2_btree_gc_rewrite_disabled &&
|
||||||
(bch2_btree_gc_always_rewrite || max_stale > 16))
|
(bch2_btree_gc_always_rewrite || max_stale > 16))
|
||||||
bch2_btree_node_rewrite(&trans, &iter,
|
bch2_btree_node_rewrite(&trans, &iter,
|
||||||
b->data->keys.seq,
|
b, BTREE_INSERT_NOWAIT|
|
||||||
BTREE_INSERT_NOWAIT|
|
|
||||||
BTREE_INSERT_GC_LOCK_HELD);
|
BTREE_INSERT_GC_LOCK_HELD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ int bch2_btree_delete_range(struct bch_fs *, enum btree_id,
|
|||||||
struct bpos, struct bpos, u64 *);
|
struct bpos, struct bpos, u64 *);
|
||||||
|
|
||||||
int bch2_btree_node_rewrite(struct btree_trans *, struct btree_iter *,
|
int bch2_btree_node_rewrite(struct btree_trans *, struct btree_iter *,
|
||||||
__le64, unsigned);
|
struct btree *, unsigned);
|
||||||
void bch2_btree_node_rewrite_async(struct bch_fs *, struct btree *);
|
void bch2_btree_node_rewrite_async(struct bch_fs *, struct btree *);
|
||||||
int bch2_btree_node_update_key(struct btree_trans *, struct btree_iter *,
|
int bch2_btree_node_update_key(struct btree_trans *, struct btree_iter *,
|
||||||
struct btree *, struct bkey_i *, bool);
|
struct btree *, struct bkey_i *, bool);
|
||||||
|
@ -1722,26 +1722,15 @@ err:
|
|||||||
*/
|
*/
|
||||||
int bch2_btree_node_rewrite(struct btree_trans *trans,
|
int bch2_btree_node_rewrite(struct btree_trans *trans,
|
||||||
struct btree_iter *iter,
|
struct btree_iter *iter,
|
||||||
__le64 seq, unsigned flags)
|
struct btree *b,
|
||||||
|
unsigned flags)
|
||||||
{
|
{
|
||||||
struct bch_fs *c = trans->c;
|
struct bch_fs *c = trans->c;
|
||||||
struct btree *b, *n, *parent;
|
struct btree *n, *parent;
|
||||||
struct btree_update *as;
|
struct btree_update *as;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
flags |= BTREE_INSERT_NOFAIL;
|
flags |= BTREE_INSERT_NOFAIL;
|
||||||
retry:
|
|
||||||
ret = bch2_btree_iter_traverse(iter);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
b = bch2_btree_iter_peek_node(iter);
|
|
||||||
ret = PTR_ERR_OR_ZERO(b);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (!b || b->data->keys.seq != seq)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
parent = btree_node_parent(iter->path, b);
|
parent = btree_node_parent(iter->path, b);
|
||||||
as = bch2_btree_update_start(trans, iter->path, b->c.level,
|
as = bch2_btree_update_start(trans, iter->path, b->c.level,
|
||||||
@ -1750,8 +1739,6 @@ retry:
|
|||||||
: 0) + 1,
|
: 0) + 1,
|
||||||
flags);
|
flags);
|
||||||
ret = PTR_ERR_OR_ZERO(as);
|
ret = PTR_ERR_OR_ZERO(as);
|
||||||
if (ret == -EINTR)
|
|
||||||
goto retry;
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
trace_btree_gc_rewrite_node_fail(c, b);
|
trace_btree_gc_rewrite_node_fail(c, b);
|
||||||
goto out;
|
goto out;
|
||||||
@ -1799,20 +1786,38 @@ struct async_btree_rewrite {
|
|||||||
__le64 seq;
|
__le64 seq;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int async_btree_node_rewrite_trans(struct btree_trans *trans,
|
||||||
|
struct async_btree_rewrite *a)
|
||||||
|
{
|
||||||
|
struct btree_iter iter;
|
||||||
|
struct btree *b;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
bch2_trans_node_iter_init(trans, &iter, a->btree_id, a->pos,
|
||||||
|
BTREE_MAX_DEPTH, a->level, 0);
|
||||||
|
b = bch2_btree_iter_peek_node(&iter);
|
||||||
|
ret = PTR_ERR_OR_ZERO(b);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (!b || b->data->keys.seq != a->seq)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ret = bch2_btree_node_rewrite(trans, &iter, b, 0);
|
||||||
|
out :
|
||||||
|
bch2_trans_iter_exit(trans, &iter);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void async_btree_node_rewrite_work(struct work_struct *work)
|
void async_btree_node_rewrite_work(struct work_struct *work)
|
||||||
{
|
{
|
||||||
struct async_btree_rewrite *a =
|
struct async_btree_rewrite *a =
|
||||||
container_of(work, struct async_btree_rewrite, work);
|
container_of(work, struct async_btree_rewrite, work);
|
||||||
struct bch_fs *c = a->c;
|
struct bch_fs *c = a->c;
|
||||||
struct btree_trans trans;
|
|
||||||
struct btree_iter iter;
|
|
||||||
|
|
||||||
bch2_trans_init(&trans, c, 0, 0);
|
bch2_trans_do(c, NULL, NULL, 0,
|
||||||
bch2_trans_node_iter_init(&trans, &iter, a->btree_id, a->pos,
|
async_btree_node_rewrite_trans(&trans, a));
|
||||||
BTREE_MAX_DEPTH, a->level, 0);
|
|
||||||
bch2_btree_node_rewrite(&trans, &iter, a->seq, 0);
|
|
||||||
bch2_trans_iter_exit(&trans, &iter);
|
|
||||||
bch2_trans_exit(&trans);
|
|
||||||
percpu_ref_put(&c->writes);
|
percpu_ref_put(&c->writes);
|
||||||
kfree(a);
|
kfree(a);
|
||||||
}
|
}
|
||||||
|
@ -910,8 +910,11 @@ retry:
|
|||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = bch2_btree_node_rewrite(&trans, &iter,
|
ret = bch2_btree_node_rewrite(&trans, &iter, b, 0) ?: ret;
|
||||||
b->data->keys.seq, 0) ?: ret;
|
if (ret == -EINTR)
|
||||||
|
continue;
|
||||||
|
if (ret)
|
||||||
|
break;
|
||||||
next:
|
next:
|
||||||
bch2_btree_iter_next_node(&iter);
|
bch2_btree_iter_next_node(&iter);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user