On Tue, May 13, 2025 at 06:54:26PM +0800, Alan Huang wrote:
> Before invoking bch2_accounting_mem_mod_locked in
> bch2_gc_accounting_done, we already write locked mark_lock,
> in bch2_accounting_mem_insert, we lock mark_lock again.
>
> Signed-off-by: Alan Huang <[email protected]>
Applied, queued up for 6.15
> ---
> fs/bcachefs/disk_accounting.c | 17 +++++++++++++++--
> fs/bcachefs/disk_accounting.h | 16 +++++++++++-----
> 2 files changed, 26 insertions(+), 7 deletions(-)
>
> diff --git a/fs/bcachefs/disk_accounting.c b/fs/bcachefs/disk_accounting.c
> index 2dcccf1edbb9..195dc3fcec1d 100644
> --- a/fs/bcachefs/disk_accounting.c
> +++ b/fs/bcachefs/disk_accounting.c
> @@ -376,6 +376,19 @@ int bch2_accounting_mem_insert(struct bch_fs *c, struct
> bkey_s_c_accounting a,
> return ret;
> }
>
> +int bch2_accounting_mem_insert_locked(struct bch_fs *c, struct
> bkey_s_c_accounting a,
> + enum bch_accounting_mode mode)
> +{
> + union bch_replicas_padded r;
> +
> + if (mode != BCH_ACCOUNTING_read &&
> + accounting_to_replicas(&r.e, a.k->p) &&
> + !bch2_replicas_marked_locked(c, &r.e))
> + return -BCH_ERR_btree_insert_need_mark_replicas;
> +
> + return __bch2_accounting_mem_insert(c, a);
> +}
> +
> static bool accounting_mem_entry_is_zero(struct accounting_mem_entry *e)
> {
> for (unsigned i = 0; i < e->nr_counters; i++)
> @@ -585,7 +598,7 @@ int bch2_gc_accounting_done(struct bch_fs *c)
> accounting_key_init(&k_i.k, &acc_k,
> src_v, nr);
> bch2_accounting_mem_mod_locked(trans,
>
> bkey_i_to_s_c_accounting(&k_i.k),
> -
> BCH_ACCOUNTING_normal);
> +
> BCH_ACCOUNTING_normal, true);
>
> preempt_disable();
> struct bch_fs_usage_base *dst =
> this_cpu_ptr(c->usage);
> @@ -614,7 +627,7 @@ static int accounting_read_key(struct btree_trans *trans,
> struct bkey_s_c k)
>
> percpu_down_read(&c->mark_lock);
> int ret = bch2_accounting_mem_mod_locked(trans,
> bkey_s_c_to_accounting(k),
> - BCH_ACCOUNTING_read);
> + BCH_ACCOUNTING_read, false);
> percpu_up_read(&c->mark_lock);
> return ret;
> }
> diff --git a/fs/bcachefs/disk_accounting.h b/fs/bcachefs/disk_accounting.h
> index 6524cb14a58a..54cb8a5b117d 100644
> --- a/fs/bcachefs/disk_accounting.h
> +++ b/fs/bcachefs/disk_accounting.h
> @@ -136,6 +136,7 @@ enum bch_accounting_mode {
> };
>
> int bch2_accounting_mem_insert(struct bch_fs *, struct bkey_s_c_accounting,
> enum bch_accounting_mode);
> +int bch2_accounting_mem_insert_locked(struct bch_fs *, struct
> bkey_s_c_accounting, enum bch_accounting_mode);
> void bch2_accounting_mem_gc(struct bch_fs *);
>
> static inline bool bch2_accounting_is_mem(struct disk_accounting_pos *acc)
> @@ -150,7 +151,8 @@ static inline bool bch2_accounting_is_mem(struct
> disk_accounting_pos *acc)
> */
> static inline int bch2_accounting_mem_mod_locked(struct btree_trans *trans,
> struct bkey_s_c_accounting a,
> - enum bch_accounting_mode mode)
> + enum bch_accounting_mode mode,
> + bool write_locked)
> {
> struct bch_fs *c = trans->c;
> struct bch_accounting_mem *acc = &c->accounting;
> @@ -189,7 +191,11 @@ static inline int bch2_accounting_mem_mod_locked(struct
> btree_trans *trans,
>
> while ((idx = eytzinger0_find(acc->k.data, acc->k.nr,
> sizeof(acc->k.data[0]),
> accounting_pos_cmp, &a.k->p)) >=
> acc->k.nr) {
> - int ret = bch2_accounting_mem_insert(c, a, mode);
> + int ret = 0;
> + if (unlikely(write_locked))
> + ret = bch2_accounting_mem_insert_locked(c, a, mode);
> + else
> + ret = bch2_accounting_mem_insert(c, a, mode);
> if (ret)
> return ret;
> }
> @@ -206,7 +212,7 @@ static inline int bch2_accounting_mem_mod_locked(struct
> btree_trans *trans,
> static inline int bch2_accounting_mem_add(struct btree_trans *trans, struct
> bkey_s_c_accounting a, bool gc)
> {
> percpu_down_read(&trans->c->mark_lock);
> - int ret = bch2_accounting_mem_mod_locked(trans, a, gc ?
> BCH_ACCOUNTING_gc : BCH_ACCOUNTING_normal);
> + int ret = bch2_accounting_mem_mod_locked(trans, a, gc ?
> BCH_ACCOUNTING_gc : BCH_ACCOUNTING_normal, false);
> percpu_up_read(&trans->c->mark_lock);
> return ret;
> }
> @@ -259,7 +265,7 @@ static inline int
> bch2_accounting_trans_commit_hook(struct btree_trans *trans,
> EBUG_ON(bversion_zero(a->k.bversion));
>
> return likely(!(commit_flags & BCH_TRANS_COMMIT_skip_accounting_apply))
> - ? bch2_accounting_mem_mod_locked(trans, accounting_i_to_s_c(a),
> BCH_ACCOUNTING_normal)
> + ? bch2_accounting_mem_mod_locked(trans, accounting_i_to_s_c(a),
> BCH_ACCOUNTING_normal, false)
> : 0;
> }
>
> @@ -271,7 +277,7 @@ static inline void
> bch2_accounting_trans_commit_revert(struct btree_trans *trans
> struct bkey_s_accounting a = accounting_i_to_s(a_i);
>
> bch2_accounting_neg(a);
> - bch2_accounting_mem_mod_locked(trans, a.c,
> BCH_ACCOUNTING_normal);
> + bch2_accounting_mem_mod_locked(trans, a.c,
> BCH_ACCOUNTING_normal, false);
> bch2_accounting_neg(a);
> }
> }
> --
> 2.48.1
>