2017-03-16 22:18:50 -08: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 00:26:52 -05:00
struct btree_trans ;
2017-03-16 22:18:50 -08:00
struct bkey ;
2018-11-01 15:10:01 -04:00
enum btree_node_type ;
2019-07-16 12:23:04 -04:00
extern const char * const bch2_bkey_types [ ] ;
2017-03-16 22:18:50 -08:00
2022-04-03 21:50:25 -04: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 15:59:53 -04:00
*/
2017-03-16 22:18:50 -08:00
struct bkey_ops {
2022-04-03 21:50:25 -04:00
int ( * key_invalid ) ( const struct bch_fs * c , struct bkey_s_c k ,
2022-12-20 19:58:16 -05:00
unsigned flags , struct printbuf * err ) ;
2018-11-09 01:24:07 -05:00
void ( * val_to_text ) ( struct printbuf * , struct bch_fs * ,
struct bkey_s_c ) ;
2020-02-06 20:15:15 -05:00
void ( * swab ) ( struct bkey_s ) ;
2018-11-01 15:10:01 -04:00
bool ( * key_normalize ) ( struct bch_fs * , struct bkey_s ) ;
2021-04-28 23:49:30 -04:00
bool ( * key_merge ) ( struct bch_fs * , struct bkey_s , struct bkey_s_c ) ;
2022-03-31 21:44:55 -04:00
int ( * trans_trigger ) ( struct btree_trans * , enum btree_id , unsigned ,
struct bkey_s_c , struct bkey_i * , unsigned ) ;
2023-03-01 22:14:31 -05:00
int ( * atomic_trigger ) ( struct btree_trans * , enum btree_id , unsigned ,
struct bkey_s_c , struct bkey_s_c , unsigned ) ;
2020-01-07 13:29:32 -05:00
void ( * compat ) ( enum btree_id id , unsigned version ,
unsigned big_endian , int write ,
struct bkey_s ) ;
2017-03-16 22:18:50 -08:00
} ;
2021-04-28 23:49:30 -04:00
extern const struct bkey_ops bch2_bkey_ops [ ] ;
2022-12-20 20:00:34 -05:00
# define BKEY_INVALID_FROM_JOURNAL (1 << 1)
2022-12-20 19:58:16 -05:00
int bch2_bkey_val_invalid ( struct bch_fs * , struct bkey_s_c , unsigned , struct printbuf * ) ;
2022-04-03 17:50:01 -04:00
int __bch2_bkey_invalid ( struct bch_fs * , struct bkey_s_c ,
2022-12-20 19:58:16 -05:00
enum btree_node_type , unsigned , struct printbuf * ) ;
2022-04-03 17:50:01 -04:00
int bch2_bkey_invalid ( struct bch_fs * , struct bkey_s_c ,
2022-12-20 19:58:16 -05:00
enum btree_node_type , unsigned , struct printbuf * ) ;
2022-04-03 17:50:01 -04:00
int bch2_bkey_in_btree_node ( struct btree * , struct bkey_s_c , struct printbuf * ) ;
2017-03-16 22:18:50 -08:00
2018-11-09 01:24:07 -05:00
void bch2_bpos_to_text ( struct printbuf * , struct bpos ) ;
void bch2_bkey_to_text ( struct printbuf * , const struct bkey * ) ;
2018-11-01 15:10:01 -04:00
void bch2_val_to_text ( struct printbuf * , struct bch_fs * ,
2018-11-09 01:24:07 -05:00
struct bkey_s_c ) ;
void bch2_bkey_val_to_text ( struct printbuf * , struct bch_fs * ,
2018-11-01 15:10:01 -04:00
struct bkey_s_c ) ;
2020-02-06 20:15:15 -05:00
void bch2_bkey_swab_val ( struct bkey_s ) ;
2018-11-01 15:10:01 -04:00
bool bch2_bkey_normalize ( struct bch_fs * , struct bkey_s ) ;
2017-03-16 22:18:50 -08:00
2021-04-28 23:49:30 -04: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 03:12:22 -05:00
bpos_eq ( l - > p , bkey_start_pos ( r ) ) ;
2021-04-28 23:49:30 -04:00
}
bool bch2_bkey_merge ( struct bch_fs * , struct bkey_s , struct bkey_s_c ) ;
2017-03-16 22:18:50 -08:00
2022-03-13 00:26:52 -05:00
static inline int bch2_mark_key ( struct btree_trans * trans ,
2023-03-01 22:14:31 -05:00
enum btree_id btree , unsigned level ,
struct bkey_s_c old , struct bkey_s_c new ,
unsigned flags )
2022-03-13 00:26:52 -05:00
{
const struct bkey_ops * ops = & bch2_bkey_ops [ old . k - > type ? : new . k - > type ] ;
return ops - > atomic_trigger
2023-03-01 22:14:31 -05:00
? ops - > atomic_trigger ( trans , btree , level , old , new , flags )
2022-03-13 00:26:52 -05:00
: 0 ;
}
2022-03-31 21:44:55 -04:00
enum btree_update_flags {
__BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE ,
__BTREE_UPDATE_NOJOURNAL ,
__BTREE_UPDATE_KEY_CACHE_RECLAIM ,
__BTREE_UPDATE_NO_KEY_CACHE_COHERENCY ,
__BTREE_TRIGGER_NORUN , /* Don't run triggers at all */
__BTREE_TRIGGER_INSERT ,
__BTREE_TRIGGER_OVERWRITE ,
__BTREE_TRIGGER_GC ,
__BTREE_TRIGGER_BUCKET_INVALIDATE ,
__BTREE_TRIGGER_NOATOMIC ,
} ;
# 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_UPDATE_NO_KEY_CACHE_COHERENCY \
( 1U < < __BTREE_UPDATE_NO_KEY_CACHE_COHERENCY )
# 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)
# define BTREE_TRIGGER_NOATOMIC (1U << __BTREE_TRIGGER_NOATOMIC)
# define BTREE_TRIGGER_WANTS_OLD_AND_NEW \
( ( 1U < < KEY_TYPE_alloc ) | \
( 1U < < KEY_TYPE_alloc_v2 ) | \
( 1U < < KEY_TYPE_alloc_v3 ) | \
( 1U < < KEY_TYPE_alloc_v4 ) | \
( 1U < < KEY_TYPE_stripe ) | \
( 1U < < KEY_TYPE_inode ) | \
( 1U < < KEY_TYPE_inode_v2 ) | \
( 1U < < KEY_TYPE_snapshot ) )
static inline int bch2_trans_mark_key ( struct btree_trans * trans ,
enum btree_id btree_id , unsigned level ,
struct bkey_s_c old , struct bkey_i * new ,
unsigned flags )
2022-03-13 00:26:52 -05:00
{
const struct bkey_ops * ops = & bch2_bkey_ops [ old . k - > type ? : new - > k . type ] ;
return ops - > trans_trigger
2022-03-31 21:44:55 -04:00
? ops - > trans_trigger ( trans , btree_id , level , old , new , flags )
2022-03-13 00:26:52 -05:00
: 0 ;
}
2022-03-31 21:44:55 -04: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 ;
return bch2_trans_mark_key ( trans , btree_id , level , old , & deleted ,
BTREE_TRIGGER_OVERWRITE | flags ) ;
}
static inline int bch2_trans_mark_new ( struct btree_trans * trans ,
enum btree_id btree_id , unsigned level ,
struct bkey_i * new , unsigned flags )
{
struct bkey_i deleted ;
bkey_init ( & deleted . k ) ;
deleted . k . p = new - > k . p ;
return bch2_trans_mark_key ( trans , btree_id , level , bkey_i_to_s_c ( & deleted ) , new ,
BTREE_TRIGGER_INSERT | flags ) ;
}
2018-11-01 15:10:01 -04:00
void bch2_bkey_renumber ( enum btree_node_type , struct bkey_packed * , int ) ;
2017-03-16 22:18:50 -08:00
2020-01-07 13:29:32 -05: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-16 22:18:50 -08:00
# endif /* _BCACHEFS_BKEY_METHODS_H */