diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2019-05-21 15:49:56 -0400 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 17:08:22 -0400 |
commit | 4ee202e2b70fc8f6a7abd8fc3b3a8024c437fe24 (patch) | |
tree | 3c5e3994cdb79319aac5c47aaf02cf9edd0ce8c2 | |
parent | cdeeb75ea9e329b6e02e7956f741de7c9ddfbb3b (diff) |
bcachefs: better BTREE_INSERT_NO_CLEAR_REPLICAS
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r-- | fs/bcachefs/btree_update_leaf.c | 15 | ||||
-rw-r--r-- | fs/bcachefs/buckets.c | 31 |
2 files changed, 21 insertions, 25 deletions
diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c index e6fbe8a7413a..7475d5c4420b 100644 --- a/fs/bcachefs/btree_update_leaf.c +++ b/fs/bcachefs/btree_update_leaf.c @@ -544,13 +544,6 @@ static inline int do_btree_insert_at(struct btree_trans *trans, struct btree_insert_entry *i; int ret; - if (likely(!(trans->flags & BTREE_INSERT_NO_CLEAR_REPLICAS)) && - trans->fs_usage_deltas) { - memset(&trans->fs_usage_deltas->fs_usage, 0, - sizeof(trans->fs_usage_deltas->fs_usage)); - trans->fs_usage_deltas->used = 0; - } - trans_for_each_update_iter(trans, i) BUG_ON(i->iter->uptodate >= BTREE_ITER_NEED_RELOCK); @@ -561,7 +554,7 @@ static inline int do_btree_insert_at(struct btree_trans *trans, if (ret == -EINTR) trace_trans_restart_mark(trans->ip); if (ret) - return ret; + goto out_clear_replicas; } btree_trans_lock_write(c, trans); @@ -655,6 +648,12 @@ out: } bch2_journal_res_put(&c->journal, &trans->journal_res); +out_clear_replicas: + if (trans->fs_usage_deltas) { + memset(&trans->fs_usage_deltas->fs_usage, 0, + sizeof(trans->fs_usage_deltas->fs_usage)); + trans->fs_usage_deltas->used = 0; + } return ret; } diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c index 5c18cebeb180..f38cda70617b 100644 --- a/fs/bcachefs/buckets.c +++ b/fs/bcachefs/buckets.c @@ -1260,30 +1260,31 @@ void bch2_trans_fs_usage_apply(struct btree_trans *trans, /* trans_mark: */ -static void replicas_deltas_realloc(struct btree_trans *trans) +static struct replicas_delta_list * +replicas_deltas_realloc(struct btree_trans *trans, unsigned more) { struct replicas_delta_list *d = trans->fs_usage_deltas; - unsigned new_size = d ? d->size * 2 : 128; + unsigned new_size = d ? (d->size + more) * 2 : 128; - d = krealloc(d, sizeof(*d) + new_size, GFP_NOIO|__GFP_ZERO); - BUG_ON(!d); + if (!d || d->used + more > d->size) { + d = krealloc(d, sizeof(*d) + new_size, GFP_NOIO|__GFP_ZERO); + BUG_ON(!d); - d->size = new_size; - trans->fs_usage_deltas = d; + d->size = new_size; + trans->fs_usage_deltas = d; + } + return d; } static inline void update_replicas_list(struct btree_trans *trans, struct bch_replicas_entry *r, s64 sectors) { - struct replicas_delta_list *d = trans->fs_usage_deltas; + struct replicas_delta_list *d; struct replicas_delta *n; unsigned b = replicas_entry_bytes(r) + 8; - if (!d || d->used + b > d->size) { - replicas_deltas_realloc(trans); - d = trans->fs_usage_deltas; - } + d = replicas_deltas_realloc(trans, b); n = (void *) d->d + d->used; n->delta = sectors; @@ -1566,9 +1567,7 @@ int bch2_trans_mark_key(struct btree_trans *trans, return bch2_trans_mark_extent(trans, k, sectors, BCH_DATA_USER); case KEY_TYPE_inode: - if (!trans->fs_usage_deltas) - replicas_deltas_realloc(trans); - d = trans->fs_usage_deltas; + d = replicas_deltas_realloc(trans, 0); if (inserting) d->fs_usage.nr_inodes++; @@ -1578,9 +1577,7 @@ int bch2_trans_mark_key(struct btree_trans *trans, case KEY_TYPE_reservation: { unsigned replicas = bkey_s_c_to_reservation(k).v->nr_replicas; - if (!trans->fs_usage_deltas) - replicas_deltas_realloc(trans); - d = trans->fs_usage_deltas; + d = replicas_deltas_realloc(trans, 0); sectors *= replicas; replicas = clamp_t(unsigned, replicas, 1, |