diff options
author | Kent Overstreet <kent.overstreet@linux.dev> | 2023-04-28 05:48:33 +0200 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@linux.dev> | 2023-10-22 23:10:01 +0200 |
commit | 34dfa5db191fe227c0c413624b7387f1f1804029 (patch) | |
tree | 44af501b23067b94c95d40191829a88917f7c08e /fs/bcachefs/btree_update.h | |
parent | bcachefs: Move bch2_bkey_make_mut() to btree_update.h (diff) | |
download | linux-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.h | 101 |
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 */ |