summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2019-05-21 15:49:56 -0400
committerKent Overstreet <kent.overstreet@gmail.com>2019-05-21 17:23:06 -0400
commit90d7e65242808ba0fe13b56f77c9bfd66e31cc1b (patch)
treec15645ecaf9b5f26b1128ecf629ad2682621ac33
parentd975ae8783ec0537b71c3c5be0c28b78ad08e236 (diff)
bcachefs: better BTREE_INSERT_NO_CLEAR_REPLICAS
-rw-r--r--fs/bcachefs/btree_update_leaf.c15
-rw-r--r--fs/bcachefs/buckets.c31
2 files changed, 21 insertions, 25 deletions
diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c
index 33e785763358..44c1ff8740d6 100644
--- a/fs/bcachefs/btree_update_leaf.c
+++ b/fs/bcachefs/btree_update_leaf.c
@@ -543,13 +543,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);
@@ -560,7 +553,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);
@@ -654,6 +647,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 4235d7d5eb4d..cc1ed50f891f 100644
--- a/fs/bcachefs/buckets.c
+++ b/fs/bcachefs/buckets.c
@@ -1251,30 +1251,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;
@@ -1557,9 +1558,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++;
@@ -1569,9 +1568,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,