summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2021-11-28 14:08:58 -0500
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:09:18 -0400
commit502cfb3591ec1f3d133c7eb281b8b93ca2bb2768 (patch)
treeb47077a84db629dbd528459880455e66a90573cb /fs
parentf449bedb068447d3e9b1d64a41852b2aaca36fda (diff)
downloadlwn-502cfb3591ec1f3d133c7eb281b8b93ca2bb2768.tar.gz
lwn-502cfb3591ec1f3d133c7eb281b8b93ca2bb2768.zip
bcachefs: Kill bch2_replicas_delta_list_marked()
This changes bch2_trans_fs_usage_apply() to handle failure (replicas entry missing) by reverting the changes it made - meaning we can make the main transaction commit path a bit slimmer, and perhaps also simplify some locking in upcoming patches. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/bcachefs/btree_update_leaf.c30
-rw-r--r--fs/bcachefs/buckets.c17
-rw-r--r--fs/bcachefs/buckets.h2
-rw-r--r--fs/bcachefs/replicas.c14
-rw-r--r--fs/bcachefs/replicas.h1
5 files changed, 26 insertions, 38 deletions
diff --git a/fs/bcachefs/btree_update_leaf.c b/fs/bcachefs/btree_update_leaf.c
index 61c87525e48d..c5cbd3a4d66b 100644
--- a/fs/bcachefs/btree_update_leaf.c
+++ b/fs/bcachefs/btree_update_leaf.c
@@ -438,17 +438,6 @@ bch2_trans_commit_write_locked(struct btree_trans *trans,
marking = true;
}
- if (marking) {
- percpu_down_read(&c->mark_lock);
- }
-
- /* Must be called under mark_lock: */
- if (marking && trans->fs_usage_deltas &&
- !bch2_replicas_delta_list_marked(c, trans->fs_usage_deltas)) {
- ret = BTREE_INSERT_NEED_MARK_REPLICAS;
- goto err;
- }
-
/*
* Don't get journal reservation until after we know insert will
* succeed:
@@ -457,7 +446,7 @@ bch2_trans_commit_write_locked(struct btree_trans *trans,
ret = bch2_trans_journal_res_get(trans,
JOURNAL_RES_GET_NONBLOCK);
if (ret)
- goto err;
+ return ret;
} else {
trans->journal_res.seq = c->journal.replay_journal_seq;
}
@@ -485,22 +474,27 @@ bch2_trans_commit_write_locked(struct btree_trans *trans,
i->k->k.version = MAX_VERSION;
}
+ if (marking)
+ percpu_down_read(&c->mark_lock);
+
+ if (marking && trans->fs_usage_deltas &&
+ bch2_trans_fs_usage_apply(trans, trans->fs_usage_deltas)) {
+ percpu_up_read(&c->mark_lock);
+ return BTREE_INSERT_NEED_MARK_REPLICAS;
+ }
+
trans_for_each_update(trans, i)
if (BTREE_NODE_TYPE_HAS_MEM_TRIGGERS & (1U << i->bkey_type))
bch2_mark_update(trans, i->path, i->k, i->flags);
- if (marking && trans->fs_usage_deltas)
- bch2_trans_fs_usage_apply(trans, trans->fs_usage_deltas);
-
if (unlikely(c->gc_pos.phase))
bch2_trans_mark_gc(trans);
trans_for_each_update(trans, i)
do_btree_insert_one(trans, i);
-err:
- if (marking) {
+
+ if (marking)
percpu_up_read(&c->mark_lock);
- }
return ret;
}
diff --git a/fs/bcachefs/buckets.c b/fs/bcachefs/buckets.c
index 2c0a385ace50..e919afe6a110 100644
--- a/fs/bcachefs/buckets.c
+++ b/fs/bcachefs/buckets.c
@@ -1363,14 +1363,14 @@ void fs_usage_apply_warn(struct btree_trans *trans,
__WARN();
}
-void bch2_trans_fs_usage_apply(struct btree_trans *trans,
- struct replicas_delta_list *deltas)
+int bch2_trans_fs_usage_apply(struct btree_trans *trans,
+ struct replicas_delta_list *deltas)
{
struct bch_fs *c = trans->c;
static int warned_disk_usage = 0;
bool warn = false;
unsigned disk_res_sectors = trans->disk_res ? trans->disk_res->sectors : 0;
- struct replicas_delta *d = deltas->d;
+ struct replicas_delta *d = deltas->d, *d2;
struct replicas_delta *top = (void *) deltas->d + deltas->used;
struct bch_fs_usage *dst;
s64 added = 0, should_not_have_added;
@@ -1389,7 +1389,8 @@ void bch2_trans_fs_usage_apply(struct btree_trans *trans,
added += d->delta;
}
- BUG_ON(__update_replicas(c, dst, &d->r, d->delta));
+ if (__update_replicas(c, dst, &d->r, d->delta))
+ goto need_mark;
}
dst->nr_inodes += deltas->nr_inodes;
@@ -1427,6 +1428,14 @@ void bch2_trans_fs_usage_apply(struct btree_trans *trans,
if (unlikely(warn) && !xchg(&warned_disk_usage, 1))
fs_usage_apply_warn(trans, disk_res_sectors, should_not_have_added);
+ return 0;
+need_mark:
+ /* revert changes: */
+ for (d2 = deltas->d; d2 != d; d2 = replicas_delta_next(d2))
+ BUG_ON(__update_replicas(c, dst, &d2->r, -d2->delta));
+
+ preempt_enable();
+ return -1;
}
/* trans_mark: */
diff --git a/fs/bcachefs/buckets.h b/fs/bcachefs/buckets.h
index 54a29bf69d67..7b7d08af2253 100644
--- a/fs/bcachefs/buckets.h
+++ b/fs/bcachefs/buckets.h
@@ -233,7 +233,7 @@ int bch2_mark_update(struct btree_trans *, struct btree_path *,
int bch2_trans_mark_key(struct btree_trans *, struct bkey_s_c,
struct bkey_s_c, unsigned);
-void bch2_trans_fs_usage_apply(struct btree_trans *, struct replicas_delta_list *);
+int bch2_trans_fs_usage_apply(struct btree_trans *, struct replicas_delta_list *);
int bch2_trans_mark_metadata_bucket(struct btree_trans *, struct bch_dev *,
size_t, enum bch_data_type, unsigned);
diff --git a/fs/bcachefs/replicas.c b/fs/bcachefs/replicas.c
index 57e093983dfc..9bfe7fa51d32 100644
--- a/fs/bcachefs/replicas.c
+++ b/fs/bcachefs/replicas.c
@@ -475,20 +475,6 @@ static int __bch2_mark_bkey_replicas(struct bch_fs *c, struct bkey_s_c k,
/* replicas delta list: */
-bool bch2_replicas_delta_list_marked(struct bch_fs *c,
- struct replicas_delta_list *r)
-{
- struct replicas_delta *d = r->d;
- struct replicas_delta *top = (void *) r->d + r->used;
-
- percpu_rwsem_assert_held(&c->mark_lock);
-
- for (d = r->d; d != top; d = replicas_delta_next(d))
- if (bch2_replicas_entry_idx(c, &d->r) < 0)
- return false;
- return true;
-}
-
int bch2_replicas_delta_list_mark(struct bch_fs *c,
struct replicas_delta_list *r)
{
diff --git a/fs/bcachefs/replicas.h b/fs/bcachefs/replicas.h
index 72ac544f16d8..66ca88deb0c0 100644
--- a/fs/bcachefs/replicas.h
+++ b/fs/bcachefs/replicas.h
@@ -48,7 +48,6 @@ replicas_delta_next(struct replicas_delta *d)
return (void *) d + replicas_entry_bytes(&d->r) + 8;
}
-bool bch2_replicas_delta_list_marked(struct bch_fs *, struct replicas_delta_list *);
int bch2_replicas_delta_list_mark(struct bch_fs *, struct replicas_delta_list *);
void bch2_bkey_to_replicas(struct bch_replicas_entry *, struct bkey_s_c);