summaryrefslogtreecommitdiff
path: root/libbcachefs/alloc_background.c
diff options
context:
space:
mode:
Diffstat (limited to 'libbcachefs/alloc_background.c')
-rw-r--r--libbcachefs/alloc_background.c57
1 files changed, 32 insertions, 25 deletions
diff --git a/libbcachefs/alloc_background.c b/libbcachefs/alloc_background.c
index c3794518..9d9615aa 100644
--- a/libbcachefs/alloc_background.c
+++ b/libbcachefs/alloc_background.c
@@ -208,29 +208,25 @@ void bch2_alloc_to_text(struct printbuf *out, struct bch_fs *c,
get_alloc_field(a.v, &d, i));
}
-int bch2_alloc_read(struct bch_fs *c, struct journal_keys *journal_keys)
+static int bch2_alloc_read_fn(struct bch_fs *c, enum btree_id id,
+ unsigned level, struct bkey_s_c k)
{
- struct btree_trans trans;
- struct btree_and_journal_iter iter;
- struct bkey_s_c k;
- struct bch_dev *ca;
- unsigned i;
- int ret = 0;
-
- bch2_trans_init(&trans, c, 0, 0);
-
- bch2_btree_and_journal_iter_init(&iter, &trans, journal_keys,
- BTREE_ID_ALLOC, POS_MIN);
-
- while ((k = bch2_btree_and_journal_iter_peek(&iter)).k) {
+ if (!level)
bch2_mark_key(c, k, 0, 0, NULL, 0,
BTREE_TRIGGER_ALLOC_READ|
BTREE_TRIGGER_NOATOMIC);
- bch2_btree_and_journal_iter_advance(&iter);
- }
+ return 0;
+}
+
+int bch2_alloc_read(struct bch_fs *c, struct journal_keys *journal_keys)
+{
+ struct bch_dev *ca;
+ unsigned i;
+ int ret = 0;
- ret = bch2_trans_exit(&trans) ?: ret;
+ ret = bch2_btree_and_journal_walk(c, journal_keys, BTREE_ID_ALLOC,
+ NULL, bch2_alloc_read_fn);
if (ret) {
bch_err(c, "error reading alloc info: %i", ret);
return ret;
@@ -847,7 +843,7 @@ static int bch2_invalidate_one_bucket2(struct btree_trans *trans,
struct bkey_s_c k;
bool invalidating_cached_data;
size_t b;
- int ret;
+ int ret = 0;
BUG_ON(!ca->alloc_heap.used ||
!ca->alloc_heap.data[0].nr);
@@ -861,11 +857,27 @@ static int bch2_invalidate_one_bucket2(struct btree_trans *trans,
BUG_ON(!fifo_push(&ca->free_inc, b));
+ g = bucket(ca, b);
+ m = READ_ONCE(g->mark);
+
bch2_mark_alloc_bucket(c, ca, b, true, gc_pos_alloc(c, NULL), 0);
spin_unlock(&c->freelist_lock);
percpu_up_read(&c->mark_lock);
+ invalidating_cached_data = m.cached_sectors != 0;
+ if (!invalidating_cached_data)
+ goto out;
+
+ /*
+ * If the read-only path is trying to shut down, we can't be generating
+ * new btree updates:
+ */
+ if (test_bit(BCH_FS_ALLOCATOR_STOPPING, &c->flags)) {
+ ret = 1;
+ goto out;
+ }
+
BUG_ON(BKEY_ALLOC_VAL_U64s_MAX > 8);
bch2_btree_iter_set_pos(iter, POS(ca->dev_idx, b));
@@ -919,7 +931,7 @@ retry:
flags);
if (ret == -EINTR)
goto retry;
-
+out:
if (!ret) {
/* remove from alloc_heap: */
struct alloc_heap_entry e, *top = ca->alloc_heap.data;
@@ -953,7 +965,7 @@ retry:
percpu_up_read(&c->mark_lock);
}
- return ret;
+ return ret < 0 ? ret : 0;
}
static bool bch2_invalidate_one_bucket(struct bch_fs *c, struct bch_dev *ca,
@@ -1465,11 +1477,6 @@ again:
}
rcu_read_unlock();
- if (c->btree_roots_dirty) {
- bch2_journal_meta(&c->journal);
- goto again;
- }
-
return !nodes_unwritten &&
!bch2_btree_interior_updates_nr_pending(c);
}