summaryrefslogtreecommitdiffstats
path: root/fs/bcachefs/btree_update.h
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-04-28 05:48:33 +0200
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 23:10:01 +0200
commit34dfa5db191fe227c0c413624b7387f1f1804029 (patch)
tree44af501b23067b94c95d40191829a88917f7c08e /fs/bcachefs/btree_update.h
parentbcachefs: Move bch2_bkey_make_mut() to btree_update.h (diff)
downloadlinux-34dfa5db191fe227c0c413624b7387f1f1804029.tar.xz
linux-34dfa5db191fe227c0c413624b7387f1f1804029.zip
bcachefs: bch2_bkey_get_mut() improvements
- bch2_bkey_get_mut() now handles types increasing in size, allocating a buffer for the type's current size when necessary - bch2_bkey_make_mut_typed() - bch2_bkey_get_mut() now initializes the iterator, like bch2_bkey_get_iter() Also, refactor so that most of the code is in functions - now macros are only used for wrappers. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/btree_update.h')
-rw-r--r--fs/bcachefs/btree_update.h101
1 files changed, 72 insertions, 29 deletions
diff --git a/fs/bcachefs/btree_update.h b/fs/bcachefs/btree_update.h
index 0b320dfaed43..5e2aa21caf55 100644
--- a/fs/bcachefs/btree_update.h
+++ b/fs/bcachefs/btree_update.h
@@ -183,47 +183,90 @@ static inline void bch2_trans_reset_updates(struct btree_trans *trans)
}
}
-static inline struct bkey_i *bch2_bkey_make_mut(struct btree_trans *trans, struct bkey_s_c k)
+static inline struct bkey_i *__bch2_bkey_make_mut(struct btree_trans *trans, struct bkey_s_c k,
+ unsigned type, unsigned min_bytes)
{
- struct bkey_i *mut = bch2_trans_kmalloc_nomemzero(trans, bkey_bytes(k.k));
+ unsigned bytes = max_t(unsigned, min_bytes, bkey_bytes(k.k));
+ struct bkey_i *mut;
+
+ if (type && k.k->type != type)
+ return ERR_PTR(-ENOENT);
- if (!IS_ERR(mut))
+ mut = bch2_trans_kmalloc_nomemzero(trans, bytes);
+ if (!IS_ERR(mut)) {
bkey_reassemble(mut, k);
+
+ if (unlikely(bytes > bkey_bytes(k.k))) {
+ memset((void *) mut + bkey_bytes(k.k), 0,
+ bytes - bkey_bytes(k.k));
+ mut->k.u64s = DIV_ROUND_UP(bytes, sizeof(u64));
+ }
+ }
return mut;
}
-static inline struct bkey_i *bch2_bkey_get_mut(struct btree_trans *trans,
- struct btree_iter *iter)
+static inline struct bkey_i *bch2_bkey_make_mut(struct btree_trans *trans, struct bkey_s_c k)
{
- struct bkey_s_c k = bch2_btree_iter_peek_slot(iter);
+ return __bch2_bkey_make_mut(trans, k, 0, 0);
+}
- return unlikely(IS_ERR(k.k))
+#define bch2_bkey_make_mut_typed(_trans, _k, _type) \
+ bkey_i_to_##_type(__bch2_bkey_make_mut(_trans, _k, \
+ KEY_TYPE_##_type, sizeof(struct bkey_i_##_type)))
+
+static inline struct bkey_i *__bch2_bkey_get_mut(struct btree_trans *trans,
+ struct btree_iter *iter,
+ unsigned btree_id, struct bpos pos,
+ unsigned flags, unsigned type, unsigned min_bytes)
+{
+ struct bkey_s_c k = __bch2_bkey_get_iter(trans, iter,
+ btree_id, pos, flags|BTREE_ITER_INTENT, type);
+ struct bkey_i *ret = unlikely(IS_ERR(k.k))
? ERR_CAST(k.k)
- : bch2_bkey_make_mut(trans, k);
+ : __bch2_bkey_make_mut(trans, k, 0, min_bytes);
+ if (unlikely(IS_ERR(ret)))
+ bch2_trans_iter_exit(trans, iter);
+ return ret;
}
-#define bch2_bkey_get_mut_typed(_trans, _iter, _type) \
-({ \
- struct bkey_i *_k = bch2_bkey_get_mut(_trans, _iter); \
- struct bkey_i_##_type *_ret; \
- \
- if (IS_ERR(_k)) \
- _ret = ERR_CAST(_k); \
- else if (unlikely(_k->k.type != KEY_TYPE_##_type)) \
- _ret = ERR_PTR(-ENOENT); \
- else \
- _ret = bkey_i_to_##_type(_k); \
- _ret; \
-})
+static inline struct bkey_i *bch2_bkey_get_mut_minsize(struct btree_trans *trans,
+ struct btree_iter *iter,
+ unsigned btree_id, struct bpos pos,
+ unsigned flags, unsigned min_bytes)
+{
+ return __bch2_bkey_get_mut(trans, iter, btree_id, pos, flags, 0, min_bytes);
+}
+
+static inline struct bkey_i *bch2_bkey_get_mut(struct btree_trans *trans,
+ struct btree_iter *iter,
+ unsigned btree_id, struct bpos pos,
+ unsigned flags)
+{
+ return bch2_bkey_get_mut_minsize(trans, iter, btree_id, pos, flags, 0);
+}
+
+#define bch2_bkey_get_mut_typed(_trans, _iter, _btree_id, _pos, _flags, _type)\
+ bkey_i_to_##_type(__bch2_bkey_get_mut(_trans, _iter, \
+ _btree_id, _pos, _flags, \
+ KEY_TYPE_##_type, sizeof(struct bkey_i_##_type)))
+
+static inline struct bkey_i *__bch2_bkey_alloc(struct btree_trans *trans, struct btree_iter *iter,
+ unsigned type, unsigned val_size)
+{
+ struct bkey_i *k = bch2_trans_kmalloc(trans, sizeof(*k) + val_size);
+
+ if (!IS_ERR(k)) {
+ bkey_init(&k->k);
+ k->k.p = iter->pos;
+ k->k.type = type;
+ set_bkey_val_bytes(&k->k, val_size);
+ }
+
+ return k;
+}
#define bch2_bkey_alloc(_trans, _iter, _type) \
-({ \
- struct bkey_i_##_type *_k = bch2_trans_kmalloc_nomemzero(_trans, sizeof(*_k));\
- if (!IS_ERR(_k)) { \
- bkey_##_type##_init(&_k->k_i); \
- _k->k.p = (_iter)->pos; \
- } \
- _k; \
-})
+ bkey_i_to_##_type(__bch2_bkey_alloc(_trans, _iter, \
+ KEY_TYPE_##_type, sizeof(struct bch_##_type)))
#endif /* _BCACHEFS_BTREE_UPDATE_H */