summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/bcachefs/btree_update_interior.c34
-rw-r--r--fs/bcachefs/btree_update_interior.h12
-rw-r--r--fs/bcachefs/extents.c12
-rw-r--r--fs/bcachefs/extents.h1
4 files changed, 42 insertions, 17 deletions
diff --git a/fs/bcachefs/btree_update_interior.c b/fs/bcachefs/btree_update_interior.c
index 8e3d3db2c53b..ebdb4d2f1be9 100644
--- a/fs/bcachefs/btree_update_interior.c
+++ b/fs/bcachefs/btree_update_interior.c
@@ -285,7 +285,7 @@ static struct btree *__bch2_btree_node_alloc(struct btree_trans *trans,
struct closure *cl,
bool interior_node,
unsigned target,
- unsigned flags)
+ enum bch_trans_commit_flags flags)
{
struct bch_fs *c = trans->c;
struct write_point *wp;
@@ -305,13 +305,18 @@ static struct btree *__bch2_btree_node_alloc(struct btree_trans *trans,
mutex_lock(&c->btree_reserve_cache_lock);
if (c->btree_reserve_cache_nr > nr_reserve) {
- struct btree_alloc *a =
- &c->btree_reserve_cache[--c->btree_reserve_cache_nr];
-
- bkey_copy(&b->key, &a->k);
- b->ob = a->ob;
- mutex_unlock(&c->btree_reserve_cache_lock);
- goto out;
+ for (struct btree_alloc *a = c->btree_reserve_cache;
+ a < c->btree_reserve_cache + c->btree_reserve_cache_nr;
+ a++) {
+ if (target && !bch2_bkey_in_target(c, bkey_i_to_s_c(&a->k), target))
+ continue;
+
+ bkey_copy(&b->key, &a->k);
+ b->ob = a->ob;
+ *a = c->btree_reserve_cache[--c->btree_reserve_cache_nr];
+ mutex_unlock(&c->btree_reserve_cache_lock);
+ goto out;
+ }
}
mutex_unlock(&c->btree_reserve_cache_lock);
retry:
@@ -1139,7 +1144,8 @@ static const char * const btree_node_reawrite_reason_strs[] = {
static struct btree_update *
bch2_btree_update_start(struct btree_trans *trans, struct btree_path *path,
unsigned level_start, bool split,
- unsigned target, unsigned flags)
+ unsigned target,
+ enum bch_trans_commit_flags flags)
{
struct bch_fs *c = trans->c;
struct btree_update *as;
@@ -2222,7 +2228,7 @@ int bch2_btree_node_rewrite(struct btree_trans *trans,
struct btree_iter *iter,
struct btree *b,
unsigned target,
- unsigned flags)
+ enum bch_trans_commit_flags flags)
{
struct bch_fs *c = trans->c;
struct btree *n, *parent;
@@ -2287,7 +2293,8 @@ err:
int bch2_btree_node_rewrite_key(struct btree_trans *trans,
enum btree_id btree, unsigned level,
- struct bkey_i *k, unsigned flags)
+ struct bkey_i *k,
+ enum bch_trans_commit_flags flags)
{
struct btree_iter iter;
bch2_trans_node_iter_init(trans, &iter,
@@ -2311,7 +2318,7 @@ int bch2_btree_node_rewrite_pos(struct btree_trans *trans,
enum btree_id btree, unsigned level,
struct bpos pos,
unsigned target,
- unsigned flags)
+ enum bch_trans_commit_flags flags)
{
BUG_ON(!level);
@@ -2330,7 +2337,8 @@ err:
}
int bch2_btree_node_rewrite_key_get_iter(struct btree_trans *trans,
- struct btree *b, unsigned flags)
+ struct btree *b,
+ enum bch_trans_commit_flags flags)
{
struct btree_iter iter;
int ret = get_iter_to_node(trans, &iter, b);
diff --git a/fs/bcachefs/btree_update_interior.h b/fs/bcachefs/btree_update_interior.h
index ac04e45a8515..6ed049f19a9a 100644
--- a/fs/bcachefs/btree_update_interior.h
+++ b/fs/bcachefs/btree_update_interior.h
@@ -175,15 +175,19 @@ static inline int bch2_foreground_maybe_merge(struct btree_trans *trans,
}
int bch2_btree_node_rewrite(struct btree_trans *, struct btree_iter *,
- struct btree *, unsigned, unsigned);
+ struct btree *, unsigned,
+ enum bch_trans_commit_flags);
int bch2_btree_node_rewrite_key(struct btree_trans *,
enum btree_id, unsigned,
- struct bkey_i *, unsigned);
+ struct bkey_i *,
+ enum bch_trans_commit_flags);
int bch2_btree_node_rewrite_pos(struct btree_trans *,
enum btree_id, unsigned,
- struct bpos, unsigned, unsigned);
+ struct bpos, unsigned,
+ enum bch_trans_commit_flags);
int bch2_btree_node_rewrite_key_get_iter(struct btree_trans *,
- struct btree *, unsigned);
+ struct btree *,
+ enum bch_trans_commit_flags);
void bch2_btree_node_rewrite_async(struct bch_fs *, struct btree *);
diff --git a/fs/bcachefs/extents.c b/fs/bcachefs/extents.c
index 83cbd77dcb9c..ec0951fbddea 100644
--- a/fs/bcachefs/extents.c
+++ b/fs/bcachefs/extents.c
@@ -1023,6 +1023,18 @@ bool bch2_bkey_has_target(struct bch_fs *c, struct bkey_s_c k, unsigned target)
return false;
}
+bool bch2_bkey_in_target(struct bch_fs *c, struct bkey_s_c k, unsigned target)
+{
+ struct bkey_ptrs_c ptrs = bch2_bkey_ptrs_c(k);
+
+ guard(rcu)();
+ bkey_for_each_ptr(ptrs, ptr)
+ if (!bch2_dev_in_target(c, ptr->dev, target))
+ return false;
+
+ return true;
+}
+
bool bch2_bkey_matches_ptr(struct bch_fs *c, struct bkey_s_c k,
struct bch_extent_ptr m, u64 offset)
{
diff --git a/fs/bcachefs/extents.h b/fs/bcachefs/extents.h
index b8590e51b76e..f212f91c278d 100644
--- a/fs/bcachefs/extents.h
+++ b/fs/bcachefs/extents.h
@@ -615,6 +615,7 @@ static inline struct bch_extent_ptr *bch2_bkey_has_device(struct bkey_s k, unsig
}
bool bch2_bkey_has_target(struct bch_fs *, struct bkey_s_c, unsigned);
+bool bch2_bkey_in_target(struct bch_fs *, struct bkey_s_c, unsigned);
void bch2_bkey_extent_entry_drop(struct bkey_i *, union bch_extent_entry *);