mirror of
https://github.com/torvalds/linux.git
synced 2024-11-16 00:52:01 +00:00
bcachefs: Convert bch2_mark_key() to take a btree_trans *
This helps to unify the interface between bch2_mark_key() and bch2_trans_mark_key() - and it also gives access to the journal reservation and journal seq in the mark_key path. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
This commit is contained in:
parent
961b2d6282
commit
904823de49
@ -261,8 +261,9 @@ void bch2_alloc_to_text(struct printbuf *out, struct bch_fs *c,
|
||||
#undef x
|
||||
}
|
||||
|
||||
static int bch2_alloc_read_fn(struct bch_fs *c, struct bkey_s_c k)
|
||||
static int bch2_alloc_read_fn(struct btree_trans *trans, struct bkey_s_c k)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct bch_dev *ca;
|
||||
struct bucket *g;
|
||||
struct bkey_alloc_unpacked u;
|
||||
@ -289,11 +290,14 @@ static int bch2_alloc_read_fn(struct bch_fs *c, struct bkey_s_c k)
|
||||
|
||||
int bch2_alloc_read(struct bch_fs *c)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
down_read(&c->gc_lock);
|
||||
ret = bch2_btree_and_journal_walk(c, BTREE_ID_alloc, bch2_alloc_read_fn);
|
||||
ret = bch2_btree_and_journal_walk(&trans, BTREE_ID_alloc, bch2_alloc_read_fn);
|
||||
up_read(&c->gc_lock);
|
||||
bch2_trans_exit(&trans);
|
||||
if (ret) {
|
||||
bch_err(c, "error reading alloc info: %i", ret);
|
||||
return ret;
|
||||
|
@ -688,11 +688,12 @@ fsck_err:
|
||||
|
||||
/* marking of btree keys/nodes: */
|
||||
|
||||
static int bch2_gc_mark_key(struct bch_fs *c, enum btree_id btree_id,
|
||||
static int bch2_gc_mark_key(struct btree_trans *trans, enum btree_id btree_id,
|
||||
unsigned level, bool is_root,
|
||||
struct bkey_s_c *k,
|
||||
u8 *max_stale, bool initial)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct bkey_ptrs_c ptrs;
|
||||
const struct bch_extent_ptr *ptr;
|
||||
unsigned flags =
|
||||
@ -740,7 +741,7 @@ static int bch2_gc_mark_key(struct bch_fs *c, enum btree_id btree_id,
|
||||
*max_stale = max(*max_stale, ptr_stale(ca, ptr));
|
||||
}
|
||||
|
||||
ret = bch2_mark_key(c, *k, flags);
|
||||
ret = bch2_mark_key(trans, *k, flags);
|
||||
fsck_err:
|
||||
err:
|
||||
if (ret)
|
||||
@ -748,9 +749,10 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int btree_gc_mark_node(struct bch_fs *c, struct btree *b, u8 *max_stale,
|
||||
static int btree_gc_mark_node(struct btree_trans *trans, struct btree *b, u8 *max_stale,
|
||||
bool initial)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct btree_node_iter iter;
|
||||
struct bkey unpacked;
|
||||
struct bkey_s_c k;
|
||||
@ -768,7 +770,7 @@ static int btree_gc_mark_node(struct bch_fs *c, struct btree *b, u8 *max_stale,
|
||||
bkey_init(&prev.k->k);
|
||||
|
||||
while ((k = bch2_btree_node_iter_peek_unpack(&iter, b, &unpacked)).k) {
|
||||
ret = bch2_gc_mark_key(c, b->c.btree_id, b->c.level, false,
|
||||
ret = bch2_gc_mark_key(trans, b->c.btree_id, b->c.level, false,
|
||||
&k, max_stale, initial);
|
||||
if (ret)
|
||||
break;
|
||||
@ -790,10 +792,10 @@ static int btree_gc_mark_node(struct bch_fs *c, struct btree *b, u8 *max_stale,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bch2_gc_btree(struct bch_fs *c, enum btree_id btree_id,
|
||||
static int bch2_gc_btree(struct btree_trans *trans, enum btree_id btree_id,
|
||||
bool initial, bool metadata_only)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
struct bch_fs *c = trans->c;
|
||||
struct btree_iter iter;
|
||||
struct btree *b;
|
||||
unsigned depth = metadata_only ? 1
|
||||
@ -803,35 +805,32 @@ static int bch2_gc_btree(struct bch_fs *c, enum btree_id btree_id,
|
||||
u8 max_stale = 0;
|
||||
int ret = 0;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
gc_pos_set(c, gc_pos_btree(btree_id, POS_MIN, 0));
|
||||
|
||||
__for_each_btree_node(&trans, iter, btree_id, POS_MIN,
|
||||
__for_each_btree_node(trans, iter, btree_id, POS_MIN,
|
||||
0, depth, BTREE_ITER_PREFETCH, b, ret) {
|
||||
bch2_verify_btree_nr_keys(b);
|
||||
|
||||
gc_pos_set(c, gc_pos_btree_node(b));
|
||||
|
||||
ret = btree_gc_mark_node(c, b, &max_stale, initial);
|
||||
ret = btree_gc_mark_node(trans, b, &max_stale, initial);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
if (!initial) {
|
||||
if (max_stale > 64)
|
||||
bch2_btree_node_rewrite(&trans, &iter, b,
|
||||
bch2_btree_node_rewrite(trans, &iter, b,
|
||||
BTREE_INSERT_NOWAIT|
|
||||
BTREE_INSERT_GC_LOCK_HELD);
|
||||
else if (!bch2_btree_gc_rewrite_disabled &&
|
||||
(bch2_btree_gc_always_rewrite || max_stale > 16))
|
||||
bch2_btree_node_rewrite(&trans, &iter,
|
||||
bch2_btree_node_rewrite(trans, &iter,
|
||||
b, BTREE_INSERT_NOWAIT|
|
||||
BTREE_INSERT_GC_LOCK_HELD);
|
||||
}
|
||||
}
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_iter_exit(trans, &iter);
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -840,7 +839,7 @@ static int bch2_gc_btree(struct bch_fs *c, enum btree_id btree_id,
|
||||
if (!btree_node_fake(b)) {
|
||||
struct bkey_s_c k = bkey_i_to_s_c(&b->key);
|
||||
|
||||
ret = bch2_gc_mark_key(c, b->c.btree_id, b->c.level, true,
|
||||
ret = bch2_gc_mark_key(trans, b->c.btree_id, b->c.level, true,
|
||||
&k, &max_stale, initial);
|
||||
}
|
||||
gc_pos_set(c, gc_pos_btree_root(b->c.btree_id));
|
||||
@ -849,9 +848,10 @@ static int bch2_gc_btree(struct bch_fs *c, enum btree_id btree_id,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bch2_gc_btree_init_recurse(struct bch_fs *c, struct btree *b,
|
||||
static int bch2_gc_btree_init_recurse(struct btree_trans *trans, struct btree *b,
|
||||
unsigned target_depth)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct btree_and_journal_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct bkey_buf cur, prev;
|
||||
@ -868,7 +868,7 @@ static int bch2_gc_btree_init_recurse(struct bch_fs *c, struct btree *b,
|
||||
BUG_ON(bpos_cmp(k.k->p, b->data->min_key) < 0);
|
||||
BUG_ON(bpos_cmp(k.k->p, b->data->max_key) > 0);
|
||||
|
||||
ret = bch2_gc_mark_key(c, b->c.btree_id, b->c.level, false,
|
||||
ret = bch2_gc_mark_key(trans, b->c.btree_id, b->c.level, false,
|
||||
&k, &max_stale, true);
|
||||
if (ret) {
|
||||
bch_err(c, "%s: error %i from bch2_gc_mark_key", __func__, ret);
|
||||
@ -935,7 +935,7 @@ static int bch2_gc_btree_init_recurse(struct bch_fs *c, struct btree *b,
|
||||
break;
|
||||
}
|
||||
|
||||
ret = bch2_gc_btree_init_recurse(c, child,
|
||||
ret = bch2_gc_btree_init_recurse(trans, child,
|
||||
target_depth);
|
||||
six_unlock_read(&child->c.lock);
|
||||
|
||||
@ -950,10 +950,11 @@ fsck_err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bch2_gc_btree_init(struct bch_fs *c,
|
||||
static int bch2_gc_btree_init(struct btree_trans *trans,
|
||||
enum btree_id btree_id,
|
||||
bool metadata_only)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct btree *b;
|
||||
unsigned target_depth = metadata_only ? 1
|
||||
: bch2_expensive_debug_checks ? 0
|
||||
@ -986,12 +987,12 @@ static int bch2_gc_btree_init(struct bch_fs *c,
|
||||
}
|
||||
|
||||
if (b->c.level >= target_depth)
|
||||
ret = bch2_gc_btree_init_recurse(c, b, target_depth);
|
||||
ret = bch2_gc_btree_init_recurse(trans, b, target_depth);
|
||||
|
||||
if (!ret) {
|
||||
struct bkey_s_c k = bkey_i_to_s_c(&b->key);
|
||||
|
||||
ret = bch2_gc_mark_key(c, b->c.btree_id, b->c.level, true,
|
||||
ret = bch2_gc_mark_key(trans, b->c.btree_id, b->c.level, true,
|
||||
&k, &max_stale, true);
|
||||
}
|
||||
fsck_err:
|
||||
@ -1010,21 +1011,26 @@ static inline int btree_id_gc_phase_cmp(enum btree_id l, enum btree_id r)
|
||||
|
||||
static int bch2_gc_btrees(struct bch_fs *c, bool initial, bool metadata_only)
|
||||
{
|
||||
struct btree_trans trans;
|
||||
enum btree_id ids[BTREE_ID_NR];
|
||||
unsigned i;
|
||||
int ret = 0;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
for (i = 0; i < BTREE_ID_NR; i++)
|
||||
ids[i] = i;
|
||||
bubble_sort(ids, BTREE_ID_NR, btree_id_gc_phase_cmp);
|
||||
|
||||
for (i = 0; i < BTREE_ID_NR && !ret; i++)
|
||||
ret = initial
|
||||
? bch2_gc_btree_init(c, ids[i], metadata_only)
|
||||
: bch2_gc_btree(c, ids[i], initial, metadata_only);
|
||||
? bch2_gc_btree_init(&trans, ids[i], metadata_only)
|
||||
: bch2_gc_btree(&trans, ids[i], initial, metadata_only);
|
||||
|
||||
if (ret < 0)
|
||||
bch_err(c, "%s: ret %i", __func__, ret);
|
||||
|
||||
bch2_trans_exit(&trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1373,8 +1379,10 @@ static int bch2_gc_start(struct bch_fs *c,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bch2_gc_reflink_done_initial_fn(struct bch_fs *c, struct bkey_s_c k)
|
||||
static int bch2_gc_reflink_done_initial_fn(struct btree_trans *trans,
|
||||
struct bkey_s_c k)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct reflink_gc *r;
|
||||
const __le64 *refcount = bkey_refcount_c(k);
|
||||
char buf[200];
|
||||
@ -1439,16 +1447,16 @@ static int bch2_gc_reflink_done(struct bch_fs *c, bool initial,
|
||||
if (metadata_only)
|
||||
return 0;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
if (initial) {
|
||||
c->reflink_gc_idx = 0;
|
||||
|
||||
ret = bch2_btree_and_journal_walk(c, BTREE_ID_reflink,
|
||||
ret = bch2_btree_and_journal_walk(&trans, BTREE_ID_reflink,
|
||||
bch2_gc_reflink_done_initial_fn);
|
||||
goto out;
|
||||
}
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
|
||||
for_each_btree_key(&trans, iter, BTREE_ID_reflink, POS_MIN,
|
||||
BTREE_ITER_PREFETCH, k, ret) {
|
||||
const __le64 *refcount = bkey_refcount_c(k);
|
||||
@ -1496,16 +1504,18 @@ static int bch2_gc_reflink_done(struct bch_fs *c, bool initial,
|
||||
}
|
||||
fsck_err:
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
bch2_trans_exit(&trans);
|
||||
out:
|
||||
genradix_free(&c->reflink_gc_table);
|
||||
c->reflink_gc_nr = 0;
|
||||
bch2_trans_exit(&trans);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bch2_gc_reflink_start_initial_fn(struct bch_fs *c, struct bkey_s_c k)
|
||||
static int bch2_gc_reflink_start_initial_fn(struct btree_trans *trans,
|
||||
struct bkey_s_c k)
|
||||
{
|
||||
|
||||
struct bch_fs *c = trans->c;
|
||||
struct reflink_gc *r;
|
||||
const __le64 *refcount = bkey_refcount_c(k);
|
||||
|
||||
@ -1530,19 +1540,20 @@ static int bch2_gc_reflink_start(struct bch_fs *c, bool initial,
|
||||
struct btree_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct reflink_gc *r;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (metadata_only)
|
||||
return 0;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
genradix_free(&c->reflink_gc_table);
|
||||
c->reflink_gc_nr = 0;
|
||||
|
||||
if (initial)
|
||||
return bch2_btree_and_journal_walk(c, BTREE_ID_reflink,
|
||||
bch2_gc_reflink_start_initial_fn);
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
if (initial) {
|
||||
ret = bch2_btree_and_journal_walk(&trans, BTREE_ID_reflink,
|
||||
bch2_gc_reflink_start_initial_fn);
|
||||
goto out;
|
||||
}
|
||||
|
||||
for_each_btree_key(&trans, iter, BTREE_ID_reflink, POS_MIN,
|
||||
BTREE_ITER_PREFETCH, k, ret) {
|
||||
@ -1563,9 +1574,9 @@ static int bch2_gc_reflink_start(struct bch_fs *c, bool initial,
|
||||
r->refcount = 0;
|
||||
}
|
||||
bch2_trans_iter_exit(&trans, &iter);
|
||||
|
||||
out:
|
||||
bch2_trans_exit(&trans);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2693,6 +2693,7 @@ void bch2_trans_begin(struct btree_trans *trans)
|
||||
trans_for_each_update(trans, i)
|
||||
__btree_path_put(i->path, true);
|
||||
|
||||
memset(&trans->journal_res, 0, sizeof(trans->journal_res));
|
||||
trans->extra_journal_res = 0;
|
||||
trans->nr_updates = 0;
|
||||
trans->mem_top = 0;
|
||||
|
@ -528,11 +528,13 @@ void bch2_mark_alloc_bucket(struct bch_fs *c, struct bch_dev *ca,
|
||||
BUG_ON(owned_by_allocator == old.owned_by_allocator);
|
||||
}
|
||||
|
||||
static int bch2_mark_alloc(struct bch_fs *c,
|
||||
static int bch2_mark_alloc(struct btree_trans *trans,
|
||||
struct bkey_s_c old, struct bkey_s_c new,
|
||||
u64 journal_seq, unsigned flags)
|
||||
unsigned flags)
|
||||
{
|
||||
bool gc = flags & BTREE_TRIGGER_GC;
|
||||
u64 journal_seq = trans->journal_res.seq;
|
||||
struct bch_fs *c = trans->c;
|
||||
struct bkey_alloc_unpacked u;
|
||||
struct bch_dev *ca;
|
||||
struct bucket *g;
|
||||
@ -677,7 +679,8 @@ static s64 ptr_disk_sectors(s64 sectors, struct extent_ptr_decoded p)
|
||||
: sectors;
|
||||
}
|
||||
|
||||
static int check_bucket_ref(struct bch_fs *c, struct bkey_s_c k,
|
||||
static int check_bucket_ref(struct bch_fs *c,
|
||||
struct bkey_s_c k,
|
||||
const struct bch_extent_ptr *ptr,
|
||||
s64 sectors, enum bch_data_type ptr_data_type,
|
||||
u8 bucket_gen, u8 bucket_data_type,
|
||||
@ -751,10 +754,12 @@ static int check_bucket_ref(struct bch_fs *c, struct bkey_s_c k,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mark_stripe_bucket(struct bch_fs *c, struct bkey_s_c k,
|
||||
unsigned ptr_idx,
|
||||
u64 journal_seq, unsigned flags)
|
||||
static int mark_stripe_bucket(struct btree_trans *trans,
|
||||
struct bkey_s_c k,
|
||||
unsigned ptr_idx,
|
||||
u64 journal_seq, unsigned flags)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
const struct bch_stripe *s = bkey_s_c_to_stripe(k).v;
|
||||
unsigned nr_data = s->nr_blocks - s->nr_redundant;
|
||||
bool parity = ptr_idx >= nr_data;
|
||||
@ -798,7 +803,8 @@ static int mark_stripe_bucket(struct bch_fs *c, struct bkey_s_c k,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __mark_pointer(struct bch_fs *c, struct bkey_s_c k,
|
||||
static int __mark_pointer(struct btree_trans *trans,
|
||||
struct bkey_s_c k,
|
||||
const struct bch_extent_ptr *ptr,
|
||||
s64 sectors, enum bch_data_type ptr_data_type,
|
||||
u8 bucket_gen, u8 *bucket_data_type,
|
||||
@ -807,7 +813,7 @@ static int __mark_pointer(struct bch_fs *c, struct bkey_s_c k,
|
||||
u16 *dst_sectors = !ptr->cached
|
||||
? dirty_sectors
|
||||
: cached_sectors;
|
||||
int ret = check_bucket_ref(c, k, ptr, sectors, ptr_data_type,
|
||||
int ret = check_bucket_ref(trans->c, k, ptr, sectors, ptr_data_type,
|
||||
bucket_gen, *bucket_data_type,
|
||||
*dirty_sectors, *cached_sectors);
|
||||
|
||||
@ -820,12 +826,15 @@ static int __mark_pointer(struct bch_fs *c, struct bkey_s_c k,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bch2_mark_pointer(struct bch_fs *c, struct bkey_s_c k,
|
||||
static int bch2_mark_pointer(struct btree_trans *trans,
|
||||
struct bkey_s_c k,
|
||||
struct extent_ptr_decoded p,
|
||||
s64 sectors, enum bch_data_type data_type,
|
||||
u64 journal_seq, unsigned flags)
|
||||
unsigned flags)
|
||||
{
|
||||
bool gc = flags & BTREE_TRIGGER_GC;
|
||||
u64 journal_seq = trans->journal_res.seq;
|
||||
struct bch_fs *c = trans->c;
|
||||
struct bucket_mark old, new;
|
||||
struct bch_dev *ca = bch_dev_bkey_exists(c, p.ptr.dev);
|
||||
struct bucket *g = PTR_BUCKET(ca, &p.ptr, gc);
|
||||
@ -838,7 +847,8 @@ static int bch2_mark_pointer(struct bch_fs *c, struct bkey_s_c k,
|
||||
new.v.counter = old.v.counter = v;
|
||||
bucket_data_type = new.data_type;
|
||||
|
||||
ret = __mark_pointer(c, k, &p.ptr, sectors, data_type, new.gen,
|
||||
ret = __mark_pointer(trans, k, &p.ptr, sectors,
|
||||
data_type, new.gen,
|
||||
&bucket_data_type,
|
||||
&new.dirty_sectors,
|
||||
&new.cached_sectors);
|
||||
@ -867,13 +877,14 @@ static int bch2_mark_pointer(struct bch_fs *c, struct bkey_s_c k,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bch2_mark_stripe_ptr(struct bch_fs *c,
|
||||
static int bch2_mark_stripe_ptr(struct btree_trans *trans,
|
||||
struct bch_extent_stripe_ptr p,
|
||||
enum bch_data_type data_type,
|
||||
s64 sectors,
|
||||
unsigned journal_seq, unsigned flags)
|
||||
unsigned flags)
|
||||
{
|
||||
bool gc = flags & BTREE_TRIGGER_GC;
|
||||
struct bch_fs *c = trans->c;
|
||||
struct bch_replicas_padded r;
|
||||
struct stripe *m;
|
||||
unsigned i, blocks_nonempty = 0;
|
||||
@ -906,16 +917,18 @@ static int bch2_mark_stripe_ptr(struct bch_fs *c,
|
||||
spin_unlock(&c->ec_stripes_heap_lock);
|
||||
|
||||
r.e.data_type = data_type;
|
||||
update_replicas(c, &r.e, sectors, journal_seq, gc);
|
||||
update_replicas(c, &r.e, sectors, trans->journal_res.seq, gc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bch2_mark_extent(struct bch_fs *c,
|
||||
static int bch2_mark_extent(struct btree_trans *trans,
|
||||
struct bkey_s_c old, struct bkey_s_c new,
|
||||
unsigned journal_seq, unsigned flags)
|
||||
unsigned flags)
|
||||
{
|
||||
bool gc = flags & BTREE_TRIGGER_GC;
|
||||
u64 journal_seq = trans->journal_res.seq;
|
||||
struct bch_fs *c = trans->c;
|
||||
struct bkey_s_c k = flags & BTREE_TRIGGER_INSERT ? new : old;
|
||||
struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
|
||||
const union bch_extent_entry *entry;
|
||||
@ -944,8 +957,8 @@ static int bch2_mark_extent(struct bch_fs *c,
|
||||
if (flags & BTREE_TRIGGER_OVERWRITE)
|
||||
disk_sectors = -disk_sectors;
|
||||
|
||||
ret = bch2_mark_pointer(c, k, p, disk_sectors, data_type,
|
||||
journal_seq, flags);
|
||||
ret = bch2_mark_pointer(trans, k, p, disk_sectors,
|
||||
data_type, flags);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@ -963,8 +976,8 @@ static int bch2_mark_extent(struct bch_fs *c,
|
||||
dirty_sectors += disk_sectors;
|
||||
r.e.devs[r.e.nr_devs++] = p.ptr.dev;
|
||||
} else {
|
||||
ret = bch2_mark_stripe_ptr(c, p.ec, data_type,
|
||||
disk_sectors, journal_seq, flags);
|
||||
ret = bch2_mark_stripe_ptr(trans, p.ec, data_type,
|
||||
disk_sectors, flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -990,11 +1003,13 @@ static int bch2_mark_extent(struct bch_fs *c,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bch2_mark_stripe(struct bch_fs *c,
|
||||
struct bkey_s_c old, struct bkey_s_c new,
|
||||
u64 journal_seq, unsigned flags)
|
||||
static int bch2_mark_stripe(struct btree_trans *trans,
|
||||
struct bkey_s_c old, struct bkey_s_c new,
|
||||
unsigned flags)
|
||||
{
|
||||
bool gc = flags & BTREE_TRIGGER_GC;
|
||||
u64 journal_seq = trans->journal_res.seq;
|
||||
struct bch_fs *c = trans->c;
|
||||
size_t idx = new.k->p.offset;
|
||||
const struct bch_stripe *old_s = old.k->type == KEY_TYPE_stripe
|
||||
? bkey_s_c_to_stripe(old).v : NULL;
|
||||
@ -1058,7 +1073,7 @@ static int bch2_mark_stripe(struct bch_fs *c,
|
||||
m->blocks_nonempty = 0;
|
||||
|
||||
for (i = 0; i < new_s->nr_blocks; i++) {
|
||||
ret = mark_stripe_bucket(c, new, i, journal_seq, flags);
|
||||
ret = mark_stripe_bucket(trans, new, i, journal_seq, flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@ -1077,24 +1092,26 @@ static int bch2_mark_stripe(struct bch_fs *c,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bch2_mark_inode(struct bch_fs *c,
|
||||
struct bkey_s_c old, struct bkey_s_c new,
|
||||
u64 journal_seq, unsigned flags)
|
||||
static int bch2_mark_inode(struct btree_trans *trans,
|
||||
struct bkey_s_c old, struct bkey_s_c new,
|
||||
unsigned flags)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct bch_fs_usage __percpu *fs_usage;
|
||||
|
||||
preempt_disable();
|
||||
fs_usage = fs_usage_ptr(c, journal_seq, flags & BTREE_TRIGGER_GC);
|
||||
fs_usage = fs_usage_ptr(c, trans->journal_res.seq, flags & BTREE_TRIGGER_GC);
|
||||
fs_usage->nr_inodes += new.k->type == KEY_TYPE_inode;
|
||||
fs_usage->nr_inodes -= old.k->type == KEY_TYPE_inode;
|
||||
preempt_enable();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bch2_mark_reservation(struct bch_fs *c,
|
||||
struct bkey_s_c old, struct bkey_s_c new,
|
||||
u64 journal_seq, unsigned flags)
|
||||
static int bch2_mark_reservation(struct btree_trans *trans,
|
||||
struct bkey_s_c old, struct bkey_s_c new,
|
||||
unsigned flags)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct bkey_s_c k = flags & BTREE_TRIGGER_INSERT ? new : old;
|
||||
struct bch_fs_usage __percpu *fs_usage;
|
||||
unsigned replicas = bkey_s_c_to_reservation(k).v->nr_replicas;
|
||||
@ -1105,7 +1122,7 @@ static int bch2_mark_reservation(struct bch_fs *c,
|
||||
sectors *= replicas;
|
||||
|
||||
preempt_disable();
|
||||
fs_usage = fs_usage_ptr(c, journal_seq, flags & BTREE_TRIGGER_GC);
|
||||
fs_usage = fs_usage_ptr(c, trans->journal_res.seq, flags & BTREE_TRIGGER_GC);
|
||||
replicas = clamp_t(unsigned, replicas, 1,
|
||||
ARRAY_SIZE(fs_usage->persistent_reserved));
|
||||
|
||||
@ -1163,10 +1180,11 @@ fsck_err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bch2_mark_reflink_p(struct bch_fs *c,
|
||||
struct bkey_s_c old, struct bkey_s_c new,
|
||||
u64 journal_seq, unsigned flags)
|
||||
static int bch2_mark_reflink_p(struct btree_trans *trans,
|
||||
struct bkey_s_c old, struct bkey_s_c new,
|
||||
unsigned flags)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct bkey_s_c k = flags & BTREE_TRIGGER_INSERT ? new : old;
|
||||
struct bkey_s_c_reflink_p p = bkey_s_c_to_reflink_p(k);
|
||||
struct reflink_gc *ref;
|
||||
@ -1197,10 +1215,10 @@ static int bch2_mark_reflink_p(struct bch_fs *c,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bch2_mark_key_locked(struct bch_fs *c,
|
||||
static int bch2_mark_key_locked(struct btree_trans *trans,
|
||||
struct bkey_s_c old,
|
||||
struct bkey_s_c new,
|
||||
u64 journal_seq, unsigned flags)
|
||||
unsigned flags)
|
||||
{
|
||||
struct bkey_s_c k = flags & BTREE_TRIGGER_INSERT ? new : old;
|
||||
|
||||
@ -1209,29 +1227,30 @@ static int bch2_mark_key_locked(struct bch_fs *c,
|
||||
switch (k.k->type) {
|
||||
case KEY_TYPE_alloc:
|
||||
case KEY_TYPE_alloc_v2:
|
||||
return bch2_mark_alloc(c, old, new, journal_seq, flags);
|
||||
return bch2_mark_alloc(trans, old, new, flags);
|
||||
case KEY_TYPE_btree_ptr:
|
||||
case KEY_TYPE_btree_ptr_v2:
|
||||
case KEY_TYPE_extent:
|
||||
case KEY_TYPE_reflink_v:
|
||||
return bch2_mark_extent(c, old, new, journal_seq, flags);
|
||||
return bch2_mark_extent(trans, old, new, flags);
|
||||
case KEY_TYPE_stripe:
|
||||
return bch2_mark_stripe(c, old, new, journal_seq, flags);
|
||||
return bch2_mark_stripe(trans, old, new, flags);
|
||||
case KEY_TYPE_inode:
|
||||
return bch2_mark_inode(c, old, new, journal_seq, flags);
|
||||
return bch2_mark_inode(trans, old, new, flags);
|
||||
case KEY_TYPE_reservation:
|
||||
return bch2_mark_reservation(c, old, new, journal_seq, flags);
|
||||
return bch2_mark_reservation(trans, old, new, flags);
|
||||
case KEY_TYPE_reflink_p:
|
||||
return bch2_mark_reflink_p(c, old, new, journal_seq, flags);
|
||||
return bch2_mark_reflink_p(trans, old, new, flags);
|
||||
case KEY_TYPE_snapshot:
|
||||
return bch2_mark_snapshot(c, old, new, journal_seq, flags);
|
||||
return bch2_mark_snapshot(trans, old, new, flags);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int bch2_mark_key(struct bch_fs *c, struct bkey_s_c new, unsigned flags)
|
||||
int bch2_mark_key(struct btree_trans *trans, struct bkey_s_c new, unsigned flags)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct bkey deleted = KEY(0, 0, 0);
|
||||
struct bkey_s_c old = (struct bkey_s_c) { &deleted, NULL };
|
||||
int ret;
|
||||
@ -1239,7 +1258,7 @@ int bch2_mark_key(struct bch_fs *c, struct bkey_s_c new, unsigned flags)
|
||||
deleted.p = new.k->p;
|
||||
|
||||
percpu_down_read(&c->mark_lock);
|
||||
ret = bch2_mark_key_locked(c, old, new, 0, flags);
|
||||
ret = bch2_mark_key_locked(trans, old, new, flags);
|
||||
percpu_up_read(&c->mark_lock);
|
||||
|
||||
return ret;
|
||||
@ -1248,7 +1267,6 @@ int bch2_mark_key(struct bch_fs *c, struct bkey_s_c new, unsigned flags)
|
||||
int bch2_mark_update(struct btree_trans *trans, struct btree_path *path,
|
||||
struct bkey_i *new, unsigned flags)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct bkey _deleted = KEY(0, 0, 0);
|
||||
struct bkey_s_c deleted = (struct bkey_s_c) { &_deleted, NULL };
|
||||
struct bkey_s_c old;
|
||||
@ -1267,15 +1285,12 @@ int bch2_mark_update(struct btree_trans *trans, struct btree_path *path,
|
||||
|
||||
if (old.k->type == new->k.type &&
|
||||
((1U << old.k->type) & BTREE_TRIGGER_WANTS_OLD_AND_NEW)) {
|
||||
ret = bch2_mark_key_locked(c, old, bkey_i_to_s_c(new),
|
||||
trans->journal_res.seq,
|
||||
ret = bch2_mark_key_locked(trans, old, bkey_i_to_s_c(new),
|
||||
BTREE_TRIGGER_INSERT|BTREE_TRIGGER_OVERWRITE|flags);
|
||||
} else {
|
||||
ret = bch2_mark_key_locked(c, deleted, bkey_i_to_s_c(new),
|
||||
trans->journal_res.seq,
|
||||
ret = bch2_mark_key_locked(trans, deleted, bkey_i_to_s_c(new),
|
||||
BTREE_TRIGGER_INSERT|flags) ?:
|
||||
bch2_mark_key_locked(c, old, deleted,
|
||||
trans->journal_res.seq,
|
||||
bch2_mark_key_locked(trans, old, deleted,
|
||||
BTREE_TRIGGER_OVERWRITE|flags);
|
||||
}
|
||||
|
||||
@ -1440,7 +1455,8 @@ static int bch2_trans_mark_pointer(struct btree_trans *trans,
|
||||
if (IS_ERR(a))
|
||||
return PTR_ERR(a);
|
||||
|
||||
ret = __mark_pointer(c, k, &p.ptr, sectors, data_type, u.gen, &u.data_type,
|
||||
ret = __mark_pointer(trans, k, &p.ptr, sectors, data_type,
|
||||
u.gen, &u.data_type,
|
||||
&u.dirty_sectors, &u.cached_sectors);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
@ -226,7 +226,7 @@ void bch2_mark_metadata_bucket(struct bch_fs *, struct bch_dev *,
|
||||
size_t, enum bch_data_type, unsigned,
|
||||
struct gc_pos, unsigned);
|
||||
|
||||
int bch2_mark_key(struct bch_fs *, struct bkey_s_c, unsigned);
|
||||
int bch2_mark_key(struct btree_trans *, struct bkey_s_c, unsigned);
|
||||
|
||||
int bch2_mark_update(struct btree_trans *, struct btree_path *,
|
||||
struct bkey_i *, unsigned);
|
||||
|
@ -1634,13 +1634,14 @@ int bch2_stripes_write(struct bch_fs *c, unsigned flags)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bch2_stripes_read_fn(struct bch_fs *c, struct bkey_s_c k)
|
||||
static int bch2_stripes_read_fn(struct btree_trans *trans, struct bkey_s_c k)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
int ret = 0;
|
||||
|
||||
if (k.k->type == KEY_TYPE_stripe)
|
||||
ret = __ec_stripe_mem_alloc(c, k.k->p.offset, GFP_KERNEL) ?:
|
||||
bch2_mark_key(c, k,
|
||||
bch2_mark_key(trans, k,
|
||||
BTREE_TRIGGER_INSERT|
|
||||
BTREE_TRIGGER_NOATOMIC);
|
||||
|
||||
@ -1649,8 +1650,13 @@ static int bch2_stripes_read_fn(struct bch_fs *c, struct bkey_s_c k)
|
||||
|
||||
int bch2_stripes_read(struct bch_fs *c)
|
||||
{
|
||||
int ret = bch2_btree_and_journal_walk(c, BTREE_ID_stripes,
|
||||
bch2_stripes_read_fn);
|
||||
struct btree_trans trans;
|
||||
int ret;
|
||||
|
||||
bch2_trans_init(&trans, c, 0, 0);
|
||||
ret = bch2_btree_and_journal_walk(&trans, BTREE_ID_stripes,
|
||||
bch2_stripes_read_fn);
|
||||
bch2_trans_exit(&trans);
|
||||
if (ret)
|
||||
bch_err(c, "error reading stripes: %i", ret);
|
||||
|
||||
|
@ -337,10 +337,11 @@ static void btree_and_journal_iter_prefetch(struct bch_fs *c, struct btree *b,
|
||||
bch2_bkey_buf_exit(&tmp, c);
|
||||
}
|
||||
|
||||
static int bch2_btree_and_journal_walk_recurse(struct bch_fs *c, struct btree *b,
|
||||
static int bch2_btree_and_journal_walk_recurse(struct btree_trans *trans, struct btree *b,
|
||||
enum btree_id btree_id,
|
||||
btree_walk_key_fn key_fn)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct btree_and_journal_iter iter;
|
||||
struct bkey_s_c k;
|
||||
struct bkey_buf tmp;
|
||||
@ -364,11 +365,11 @@ static int bch2_btree_and_journal_walk_recurse(struct bch_fs *c, struct btree *b
|
||||
|
||||
btree_and_journal_iter_prefetch(c, b, iter);
|
||||
|
||||
ret = bch2_btree_and_journal_walk_recurse(c, child,
|
||||
ret = bch2_btree_and_journal_walk_recurse(trans, child,
|
||||
btree_id, key_fn);
|
||||
six_unlock_read(&child->c.lock);
|
||||
} else {
|
||||
ret = key_fn(c, k);
|
||||
ret = key_fn(trans, k);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
@ -382,9 +383,10 @@ static int bch2_btree_and_journal_walk_recurse(struct bch_fs *c, struct btree *b
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bch2_btree_and_journal_walk(struct bch_fs *c, enum btree_id btree_id,
|
||||
int bch2_btree_and_journal_walk(struct btree_trans *trans, enum btree_id btree_id,
|
||||
btree_walk_key_fn key_fn)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct btree *b = c->btree_roots[btree_id].b;
|
||||
int ret = 0;
|
||||
|
||||
@ -392,7 +394,7 @@ int bch2_btree_and_journal_walk(struct bch_fs *c, enum btree_id btree_id,
|
||||
return 0;
|
||||
|
||||
six_lock_read(&b->c.lock, NULL, NULL);
|
||||
ret = bch2_btree_and_journal_walk_recurse(c, b, btree_id, key_fn);
|
||||
ret = bch2_btree_and_journal_walk_recurse(trans, b, btree_id, key_fn);
|
||||
six_unlock_read(&b->c.lock);
|
||||
|
||||
return ret;
|
||||
|
@ -45,9 +45,9 @@ void bch2_btree_and_journal_iter_init_node_iter(struct btree_and_journal_iter *,
|
||||
struct bch_fs *,
|
||||
struct btree *);
|
||||
|
||||
typedef int (*btree_walk_key_fn)(struct bch_fs *c, struct bkey_s_c k);
|
||||
typedef int (*btree_walk_key_fn)(struct btree_trans *, struct bkey_s_c);
|
||||
|
||||
int bch2_btree_and_journal_walk(struct bch_fs *, enum btree_id, btree_walk_key_fn);
|
||||
int bch2_btree_and_journal_walk(struct btree_trans *, enum btree_id, btree_walk_key_fn);
|
||||
|
||||
void bch2_journal_keys_free(struct journal_keys *);
|
||||
void bch2_journal_entries_free(struct list_head *);
|
||||
|
@ -61,10 +61,11 @@ const char *bch2_snapshot_invalid(const struct bch_fs *c, struct bkey_s_c k)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int bch2_mark_snapshot(struct bch_fs *c,
|
||||
int bch2_mark_snapshot(struct btree_trans *trans,
|
||||
struct bkey_s_c old, struct bkey_s_c new,
|
||||
u64 journal_seq, unsigned flags)
|
||||
unsigned flags)
|
||||
{
|
||||
struct bch_fs *c = trans->c;
|
||||
struct snapshot_t *t;
|
||||
|
||||
t = genradix_ptr_alloc(&c->snapshots,
|
||||
@ -308,7 +309,7 @@ int bch2_fs_snapshots_start(struct bch_fs *c)
|
||||
if (BCH_SNAPSHOT_DELETED(bkey_s_c_to_snapshot(k).v))
|
||||
have_deleted = true;
|
||||
|
||||
ret = bch2_mark_snapshot(c, bkey_s_c_null, k, 0, 0);
|
||||
ret = bch2_mark_snapshot(&trans, bkey_s_c_null, k, 0);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
@ -499,7 +500,7 @@ static int bch2_snapshot_node_create(struct btree_trans *trans, u32 parent,
|
||||
|
||||
bch2_trans_update(trans, &iter, &n->k_i, 0);
|
||||
|
||||
ret = bch2_mark_snapshot(trans->c, bkey_s_c_null, bkey_i_to_s_c(&n->k_i), 0, 0);
|
||||
ret = bch2_mark_snapshot(trans, bkey_s_c_null, bkey_i_to_s_c(&n->k_i), 0);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
|
@ -12,8 +12,8 @@ const char *bch2_snapshot_invalid(const struct bch_fs *, struct bkey_s_c);
|
||||
.val_to_text = bch2_snapshot_to_text, \
|
||||
}
|
||||
|
||||
int bch2_mark_snapshot(struct bch_fs *, struct bkey_s_c,
|
||||
struct bkey_s_c, u64, unsigned);
|
||||
int bch2_mark_snapshot(struct btree_trans *, struct bkey_s_c,
|
||||
struct bkey_s_c, unsigned);
|
||||
|
||||
static inline struct snapshot_t *snapshot_t(struct bch_fs *c, u32 id)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user