summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2024-05-03 12:43:31 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2024-05-09 16:23:35 -0400
commit0e57996c6964027e36a854247bfd266d207314c7 (patch)
treee435289aa771516003d99c76b3028379581069a6
parentb6fb4269e707bb410e202fb160c8d7a188ef60f8 (diff)
bcachefs: bch2_dev_get_ioref2(); alloc_background.c
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
-rw-r--r--fs/bcachefs/alloc_background.c19
-rw-r--r--fs/bcachefs/sb-members.h18
2 files changed, 26 insertions, 11 deletions
diff --git a/fs/bcachefs/alloc_background.c b/fs/bcachefs/alloc_background.c
index 71b727f5d432..b9ded84d2d94 100644
--- a/fs/bcachefs/alloc_background.c
+++ b/fs/bcachefs/alloc_background.c
@@ -1657,9 +1657,8 @@ static void discard_buckets_next_dev(struct bch_fs *c, struct discard_buckets_st
bch2_dev_usage_read(s->ca).d[BCH_DATA_free].buckets)
bch2_journal_flush_async(&c->journal, NULL);
- bch2_dev_put(s->ca);
- if (ca)
- bch2_dev_get(ca);
+ if (s->ca)
+ percpu_ref_put(&s->ca->io_ref);
s->ca = ca;
s->need_journal_commit_this_dev = 0;
}
@@ -1673,15 +1672,15 @@ static int bch2_discard_one_bucket(struct btree_trans *trans,
struct bpos pos = need_discard_iter->pos;
struct btree_iter iter = { NULL };
struct bkey_s_c k;
- struct bch_dev *ca;
struct bkey_i_alloc_v4 *a;
struct printbuf buf = PRINTBUF;
bool discard_locked = false;
int ret = 0;
- ca = bch2_dev_bkey_exists(c, pos.inode);
-
- if (!percpu_ref_tryget(&ca->io_ref)) {
+ struct bch_dev *ca = s->ca && s->ca->dev_idx == pos.inode
+ ? s->ca
+ : bch2_dev_get_ioref2(c, pos.inode, WRITE);
+ if (!ca) {
bch2_btree_iter_set_pos(need_discard_iter, POS(pos.inode + 1, 0));
return 0;
}
@@ -1787,7 +1786,6 @@ out:
discard_in_flight_remove(c, iter.pos);
s->seen++;
bch2_trans_iter_exit(trans, &iter);
- percpu_ref_put(&ca->io_ref);
printbuf_exit(&buf);
return ret;
}
@@ -1862,9 +1860,8 @@ static void bch2_do_discards_fast_work(struct work_struct *work)
if (i->snapshot)
continue;
- ca = bch2_dev_bkey_exists(c, i->inode);
-
- if (!percpu_ref_tryget(&ca->io_ref)) {
+ ca = bch2_dev_get_ioref2(c, i->inode, WRITE);
+ if (!ca) {
darray_remove_item(&c->discard_buckets_in_flight, i);
continue;
}
diff --git a/fs/bcachefs/sb-members.h b/fs/bcachefs/sb-members.h
index 7cecac44ab80..f2a7794b0b50 100644
--- a/fs/bcachefs/sb-members.h
+++ b/fs/bcachefs/sb-members.h
@@ -285,6 +285,24 @@ static inline struct bch_dev *bch2_dev_iterate(struct bch_fs *c, struct bch_dev
return bch2_dev_tryget(c, dev_idx);
}
+static inline struct bch_dev *bch2_dev_get_ioref2(struct bch_fs *c, unsigned dev, int rw)
+{
+ rcu_read_lock();
+ struct bch_dev *ca = bch2_dev_rcu(c, dev);
+ if (ca && !percpu_ref_tryget(&ca->io_ref))
+ ca = NULL;
+ rcu_read_unlock();
+
+ if (ca &&
+ (ca->mi.state == BCH_MEMBER_STATE_rw ||
+ (ca->mi.state == BCH_MEMBER_STATE_ro && rw == READ)))
+ return ca;
+
+ if (ca)
+ percpu_ref_put(&ca->io_ref);
+ return NULL;
+}
+
/* XXX kill, move to struct bch_fs */
static inline struct bch_devs_mask bch2_online_devs(struct bch_fs *c)
{