2021-03-16 00:42:25 -04:00
/* SPDX-License-Identifier: GPL-2.0 */
# ifndef _BCACHEFS_SUBVOLUME_H
# define _BCACHEFS_SUBVOLUME_H
2022-03-29 15:48:45 -04:00
# include "darray.h"
2021-10-11 12:03:19 -04:00
# include "subvolume_types.h"
2023-07-06 21:16:10 -04:00
enum bkey_invalid_flags ;
2023-03-29 11:18:52 -04:00
void bch2_snapshot_tree_to_text ( struct printbuf * , struct bch_fs * , struct bkey_s_c ) ;
int bch2_snapshot_tree_invalid ( const struct bch_fs * , struct bkey_s_c ,
2023-07-06 21:16:10 -04:00
enum bkey_invalid_flags , struct printbuf * ) ;
2023-03-29 11:18:52 -04:00
# define bch2_bkey_ops_snapshot_tree ((struct bkey_ops) { \
. key_invalid = bch2_snapshot_tree_invalid , \
. val_to_text = bch2_snapshot_tree_to_text , \
. min_val_size = 8 , \
} )
2023-04-28 03:50:57 -04:00
int bch2_snapshot_tree_lookup ( struct btree_trans * , u32 , struct bch_snapshot_tree * ) ;
2021-03-16 00:42:25 -04:00
void bch2_snapshot_to_text ( struct printbuf * , struct bch_fs * , struct bkey_s_c ) ;
2022-04-03 21:50:25 -04:00
int bch2_snapshot_invalid ( const struct bch_fs * , struct bkey_s_c ,
2023-07-06 21:16:10 -04:00
enum bkey_invalid_flags , struct printbuf * ) ;
2023-03-01 22:14:31 -05:00
int bch2_mark_snapshot ( struct btree_trans * , enum btree_id , unsigned ,
struct bkey_s_c , struct bkey_s_c , unsigned ) ;
2021-03-16 00:42:25 -04:00
2022-10-22 15:59:53 -04:00
# define bch2_bkey_ops_snapshot ((struct bkey_ops) { \
2021-03-16 00:42:25 -04:00
. key_invalid = bch2_snapshot_invalid , \
. val_to_text = bch2_snapshot_to_text , \
2023-02-17 00:39:12 -05:00
. atomic_trigger = bch2_mark_snapshot , \
2023-04-29 13:24:18 -04:00
. min_val_size = 24 , \
2022-10-22 15:59:53 -04:00
} )
2021-03-16 00:42:25 -04:00
static inline struct snapshot_t * snapshot_t ( struct bch_fs * c , u32 id )
{
return genradix_ptr ( & c - > snapshots , U32_MAX - id ) ;
}
static inline u32 bch2_snapshot_parent ( struct bch_fs * c , u32 id )
{
return snapshot_t ( c , id ) - > parent ;
}
2023-03-29 11:18:52 -04:00
static inline u32 bch2_snapshot_root ( struct bch_fs * c , u32 id )
{
u32 parent ;
while ( ( parent = bch2_snapshot_parent ( c , id ) ) )
id = parent ;
return id ;
}
2022-07-14 02:47:36 -04:00
static inline u32 bch2_snapshot_equiv ( struct bch_fs * c , u32 id )
{
return snapshot_t ( c , id ) - > equiv ;
}
static inline bool bch2_snapshot_is_equiv ( struct bch_fs * c , u32 id )
{
return id = = snapshot_t ( c , id ) - > equiv ;
}
2021-03-16 00:42:25 -04:00
static inline u32 bch2_snapshot_internal_node ( struct bch_fs * c , u32 id )
{
struct snapshot_t * s = snapshot_t ( c , id ) ;
return s - > children [ 0 ] | | s - > children [ 1 ] ;
}
static inline u32 bch2_snapshot_sibling ( struct bch_fs * c , u32 id )
{
struct snapshot_t * s ;
u32 parent = bch2_snapshot_parent ( c , id ) ;
if ( ! parent )
return 0 ;
s = snapshot_t ( c , bch2_snapshot_parent ( c , id ) ) ;
if ( id = = s - > children [ 0 ] )
return s - > children [ 1 ] ;
if ( id = = s - > children [ 1 ] )
return s - > children [ 0 ] ;
return 0 ;
}
static inline bool bch2_snapshot_is_ancestor ( struct bch_fs * c , u32 id , u32 ancestor )
{
while ( id & & id < ancestor )
id = bch2_snapshot_parent ( c , id ) ;
return id = = ancestor ;
}
2023-02-16 23:42:09 -05:00
static inline bool bch2_snapshot_has_children ( struct bch_fs * c , u32 id )
{
struct snapshot_t * t = snapshot_t ( c , id ) ;
return ( t - > children [ 0 ] | t - > children [ 1 ] ) ! = 0 ;
}
2022-03-29 15:48:45 -04:00
static inline bool snapshot_list_has_id ( snapshot_id_list * s , u32 id )
2021-10-28 16:24:39 -04:00
{
2022-03-29 15:48:45 -04:00
u32 * i ;
2021-10-28 16:24:39 -04:00
2022-03-29 15:48:45 -04:00
darray_for_each ( * s , i )
if ( * i = = id )
2021-10-28 16:24:39 -04:00
return true ;
return false ;
}
2022-07-14 02:34:48 -04:00
static inline bool snapshot_list_has_ancestor ( struct bch_fs * c , snapshot_id_list * s , u32 id )
{
u32 * i ;
darray_for_each ( * s , i )
if ( bch2_snapshot_is_ancestor ( c , id , * i ) )
return true ;
return false ;
}
static inline int snapshot_list_add ( struct bch_fs * c , snapshot_id_list * s , u32 id )
{
int ret ;
BUG_ON ( snapshot_list_has_id ( s , id ) ) ;
ret = darray_push ( s , id ) ;
if ( ret )
bch_err ( c , " error reallocating snapshot_id_list (size %zu) " , s - > size ) ;
return ret ;
}
2023-03-29 11:18:52 -04:00
int bch2_fs_check_snapshot_trees ( struct bch_fs * ) ;
2022-07-14 01:10:24 -04:00
int bch2_fs_check_snapshots ( struct bch_fs * ) ;
int bch2_fs_check_subvols ( struct bch_fs * ) ;
2021-03-16 00:42:25 -04:00
void bch2_fs_snapshots_exit ( struct bch_fs * ) ;
int bch2_fs_snapshots_start ( struct bch_fs * ) ;
2022-04-03 21:50:25 -04:00
int bch2_subvolume_invalid ( const struct bch_fs * , struct bkey_s_c ,
2022-12-20 19:58:16 -05:00
unsigned , struct printbuf * ) ;
2021-03-16 00:42:25 -04:00
void bch2_subvolume_to_text ( struct printbuf * , struct bch_fs * , struct bkey_s_c ) ;
2022-10-22 15:59:53 -04:00
# define bch2_bkey_ops_subvolume ((struct bkey_ops) { \
2021-03-16 00:42:25 -04:00
. key_invalid = bch2_subvolume_invalid , \
. val_to_text = bch2_subvolume_to_text , \
2023-04-29 13:24:18 -04:00
. min_val_size = 16 , \
2022-10-22 15:59:53 -04:00
} )
2021-03-16 00:42:25 -04:00
2021-09-30 19:46:23 -04:00
int bch2_subvolume_get ( struct btree_trans * , unsigned ,
bool , int , struct bch_subvolume * ) ;
2021-10-27 13:05:56 -04:00
int bch2_snapshot_get_subvol ( struct btree_trans * , u32 ,
struct bch_subvolume * ) ;
2021-03-16 00:42:25 -04:00
int bch2_subvolume_get_snapshot ( struct btree_trans * , u32 , u32 * ) ;
2021-12-29 13:50:50 -05:00
/* only exported for tests: */
int bch2_snapshot_node_create ( struct btree_trans * , u32 ,
u32 * , u32 * , unsigned ) ;
2022-07-14 01:10:24 -04:00
int bch2_delete_dead_snapshots ( struct bch_fs * ) ;
void bch2_delete_dead_snapshots_async ( struct bch_fs * ) ;
2021-10-11 12:03:19 -04:00
int bch2_subvolume_unlink ( struct btree_trans * , u32 ) ;
2021-03-16 00:42:25 -04:00
int bch2_subvolume_create ( struct btree_trans * , u64 , u32 ,
u32 * , u32 * , bool ) ;
int bch2_fs_subvolumes_init ( struct bch_fs * ) ;
# endif /* _BCACHEFS_SUBVOLUME_H */