2018-11-01 15:13:19 -04:00
/* SPDX-License-Identifier: GPL-2.0 */
# ifndef _BCACHEFS_EC_H
# define _BCACHEFS_EC_H
# include "ec_types.h"
2020-07-09 18:31:51 -04:00
# include "buckets_types.h"
2018-11-01 15:13:19 -04:00
# include "keylist_types.h"
2018-11-01 15:10:01 -04: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 15:13:19 -04:00
struct bkey_s_c ) ;
2018-11-01 15:10:01 -04:00
# define bch2_bkey_ops_stripe (struct bkey_ops) { \
. key_invalid = bch2_stripe_invalid , \
. val_to_text = bch2_stripe_to_text , \
2020-02-06 20:15:15 -05:00
. swab = bch2_ptr_swab , \
2018-11-01 15:13:19 -04:00
}
2018-11-25 20:53:51 -05: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 ,
2021-01-11 13:51:23 -05:00
unsigned block , unsigned csum_idx )
2018-11-25 20:53:51 -05:00
{
2021-01-11 13:51:23 -05:00
EBUG_ON ( block > = s - > nr_blocks ) ;
EBUG_ON ( csum_idx > = stripe_csums_per_device ( s ) ) ;
return ( void * ) s + stripe_csum_offset ( s , block , csum_idx ) ;
}
static inline struct bch_csum stripe_csum_get ( struct bch_stripe * s ,
unsigned block , unsigned csum_idx )
{
struct bch_csum csum = { 0 } ;
memcpy ( & csum , stripe_csum ( s , block , csum_idx ) , bch_crc_bytes [ s - > csum_type ] ) ;
return csum ;
}
static inline void stripe_csum_set ( struct bch_stripe * s ,
unsigned block , unsigned csum_idx ,
struct bch_csum csum )
{
memcpy ( stripe_csum ( s , block , csum_idx ) , & csum , bch_crc_bytes [ s - > csum_type ] ) ;
}
2021-03-12 16:55:28 -05:00
static inline bool __bch2_ptr_matches_stripe ( const struct bch_extent_ptr * stripe_ptr ,
const struct bch_extent_ptr * data_ptr ,
unsigned sectors )
{
return data_ptr - > dev = = stripe_ptr - > dev & &
data_ptr - > gen = = stripe_ptr - > gen & &
data_ptr - > offset > = stripe_ptr - > offset & &
data_ptr - > offset < stripe_ptr - > offset + sectors ;
}
static inline bool bch2_ptr_matches_stripe ( const struct bch_stripe * s ,
struct extent_ptr_decoded p )
2021-01-11 13:51:23 -05:00
{
unsigned nr_data = s - > nr_blocks - s - > nr_redundant ;
2021-03-12 16:55:28 -05:00
BUG_ON ( ! p . has_ec ) ;
if ( p . ec . block > = nr_data )
2021-01-11 13:51:23 -05:00
return false ;
2021-03-12 16:55:28 -05:00
return __bch2_ptr_matches_stripe ( & s - > ptrs [ p . ec . block ] , & p . ptr ,
le16_to_cpu ( s - > sectors ) ) ;
2021-01-11 13:51:23 -05:00
}
2021-03-12 16:55:28 -05:00
static inline bool bch2_ptr_matches_stripe_m ( const struct stripe * m ,
struct extent_ptr_decoded p )
2021-01-11 13:51:23 -05:00
{
2021-03-12 16:55:28 -05:00
unsigned nr_data = m - > nr_blocks - m - > nr_redundant ;
2021-01-11 13:51:23 -05:00
BUG_ON ( ! p . has_ec ) ;
2021-03-12 16:55:28 -05:00
if ( p . ec . block > = nr_data )
return false ;
return __bch2_ptr_matches_stripe ( & m - > ptrs [ p . ec . block ] , & p . ptr ,
m - > sectors ) ;
2018-11-25 20:53:51 -05:00
}
2018-11-01 15:13:19 -04:00
struct bch_read_bio ;
struct ec_stripe_buf {
/* might not be buffering the entire stripe: */
unsigned offset ;
unsigned size ;
2020-12-16 14:23:27 -05:00
unsigned long valid [ BITS_TO_LONGS ( BCH_BKEY_PTRS_MAX ) ] ;
2018-11-01 15:13:19 -04:00
2020-12-16 14:23:27 -05:00
void * data [ BCH_BKEY_PTRS_MAX ] ;
2018-11-01 15:13:19 -04:00
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 ;
2020-12-14 19:41:03 -05:00
struct closure iodone ;
2018-11-01 15:13:19 -04:00
/* counts in flight writes, stripe is created when pin == 0 */
atomic_t pin ;
int err ;
2020-07-06 22:33:54 -04:00
u8 nr_data ;
u8 nr_parity ;
bool allocated ;
bool pending ;
2020-12-14 19:41:03 -05:00
bool have_existing_stripe ;
2020-06-30 14:44:19 -04:00
2021-01-18 23:26:42 -05:00
unsigned long blocks_gotten [ BITS_TO_LONGS ( BCH_BKEY_PTRS_MAX ) ] ;
2020-12-16 14:23:27 -05:00
unsigned long blocks_allocated [ BITS_TO_LONGS ( BCH_BKEY_PTRS_MAX ) ] ;
2021-01-18 23:26:42 -05:00
open_bucket_idx_t blocks [ BCH_BKEY_PTRS_MAX ] ;
2020-07-09 18:31:51 -04:00
struct disk_reservation res ;
2018-11-01 15:13:19 -04:00
struct keylist keys ;
u64 inline_keys [ BKEY_U64s * 8 ] ;
2020-12-14 19:41:03 -05:00
struct ec_stripe_buf new_stripe ;
struct ec_stripe_buf existing_stripe ;
2018-11-01 15:13:19 -04:00
} ;
struct ec_stripe_head {
struct list_head list ;
struct mutex lock ;
unsigned target ;
unsigned algo ;
unsigned redundancy ;
2020-12-15 12:53:30 -05:00
bool copygc ;
2018-11-01 15:13:19 -04:00
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 * ) ;
2021-10-29 16:29:13 -04:00
void bch2_ob_add_backpointer ( struct bch_fs * , struct open_bucket * ,
struct bkey * ) ;
2018-11-01 15:13:19 -04:00
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-06 20:59:46 -04:00
void bch2_ec_stripe_head_put ( struct bch_fs * , struct ec_stripe_head * ) ;
2020-12-15 12:38:17 -05:00
struct ec_stripe_head * bch2_ec_stripe_head_get ( struct bch_fs * ,
2020-12-15 12:53:30 -05:00
unsigned , unsigned , unsigned , bool , struct closure * ) ;
2018-11-01 15:13:19 -04:00
2018-11-24 17:09:44 -05: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 15:13:19 -04:00
void bch2_ec_stop_dev ( struct bch_fs * , struct bch_dev * ) ;
void bch2_ec_flush_new_stripes ( struct bch_fs * ) ;
2021-01-14 16:19:23 -05:00
void bch2_stripes_heap_start ( struct bch_fs * ) ;
2021-04-29 15:37:47 -04:00
int bch2_stripes_read ( struct bch_fs * ) ;
2020-10-16 21:36:26 -04:00
int bch2_stripes_write ( struct bch_fs * , unsigned ) ;
2018-11-25 20:53:51 -05:00
2018-11-24 17:09:44 -05:00
int bch2_ec_mem_alloc ( struct bch_fs * , bool ) ;
2020-07-06 20:18:13 -04:00
void bch2_stripes_heap_to_text ( struct printbuf * , struct bch_fs * ) ;
2020-07-25 17:06:11 -04:00
void bch2_new_stripes_to_text ( struct printbuf * , struct bch_fs * ) ;
2020-07-06 20:18:13 -04:00
2018-11-01 15:13:19 -04:00
void bch2_fs_ec_exit ( struct bch_fs * ) ;
int bch2_fs_ec_init ( struct bch_fs * ) ;
# endif /* _BCACHEFS_EC_H */