2018-10-06 07:46:55 +03:00
/* SPDX-License-Identifier: GPL-2.0 */
# ifndef _BCACHEFS_ALLOC_FOREGROUND_H
# define _BCACHEFS_ALLOC_FOREGROUND_H
2017-03-17 09:18:50 +03:00
# include "bcachefs.h"
# include "alloc_types.h"
2022-11-25 02:03:55 +03:00
# include "extents.h"
# include "super.h"
2017-03-17 09:18:50 +03:00
2018-10-12 21:57:57 +03:00
# include <linux/hash.h>
2017-03-17 09:18:50 +03:00
struct bkey ;
struct bch_dev ;
struct bch_fs ;
struct bch_devs_List ;
2022-03-14 02:27:55 +03:00
extern const char * const bch2_alloc_reserves [ ] ;
2022-01-10 04:48:31 +03:00
void bch2_reset_alloc_cursors ( struct bch_fs * ) ;
2017-03-17 09:18:50 +03:00
struct dev_alloc_list {
unsigned nr ;
u8 devs [ BCH_SB_MEMBERS_MAX ] ;
} ;
2018-11-01 22:13:19 +03:00
struct dev_alloc_list bch2_dev_alloc_list ( struct bch_fs * ,
struct dev_stripe_state * ,
struct bch_devs_mask * ) ;
2020-07-22 20:27:00 +03:00
void bch2_dev_stripe_increment ( struct bch_dev * , struct dev_stripe_state * ) ;
2017-03-17 09:18:50 +03:00
long bch2_bucket_alloc_new_fs ( struct bch_dev * ) ;
2018-10-06 11:12:42 +03:00
struct open_bucket * bch2_bucket_alloc ( struct bch_fs * , struct bch_dev * ,
enum alloc_reserve , bool ,
struct closure * ) ;
2017-03-17 09:18:50 +03:00
2018-10-06 11:12:42 +03:00
static inline void ob_push ( struct bch_fs * c , struct open_buckets * obs ,
struct open_bucket * ob )
{
BUG_ON ( obs - > nr > = ARRAY_SIZE ( obs - > v ) ) ;
2017-03-17 09:18:50 +03:00
2018-10-06 11:12:42 +03:00
obs - > v [ obs - > nr + + ] = ob - c - > open_buckets ;
}
2017-03-17 09:18:50 +03:00
2018-10-06 11:12:42 +03:00
# define open_bucket_for_each(_c, _obs, _ob, _i) \
for ( ( _i ) = 0 ; \
( _i ) < ( _obs ) - > nr & & \
( ( _ob ) = ( _c ) - > open_buckets + ( _obs ) - > v [ _i ] , true ) ; \
( _i ) + + )
2017-03-17 09:18:50 +03:00
2018-11-01 22:13:19 +03:00
static inline struct open_bucket * ec_open_bucket ( struct bch_fs * c ,
struct open_buckets * obs )
{
struct open_bucket * ob ;
unsigned i ;
open_bucket_for_each ( c , obs , ob , i )
if ( ob - > ec )
return ob ;
return NULL ;
}
void bch2_open_bucket_write_error ( struct bch_fs * ,
struct open_buckets * , unsigned ) ;
2017-03-17 09:18:50 +03:00
void __bch2_open_bucket_put ( struct bch_fs * , struct open_bucket * ) ;
static inline void bch2_open_bucket_put ( struct bch_fs * c , struct open_bucket * ob )
{
if ( atomic_dec_and_test ( & ob - > pin ) )
__bch2_open_bucket_put ( c , ob ) ;
}
2018-10-06 11:12:42 +03:00
static inline void bch2_open_buckets_put ( struct bch_fs * c ,
struct open_buckets * ptrs )
2017-03-17 09:18:50 +03:00
{
2018-10-06 11:12:42 +03:00
struct open_bucket * ob ;
2017-03-17 09:18:50 +03:00
unsigned i ;
2018-10-06 11:12:42 +03:00
open_bucket_for_each ( c , ptrs , ob , i )
bch2_open_bucket_put ( c , ob ) ;
ptrs - > nr = 0 ;
2017-03-17 09:18:50 +03:00
}
2022-11-25 02:03:55 +03:00
static inline void bch2_alloc_sectors_done_inlined ( struct bch_fs * c , struct write_point * wp )
{
struct open_buckets ptrs = { . nr = 0 } , keep = { . nr = 0 } ;
struct open_bucket * ob ;
unsigned i ;
open_bucket_for_each ( c , & wp - > ptrs , ob , i )
ob_push ( c , ! ob - > sectors_free ? & ptrs : & keep , ob ) ;
wp - > ptrs = keep ;
mutex_unlock ( & wp - > lock ) ;
bch2_open_buckets_put ( c , & ptrs ) ;
}
2017-03-17 09:18:50 +03:00
static inline void bch2_open_bucket_get ( struct bch_fs * c ,
struct write_point * wp ,
2018-10-06 11:12:42 +03:00
struct open_buckets * ptrs )
2017-03-17 09:18:50 +03:00
{
struct open_bucket * ob ;
unsigned i ;
2018-10-06 11:12:42 +03:00
open_bucket_for_each ( c , & wp - > ptrs , ob , i ) {
2021-12-26 05:21:46 +03:00
ob - > data_type = wp - > data_type ;
2017-03-17 09:18:50 +03:00
atomic_inc ( & ob - > pin ) ;
2018-10-06 11:12:42 +03:00
ob_push ( c , ptrs , ob ) ;
2017-03-17 09:18:50 +03:00
}
}
2021-12-26 05:43:29 +03:00
static inline open_bucket_idx_t * open_bucket_hashslot ( struct bch_fs * c ,
unsigned dev , u64 bucket )
{
return c - > open_buckets_hash +
( jhash_3words ( dev , bucket , bucket > > 32 , 0 ) &
( OPEN_BUCKETS_COUNT - 1 ) ) ;
}
static inline bool bch2_bucket_is_open ( struct bch_fs * c , unsigned dev , u64 bucket )
{
open_bucket_idx_t slot = * open_bucket_hashslot ( c , dev , bucket ) ;
while ( slot ) {
struct open_bucket * ob = & c - > open_buckets [ slot ] ;
if ( ob - > dev = = dev & & ob - > bucket = = bucket )
return true ;
slot = ob - > hash ;
}
return false ;
}
2021-12-12 01:13:09 +03:00
static inline bool bch2_bucket_is_open_safe ( struct bch_fs * c , unsigned dev , u64 bucket )
{
bool ret ;
if ( bch2_bucket_is_open ( c , dev , bucket ) )
return true ;
spin_lock ( & c - > freelist_lock ) ;
ret = bch2_bucket_is_open ( c , dev , bucket ) ;
spin_unlock ( & c - > freelist_lock ) ;
return ret ;
}
2021-11-28 21:42:05 +03:00
int bch2_bucket_alloc_set ( struct bch_fs * , struct open_buckets * ,
2020-07-12 01:52:14 +03:00
struct dev_stripe_state * , struct bch_devs_mask * ,
unsigned , unsigned * , bool * , enum alloc_reserve ,
unsigned , struct closure * ) ;
2020-07-07 05:33:54 +03:00
2022-01-10 04:48:31 +03:00
int bch2_alloc_sectors_start_trans ( struct btree_trans * ,
unsigned , unsigned ,
struct write_point_specifier ,
struct bch_devs_list * ,
unsigned , unsigned ,
enum alloc_reserve ,
unsigned ,
struct closure * ,
struct write_point * * ) ;
2017-03-17 09:18:50 +03:00
2021-12-26 05:21:46 +03:00
struct bch_extent_ptr bch2_ob_ptr ( struct bch_fs * , struct open_bucket * ) ;
2022-11-25 02:03:55 +03:00
/*
* Append pointers to the space we just allocated to @ k , and mark @ sectors space
* as allocated out of @ ob
*/
static inline void
bch2_alloc_sectors_append_ptrs_inlined ( struct bch_fs * c , struct write_point * wp ,
struct bkey_i * k , unsigned sectors ,
bool cached )
{
struct open_bucket * ob ;
unsigned i ;
BUG_ON ( sectors > wp - > sectors_free ) ;
wp - > sectors_free - = sectors ;
wp - > sectors_allocated + = sectors ;
open_bucket_for_each ( c , & wp - > ptrs , ob , i ) {
struct bch_dev * ca = bch_dev_bkey_exists ( c , ob - > dev ) ;
struct bch_extent_ptr ptr = bch2_ob_ptr ( c , ob ) ;
ptr . cached = cached | |
( ! ca - > mi . durability & &
wp - > data_type = = BCH_DATA_user ) ;
bch2_bkey_append_ptr ( k , ptr ) ;
BUG_ON ( sectors > ob - > sectors_free ) ;
ob - > sectors_free - = sectors ;
}
}
2017-03-17 09:18:50 +03:00
void bch2_alloc_sectors_append_ptrs ( struct bch_fs * , struct write_point * ,
2021-12-26 05:14:49 +03:00
struct bkey_i * , unsigned , bool ) ;
2017-03-17 09:18:50 +03:00
void bch2_alloc_sectors_done ( struct bch_fs * , struct write_point * ) ;
2018-11-01 22:13:19 +03:00
void bch2_open_buckets_stop_dev ( struct bch_fs * , struct bch_dev * ,
2019-09-20 23:17:46 +03:00
struct open_buckets * ) ;
2018-11-01 22:13:19 +03:00
2018-10-06 07:46:55 +03:00
void bch2_writepoint_stop ( struct bch_fs * , struct bch_dev * ,
struct write_point * ) ;
2017-03-17 09:18:50 +03:00
static inline struct write_point_specifier writepoint_hashed ( unsigned long v )
{
return ( struct write_point_specifier ) { . v = v | 1 } ;
}
static inline struct write_point_specifier writepoint_ptr ( struct write_point * wp )
{
return ( struct write_point_specifier ) { . v = ( unsigned long ) wp } ;
}
2018-11-05 05:55:35 +03:00
void bch2_fs_allocator_foreground_init ( struct bch_fs * ) ;
2021-12-26 05:21:46 +03:00
void bch2_open_buckets_to_text ( struct printbuf * , struct bch_fs * ) ;
2022-10-31 23:13:05 +03:00
void bch2_write_points_to_text ( struct printbuf * , struct bch_fs * ) ;
2018-10-06 07:46:55 +03:00
# endif /* _BCACHEFS_ALLOC_FOREGROUND_H */