2018-11-01 22:13:19 +03:00
/* SPDX-License-Identifier: GPL-2.0 */
# ifndef _BCACHEFS_EC_H
# define _BCACHEFS_EC_H
# include "ec_types.h"
2020-07-10 01:31:51 +03:00
# include "buckets_types.h"
2018-11-01 22:13:19 +03:00
# include "keylist_types.h"
2018-11-01 22:10:01 +03:00
const char * bch2_stripe_invalid ( const struct bch_fs * , struct bkey_s_c ) ;
void bch2_stripe_to_text ( struct printbuf * , struct bch_fs * ,
2018-11-01 22:13:19 +03:00
struct bkey_s_c ) ;
2018-11-01 22:10:01 +03:00
# define bch2_bkey_ops_stripe (struct bkey_ops) { \
. key_invalid = bch2_stripe_invalid , \
. val_to_text = bch2_stripe_to_text , \
2020-02-07 04:15:15 +03:00
. swab = bch2_ptr_swab , \
2018-11-01 22:13:19 +03:00
}
2018-11-26 04:53:51 +03:00
static inline unsigned stripe_csums_per_device ( const struct bch_stripe * s )
{
return DIV_ROUND_UP ( le16_to_cpu ( s - > sectors ) ,
1 < < s - > csum_granularity_bits ) ;
}
static inline unsigned stripe_csum_offset ( const struct bch_stripe * s ,
unsigned dev , unsigned csum_idx )
{
unsigned csum_bytes = bch_crc_bytes [ s - > csum_type ] ;
return sizeof ( struct bch_stripe ) +
sizeof ( struct bch_extent_ptr ) * s - > nr_blocks +
( dev * stripe_csums_per_device ( s ) + csum_idx ) * csum_bytes ;
}
static inline unsigned stripe_blockcount_offset ( const struct bch_stripe * s ,
unsigned idx )
{
return stripe_csum_offset ( s , s - > nr_blocks , 0 ) +
sizeof ( u16 ) * idx ;
}
static inline unsigned stripe_blockcount_get ( const struct bch_stripe * s ,
unsigned idx )
{
return le16_to_cpup ( ( void * ) s + stripe_blockcount_offset ( s , idx ) ) ;
}
static inline void stripe_blockcount_set ( struct bch_stripe * s ,
unsigned idx , unsigned v )
{
__le16 * p = ( void * ) s + stripe_blockcount_offset ( s , idx ) ;
* p = cpu_to_le16 ( v ) ;
}
static inline unsigned stripe_val_u64s ( const struct bch_stripe * s )
{
return DIV_ROUND_UP ( stripe_blockcount_offset ( s , s - > nr_blocks ) ,
sizeof ( u64 ) ) ;
}
static inline void * stripe_csum ( struct bch_stripe * s ,
unsigned dev , unsigned csum_idx )
{
return ( void * ) s + stripe_csum_offset ( s , dev , csum_idx ) ;
}
2018-11-01 22:13:19 +03:00
struct bch_read_bio ;
struct ec_stripe_buf {
/* might not be buffering the entire stripe: */
unsigned offset ;
unsigned size ;
unsigned long valid [ BITS_TO_LONGS ( EC_STRIPE_MAX ) ] ;
void * data [ EC_STRIPE_MAX ] ;
union {
struct bkey_i_stripe key ;
u64 pad [ 255 ] ;
} ;
} ;
struct ec_stripe_head ;
struct ec_stripe_new {
struct bch_fs * c ;
struct ec_stripe_head * h ;
struct mutex lock ;
struct list_head list ;
/* counts in flight writes, stripe is created when pin == 0 */
atomic_t pin ;
int err ;
2020-07-07 05:33:54 +03:00
u8 nr_data ;
u8 nr_parity ;
bool allocated ;
bool pending ;
2020-06-30 21:44:19 +03:00
bool existing_stripe ;
u64 existing_stripe_idx ;
2018-11-01 22:13:19 +03:00
unsigned long blocks_allocated [ BITS_TO_LONGS ( EC_STRIPE_MAX ) ] ;
struct open_buckets blocks ;
2020-07-07 05:33:54 +03:00
u8 data_block_idx [ EC_STRIPE_MAX ] ;
2018-11-01 22:13:19 +03:00
struct open_buckets parity ;
2020-07-10 01:31:51 +03:00
struct disk_reservation res ;
2018-11-01 22:13:19 +03:00
struct keylist keys ;
u64 inline_keys [ BKEY_U64s * 8 ] ;
struct ec_stripe_buf stripe ;
} ;
struct ec_stripe_head {
struct list_head list ;
struct mutex lock ;
unsigned target ;
unsigned algo ;
unsigned redundancy ;
struct bch_devs_mask devs ;
unsigned nr_active_devs ;
unsigned blocksize ;
struct dev_stripe_state block_stripe ;
struct dev_stripe_state parity_stripe ;
struct ec_stripe_new * s ;
} ;
int bch2_ec_read_extent ( struct bch_fs * , struct bch_read_bio * ) ;
void * bch2_writepoint_ec_buf ( struct bch_fs * , struct write_point * ) ;
void bch2_ec_add_backpointer ( struct bch_fs * , struct write_point * ,
struct bpos , unsigned ) ;
void bch2_ec_bucket_written ( struct bch_fs * , struct open_bucket * ) ;
void bch2_ec_bucket_cancel ( struct bch_fs * , struct open_bucket * ) ;
int bch2_ec_stripe_new_alloc ( struct bch_fs * , struct ec_stripe_head * ) ;
2020-07-07 03:59:46 +03:00
void bch2_ec_stripe_head_put ( struct bch_fs * , struct ec_stripe_head * ) ;
2018-11-01 22:13:19 +03:00
struct ec_stripe_head * bch2_ec_stripe_head_get ( struct bch_fs * , unsigned ,
unsigned , unsigned ) ;
2018-11-25 01:09:44 +03:00
void bch2_stripes_heap_update ( struct bch_fs * , struct stripe * , size_t ) ;
void bch2_stripes_heap_del ( struct bch_fs * , struct stripe * , size_t ) ;
void bch2_stripes_heap_insert ( struct bch_fs * , struct stripe * , size_t ) ;
2018-11-01 22:13:19 +03:00
void bch2_ec_stop_dev ( struct bch_fs * , struct bch_dev * ) ;
void bch2_ec_flush_new_stripes ( struct bch_fs * ) ;
2019-04-12 05:39:39 +03:00
struct journal_keys ;
int bch2_stripes_read ( struct bch_fs * , struct journal_keys * ) ;
2020-10-17 04:36:26 +03:00
int bch2_stripes_write ( struct bch_fs * , unsigned ) ;
2018-11-26 04:53:51 +03:00
2018-11-25 01:09:44 +03:00
int bch2_ec_mem_alloc ( struct bch_fs * , bool ) ;
2020-07-07 03:18:13 +03:00
void bch2_stripes_heap_to_text ( struct printbuf * , struct bch_fs * ) ;
2020-07-26 00:06:11 +03:00
void bch2_new_stripes_to_text ( struct printbuf * , struct bch_fs * ) ;
2020-07-07 03:18:13 +03:00
2018-11-01 22:13:19 +03:00
void bch2_fs_ec_exit ( struct bch_fs * ) ;
int bch2_fs_ec_init ( struct bch_fs * ) ;
# endif /* _BCACHEFS_EC_H */