2017-03-17 09:18:50 +03:00
/* SPDX-License-Identifier: GPL-2.0 */
# ifndef _BCACHEFS_BKEY_METHODS_H
# define _BCACHEFS_BKEY_METHODS_H
# include "bkey.h"
struct bch_fs ;
struct btree ;
2022-03-13 08:26:52 +03:00
struct btree_trans ;
2017-03-17 09:18:50 +03:00
struct bkey ;
2018-11-01 22:10:01 +03:00
enum btree_node_type ;
2019-07-16 19:23:04 +03:00
extern const char * const bch2_bkey_types [ ] ;
2023-07-07 02:23:27 +03:00
extern const struct bkey_ops bch2_bkey_null_ops ;
2017-03-17 09:18:50 +03:00
2022-04-04 04:50:25 +03:00
/*
* key_invalid : checks validity of @ k , returns 0 if good or - EINVAL if bad . If
* invalid , entire key will be deleted .
*
* When invalid , error string is returned via @ err . @ rw indicates whether key is
* being read or written ; more aggressive checks can be enabled when rw = = WRITE .
2022-10-22 22:59:53 +03:00
*/
2017-03-17 09:18:50 +03:00
struct bkey_ops {
2023-10-25 03:44:36 +03:00
int ( * key_invalid ) ( struct bch_fs * c , struct bkey_s_c k ,
2023-07-07 04:16:10 +03:00
enum bkey_invalid_flags flags , struct printbuf * err ) ;
2018-11-09 09:24:07 +03:00
void ( * val_to_text ) ( struct printbuf * , struct bch_fs * ,
struct bkey_s_c ) ;
2020-02-07 04:15:15 +03:00
void ( * swab ) ( struct bkey_s ) ;
2018-11-01 22:10:01 +03:00
bool ( * key_normalize ) ( struct bch_fs * , struct bkey_s ) ;
2021-04-29 06:49:30 +03:00
bool ( * key_merge ) ( struct bch_fs * , struct bkey_s , struct bkey_s_c ) ;
2022-04-01 04:44:55 +03:00
int ( * trans_trigger ) ( struct btree_trans * , enum btree_id , unsigned ,
2023-12-28 07:19:09 +03:00
struct bkey_s_c , struct bkey_s , unsigned ) ;
2023-03-02 06:14:31 +03:00
int ( * atomic_trigger ) ( struct btree_trans * , enum btree_id , unsigned ,
2023-12-28 07:19:09 +03:00
struct bkey_s_c , struct bkey_s , unsigned ) ;
2020-01-07 21:29:32 +03:00
void ( * compat ) ( enum btree_id id , unsigned version ,
unsigned big_endian , int write ,
struct bkey_s ) ;
2023-04-29 20:24:18 +03:00
/* Size of value type when first created: */
unsigned min_val_size ;
2017-03-17 09:18:50 +03:00
} ;
2021-04-29 06:49:30 +03:00
extern const struct bkey_ops bch2_bkey_ops [ ] ;
2023-07-07 02:23:27 +03:00
static inline const struct bkey_ops * bch2_bkey_type_ops ( enum bch_bkey_type type )
{
return likely ( type < KEY_TYPE_MAX )
? & bch2_bkey_ops [ type ]
: & bch2_bkey_null_ops ;
}
2023-07-07 04:16:10 +03:00
int bch2_bkey_val_invalid ( struct bch_fs * , struct bkey_s_c ,
enum bkey_invalid_flags , struct printbuf * ) ;
int __bch2_bkey_invalid ( struct bch_fs * , struct bkey_s_c , enum btree_node_type ,
enum bkey_invalid_flags , struct printbuf * ) ;
int bch2_bkey_invalid ( struct bch_fs * , struct bkey_s_c , enum btree_node_type ,
enum bkey_invalid_flags , struct printbuf * ) ;
2023-10-25 03:44:36 +03:00
int bch2_bkey_in_btree_node ( struct bch_fs * , struct btree * ,
struct bkey_s_c , struct printbuf * ) ;
2017-03-17 09:18:50 +03:00
2018-11-09 09:24:07 +03:00
void bch2_bpos_to_text ( struct printbuf * , struct bpos ) ;
void bch2_bkey_to_text ( struct printbuf * , const struct bkey * ) ;
2018-11-01 22:10:01 +03:00
void bch2_val_to_text ( struct printbuf * , struct bch_fs * ,
2018-11-09 09:24:07 +03:00
struct bkey_s_c ) ;
void bch2_bkey_val_to_text ( struct printbuf * , struct bch_fs * ,
2018-11-01 22:10:01 +03:00
struct bkey_s_c ) ;
2020-02-07 04:15:15 +03:00
void bch2_bkey_swab_val ( struct bkey_s ) ;
2018-11-01 22:10:01 +03:00
bool bch2_bkey_normalize ( struct bch_fs * , struct bkey_s ) ;
2017-03-17 09:18:50 +03:00
2021-04-29 06:49:30 +03:00
static inline bool bch2_bkey_maybe_mergable ( const struct bkey * l , const struct bkey * r )
{
return l - > type = = r - > type & &
! bversion_cmp ( l - > version , r - > version ) & &
2022-11-24 11:12:22 +03:00
bpos_eq ( l - > p , bkey_start_pos ( r ) ) ;
2021-04-29 06:49:30 +03:00
}
bool bch2_bkey_merge ( struct bch_fs * , struct bkey_s , struct bkey_s_c ) ;
2017-03-17 09:18:50 +03:00
2022-03-13 08:26:52 +03:00
static inline int bch2_mark_key ( struct btree_trans * trans ,
2023-03-02 06:14:31 +03:00
enum btree_id btree , unsigned level ,
2023-12-28 07:19:09 +03:00
struct bkey_s_c old , struct bkey_s new ,
2023-03-02 06:14:31 +03:00
unsigned flags )
2022-03-13 08:26:52 +03:00
{
2023-07-07 02:23:27 +03:00
const struct bkey_ops * ops = bch2_bkey_type_ops ( old . k - > type ? : new . k - > type ) ;
2022-03-13 08:26:52 +03:00
return ops - > atomic_trigger
2023-03-02 06:14:31 +03:00
? ops - > atomic_trigger ( trans , btree , level , old , new , flags )
2022-03-13 08:26:52 +03:00
: 0 ;
}
2022-04-01 04:44:55 +03:00
enum btree_update_flags {
2023-05-01 01:04:43 +03:00
__BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE = __BTREE_ITER_FLAGS_END ,
2022-04-01 04:44:55 +03:00
__BTREE_UPDATE_NOJOURNAL ,
__BTREE_UPDATE_KEY_CACHE_RECLAIM ,
__BTREE_TRIGGER_NORUN , /* Don't run triggers at all */
__BTREE_TRIGGER_INSERT ,
__BTREE_TRIGGER_OVERWRITE ,
__BTREE_TRIGGER_GC ,
__BTREE_TRIGGER_BUCKET_INVALIDATE ,
} ;
# define BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE (1U << __BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE)
# define BTREE_UPDATE_NOJOURNAL (1U << __BTREE_UPDATE_NOJOURNAL)
# define BTREE_UPDATE_KEY_CACHE_RECLAIM (1U << __BTREE_UPDATE_KEY_CACHE_RECLAIM)
# define BTREE_TRIGGER_NORUN (1U << __BTREE_TRIGGER_NORUN)
# define BTREE_TRIGGER_INSERT (1U << __BTREE_TRIGGER_INSERT)
# define BTREE_TRIGGER_OVERWRITE (1U << __BTREE_TRIGGER_OVERWRITE)
# define BTREE_TRIGGER_GC (1U << __BTREE_TRIGGER_GC)
# define BTREE_TRIGGER_BUCKET_INVALIDATE (1U << __BTREE_TRIGGER_BUCKET_INVALIDATE)
static inline int bch2_trans_mark_key ( struct btree_trans * trans ,
enum btree_id btree_id , unsigned level ,
2023-12-28 07:19:09 +03:00
struct bkey_s_c old , struct bkey_s new ,
2022-04-01 04:44:55 +03:00
unsigned flags )
2022-03-13 08:26:52 +03:00
{
2023-12-28 07:19:09 +03:00
const struct bkey_ops * ops = bch2_bkey_type_ops ( old . k - > type ? : new . k - > type ) ;
2022-03-13 08:26:52 +03:00
return ops - > trans_trigger
2022-04-01 04:44:55 +03:00
? ops - > trans_trigger ( trans , btree_id , level , old , new , flags )
2022-03-13 08:26:52 +03:00
: 0 ;
}
2022-04-01 04:44:55 +03:00
static inline int bch2_trans_mark_old ( struct btree_trans * trans ,
enum btree_id btree_id , unsigned level ,
struct bkey_s_c old , unsigned flags )
{
struct bkey_i deleted ;
bkey_init ( & deleted . k ) ;
deleted . k . p = old . k - > p ;
2023-12-28 07:19:09 +03:00
return bch2_trans_mark_key ( trans , btree_id , level , old , bkey_i_to_s ( & deleted ) ,
2022-04-01 04:44:55 +03:00
BTREE_TRIGGER_OVERWRITE | flags ) ;
}
static inline int bch2_trans_mark_new ( struct btree_trans * trans ,
enum btree_id btree_id , unsigned level ,
2023-12-28 07:19:09 +03:00
struct bkey_s new , unsigned flags )
2022-04-01 04:44:55 +03:00
{
struct bkey_i deleted ;
bkey_init ( & deleted . k ) ;
2023-12-28 07:19:09 +03:00
deleted . k . p = new . k - > p ;
2022-04-01 04:44:55 +03:00
return bch2_trans_mark_key ( trans , btree_id , level , bkey_i_to_s_c ( & deleted ) , new ,
BTREE_TRIGGER_INSERT | flags ) ;
}
2018-11-01 22:10:01 +03:00
void bch2_bkey_renumber ( enum btree_node_type , struct bkey_packed * , int ) ;
2017-03-17 09:18:50 +03:00
2020-01-07 21:29:32 +03:00
void __bch2_bkey_compat ( unsigned , enum btree_id , unsigned , unsigned ,
int , struct bkey_format * , struct bkey_packed * ) ;
static inline void bch2_bkey_compat ( unsigned level , enum btree_id btree_id ,
unsigned version , unsigned big_endian ,
int write ,
struct bkey_format * f ,
struct bkey_packed * k )
{
if ( version < bcachefs_metadata_version_current | |
big_endian ! = CPU_BIG_ENDIAN )
__bch2_bkey_compat ( level , btree_id , version ,
big_endian , write , f , k ) ;
}
2017-03-17 09:18:50 +03:00
# endif /* _BCACHEFS_BKEY_METHODS_H */