mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-11-01 17:08:10 +00:00
bcachefs: Journal pin cleanups
Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
883f1a7ce0
commit
3f58a19763
4 changed files with 59 additions and 82 deletions
|
@ -867,8 +867,8 @@ static void btree_update_reparent(struct btree_update *as,
|
||||||
* just transfer the journal pin to the new interior update so
|
* just transfer the journal pin to the new interior update so
|
||||||
* btree_update_nodes_written() can drop it.
|
* btree_update_nodes_written() can drop it.
|
||||||
*/
|
*/
|
||||||
bch2_journal_pin_add_if_older(&c->journal, &child->journal,
|
bch2_journal_pin_copy(&c->journal, &as->journal,
|
||||||
&as->journal, interior_update_flush);
|
&child->journal, interior_update_flush);
|
||||||
bch2_journal_pin_drop(&c->journal, &child->journal);
|
bch2_journal_pin_drop(&c->journal, &child->journal);
|
||||||
|
|
||||||
as->journal_seq = max(as->journal_seq, child->journal_seq);
|
as->journal_seq = max(as->journal_seq, child->journal_seq);
|
||||||
|
@ -1049,13 +1049,13 @@ void bch2_btree_interior_update_will_free_node(struct btree_update *as,
|
||||||
* oldest pin of any of the nodes we're freeing. We'll release the pin
|
* oldest pin of any of the nodes we're freeing. We'll release the pin
|
||||||
* when the new nodes are persistent and reachable on disk:
|
* when the new nodes are persistent and reachable on disk:
|
||||||
*/
|
*/
|
||||||
bch2_journal_pin_add_if_older(&c->journal, &w->journal,
|
bch2_journal_pin_copy(&c->journal, &as->journal,
|
||||||
&as->journal, interior_update_flush);
|
&w->journal, interior_update_flush);
|
||||||
bch2_journal_pin_drop(&c->journal, &w->journal);
|
bch2_journal_pin_drop(&c->journal, &w->journal);
|
||||||
|
|
||||||
w = btree_prev_write(b);
|
w = btree_prev_write(b);
|
||||||
bch2_journal_pin_add_if_older(&c->journal, &w->journal,
|
bch2_journal_pin_copy(&c->journal, &as->journal,
|
||||||
&as->journal, interior_update_flush);
|
&w->journal, interior_update_flush);
|
||||||
bch2_journal_pin_drop(&c->journal, &w->journal);
|
bch2_journal_pin_drop(&c->journal, &w->journal);
|
||||||
|
|
||||||
mutex_unlock(&c->btree_interior_update_lock);
|
mutex_unlock(&c->btree_interior_update_lock);
|
||||||
|
|
|
@ -172,6 +172,9 @@ void bch2_btree_journal_key(struct btree_trans *trans,
|
||||||
struct journal *j = &c->journal;
|
struct journal *j = &c->journal;
|
||||||
struct btree *b = iter->l[0].b;
|
struct btree *b = iter->l[0].b;
|
||||||
struct btree_write *w = btree_current_write(b);
|
struct btree_write *w = btree_current_write(b);
|
||||||
|
u64 seq = likely(!(trans->flags & BTREE_INSERT_JOURNAL_REPLAY))
|
||||||
|
? trans->journal_res.seq
|
||||||
|
: j->replay_journal_seq;
|
||||||
|
|
||||||
EBUG_ON(iter->level || b->c.level);
|
EBUG_ON(iter->level || b->c.level);
|
||||||
EBUG_ON(trans->journal_res.ref !=
|
EBUG_ON(trans->journal_res.ref !=
|
||||||
|
@ -183,16 +186,10 @@ void bch2_btree_journal_key(struct btree_trans *trans,
|
||||||
cpu_to_le64(trans->journal_res.seq);
|
cpu_to_le64(trans->journal_res.seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(!journal_pin_active(&w->journal))) {
|
bch2_journal_pin_add(j, seq, &w->journal,
|
||||||
u64 seq = likely(!(trans->flags & BTREE_INSERT_JOURNAL_REPLAY))
|
btree_node_write_idx(b) == 0
|
||||||
? trans->journal_res.seq
|
? btree_node_flush0
|
||||||
: j->replay_journal_seq;
|
: btree_node_flush1);
|
||||||
|
|
||||||
bch2_journal_pin_add(j, seq, &w->journal,
|
|
||||||
btree_node_write_idx(b) == 0
|
|
||||||
? btree_node_flush0
|
|
||||||
: btree_node_flush1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unlikely(!btree_node_dirty(b)))
|
if (unlikely(!btree_node_dirty(b)))
|
||||||
set_btree_node_dirty(b);
|
set_btree_node_dirty(b);
|
||||||
|
|
|
@ -290,38 +290,6 @@ void bch2_journal_pin_put(struct journal *j, u64 seq)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void __journal_pin_add(struct journal *j,
|
|
||||||
u64 seq,
|
|
||||||
struct journal_entry_pin *pin,
|
|
||||||
journal_pin_flush_fn flush_fn)
|
|
||||||
{
|
|
||||||
struct journal_entry_pin_list *pin_list = journal_seq_pin(j, seq);
|
|
||||||
|
|
||||||
BUG_ON(journal_pin_active(pin));
|
|
||||||
BUG_ON(!atomic_read(&pin_list->count));
|
|
||||||
|
|
||||||
atomic_inc(&pin_list->count);
|
|
||||||
pin->seq = seq;
|
|
||||||
pin->flush = flush_fn;
|
|
||||||
|
|
||||||
list_add(&pin->list, flush_fn ? &pin_list->list : &pin_list->flushed);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the journal is currently full, we might want to call flush_fn
|
|
||||||
* immediately:
|
|
||||||
*/
|
|
||||||
journal_wake(j);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bch2_journal_pin_add(struct journal *j, u64 seq,
|
|
||||||
struct journal_entry_pin *pin,
|
|
||||||
journal_pin_flush_fn flush_fn)
|
|
||||||
{
|
|
||||||
spin_lock(&j->lock);
|
|
||||||
__journal_pin_add(j, seq, pin, flush_fn);
|
|
||||||
spin_unlock(&j->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void __journal_pin_drop(struct journal *j,
|
static inline void __journal_pin_drop(struct journal *j,
|
||||||
struct journal_entry_pin *pin)
|
struct journal_entry_pin *pin)
|
||||||
{
|
{
|
||||||
|
@ -354,42 +322,46 @@ void bch2_journal_pin_drop(struct journal *j,
|
||||||
spin_unlock(&j->lock);
|
spin_unlock(&j->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bch2_journal_pin_update(struct journal *j, u64 seq,
|
void __bch2_journal_pin_add(struct journal *j, u64 seq,
|
||||||
struct journal_entry_pin *pin,
|
struct journal_entry_pin *pin,
|
||||||
journal_pin_flush_fn flush_fn)
|
journal_pin_flush_fn flush_fn)
|
||||||
{
|
{
|
||||||
|
struct journal_entry_pin_list *pin_list = journal_seq_pin(j, seq);
|
||||||
|
|
||||||
spin_lock(&j->lock);
|
spin_lock(&j->lock);
|
||||||
|
|
||||||
if (pin->seq != seq) {
|
__journal_pin_drop(j, pin);
|
||||||
__journal_pin_drop(j, pin);
|
|
||||||
__journal_pin_add(j, seq, pin, flush_fn);
|
|
||||||
} else {
|
|
||||||
struct journal_entry_pin_list *pin_list =
|
|
||||||
journal_seq_pin(j, seq);
|
|
||||||
|
|
||||||
list_move(&pin->list, &pin_list->list);
|
BUG_ON(!atomic_read(&pin_list->count));
|
||||||
}
|
|
||||||
|
atomic_inc(&pin_list->count);
|
||||||
|
pin->seq = seq;
|
||||||
|
pin->flush = flush_fn;
|
||||||
|
|
||||||
|
list_add(&pin->list, flush_fn ? &pin_list->list : &pin_list->flushed);
|
||||||
|
|
||||||
spin_unlock(&j->lock);
|
spin_unlock(&j->lock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the journal is currently full, we might want to call flush_fn
|
||||||
|
* immediately:
|
||||||
|
*/
|
||||||
|
journal_wake(j);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bch2_journal_pin_add_if_older(struct journal *j,
|
void bch2_journal_pin_copy(struct journal *j,
|
||||||
struct journal_entry_pin *src_pin,
|
struct journal_entry_pin *dst,
|
||||||
struct journal_entry_pin *pin,
|
struct journal_entry_pin *src,
|
||||||
journal_pin_flush_fn flush_fn)
|
journal_pin_flush_fn flush_fn)
|
||||||
{
|
{
|
||||||
spin_lock(&j->lock);
|
if (journal_pin_active(src) &&
|
||||||
|
(!journal_pin_active(dst) || src->seq < dst->seq))
|
||||||
if (journal_pin_active(src_pin) &&
|
__bch2_journal_pin_add(j, src->seq, dst, flush_fn);
|
||||||
(!journal_pin_active(pin) ||
|
|
||||||
src_pin->seq < pin->seq)) {
|
|
||||||
__journal_pin_drop(j, pin);
|
|
||||||
__journal_pin_add(j, src_pin->seq, pin, flush_fn);
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_unlock(&j->lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bch2_journal_pin_flush: ensure journal pin callback is no longer running
|
||||||
|
*/
|
||||||
void bch2_journal_pin_flush(struct journal *j, struct journal_entry_pin *pin)
|
void bch2_journal_pin_flush(struct journal *j, struct journal_entry_pin *pin)
|
||||||
{
|
{
|
||||||
BUG_ON(journal_pin_active(pin));
|
BUG_ON(journal_pin_active(pin));
|
||||||
|
|
|
@ -29,16 +29,24 @@ journal_seq_pin(struct journal *j, u64 seq)
|
||||||
}
|
}
|
||||||
|
|
||||||
void bch2_journal_pin_put(struct journal *, u64);
|
void bch2_journal_pin_put(struct journal *, u64);
|
||||||
|
|
||||||
void bch2_journal_pin_add(struct journal *, u64, struct journal_entry_pin *,
|
|
||||||
journal_pin_flush_fn);
|
|
||||||
void bch2_journal_pin_update(struct journal *, u64, struct journal_entry_pin *,
|
|
||||||
journal_pin_flush_fn);
|
|
||||||
void bch2_journal_pin_drop(struct journal *, struct journal_entry_pin *);
|
void bch2_journal_pin_drop(struct journal *, struct journal_entry_pin *);
|
||||||
void bch2_journal_pin_add_if_older(struct journal *,
|
|
||||||
struct journal_entry_pin *,
|
void __bch2_journal_pin_add(struct journal *, u64, struct journal_entry_pin *,
|
||||||
struct journal_entry_pin *,
|
journal_pin_flush_fn);
|
||||||
journal_pin_flush_fn);
|
|
||||||
|
static inline void bch2_journal_pin_add(struct journal *j, u64 seq,
|
||||||
|
struct journal_entry_pin *pin,
|
||||||
|
journal_pin_flush_fn flush_fn)
|
||||||
|
{
|
||||||
|
if (unlikely(!journal_pin_active(pin)))
|
||||||
|
__bch2_journal_pin_add(j, seq, pin, flush_fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void bch2_journal_pin_copy(struct journal *,
|
||||||
|
struct journal_entry_pin *,
|
||||||
|
struct journal_entry_pin *,
|
||||||
|
journal_pin_flush_fn);
|
||||||
|
|
||||||
void bch2_journal_pin_flush(struct journal *, struct journal_entry_pin *);
|
void bch2_journal_pin_flush(struct journal *, struct journal_entry_pin *);
|
||||||
|
|
||||||
void bch2_journal_do_discards(struct journal *);
|
void bch2_journal_do_discards(struct journal *);
|
||||||
|
|
Loading…
Reference in a new issue