2019-08-16 09:59:56 -04:00
// SPDX-License-Identifier: GPL-2.0
# include "bcachefs.h"
2020-12-17 15:08:58 -05:00
# include "bkey_buf.h"
2019-08-16 09:59:56 -04:00
# include "btree_update.h"
2021-05-17 00:08:06 -04:00
# include "buckets.h"
2019-08-16 09:59:56 -04:00
# include "extents.h"
2019-10-10 12:47:22 -04:00
# include "inode.h"
2023-09-10 18:05:17 -04:00
# include "io_misc.h"
# include "io_write.h"
bcachefs: rebalance_work
This adds a new btree, rebalance_work, to eliminate scanning required
for finding extents that need work done on them in the background - i.e.
for the background_target and background_compression options.
rebalance_work is a bitset btree, where a KEY_TYPE_set corresponds to an
extent in the extents or reflink btree at the same pos.
A new extent field is added, bch_extent_rebalance, which indicates that
this extent has work that needs to be done in the background - and which
options to use. This allows per-inode options to be propagated to
indirect extents - at least in some circumstances. In this patch,
changing IO options on a file will not propagate the new options to
indirect extents pointed to by that file.
Updating (setting/clearing) the rebalance_work btree is done by the
extent trigger, which looks at the bch_extent_rebalance field.
Scanning is still requrired after changing IO path options - either just
for a given inode, or for the whole filesystem. We indicate that
scanning is required by adding a KEY_TYPE_cookie key to the
rebalance_work btree: the cookie counter is so that we can detect that
scanning is still required when an option has been flipped mid-way
through an existing scan.
Future possible work:
- Propagate options to indirect extents when being changed
- Add other IO path options - nr_replicas, ec, to rebalance_work so
they can be applied in the background when they change
- Add a counter, for bcachefs fs usage output, showing the pending
amount of rebalance work: we'll probably want to do this after the
disk space accounting rewrite (moving it to a new btree)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
2023-10-20 13:33:14 -04:00
# include "rebalance.h"
2019-08-16 09:59:56 -04:00
# include "reflink.h"
2021-03-16 00:28:17 -04:00
# include "subvolume.h"
2023-09-10 18:05:17 -04:00
# include "super-io.h"
2019-08-16 09:59:56 -04:00
# include <linux/sched/signal.h>
2020-10-24 19:51:34 -04:00
static inline unsigned bkey_type_to_indirect ( const struct bkey * k )
{
switch ( k - > type ) {
case KEY_TYPE_extent :
return KEY_TYPE_reflink_v ;
case KEY_TYPE_inline_data :
return KEY_TYPE_indirect_inline_data ;
default :
return 0 ;
}
}
2019-08-16 09:59:56 -04:00
/* reflink pointers */
2023-10-24 20:44:36 -04:00
int bch2_reflink_p_invalid ( struct bch_fs * c , struct bkey_s_c k ,
2023-07-06 21:16:10 -04:00
enum bkey_invalid_flags flags ,
struct printbuf * err )
2019-08-16 09:59:56 -04:00
{
struct bkey_s_c_reflink_p p = bkey_s_c_to_reflink_p ( k ) ;
2021-10-14 09:54:47 -04:00
if ( c - > sb . version > = bcachefs_metadata_version_reflink_p_fix & &
2022-04-03 17:50:01 -04:00
le64_to_cpu ( p . v - > idx ) < le32_to_cpu ( p . v - > front_pad ) ) {
2023-02-03 21:01:40 -05:00
prt_printf ( err , " idx < front_pad (%llu < %u) " ,
2022-04-03 17:50:01 -04:00
le64_to_cpu ( p . v - > idx ) , le32_to_cpu ( p . v - > front_pad ) ) ;
return - EINVAL ;
}
2021-10-14 09:54:47 -04:00
2022-04-03 17:50:01 -04:00
return 0 ;
2019-08-16 09:59:56 -04:00
}
void bch2_reflink_p_to_text ( struct printbuf * out , struct bch_fs * c ,
struct bkey_s_c k )
{
struct bkey_s_c_reflink_p p = bkey_s_c_to_reflink_p ( k ) ;
2023-02-03 21:01:40 -05:00
prt_printf ( out , " idx %llu front_pad %u back_pad %u " ,
2021-11-13 17:44:13 -05:00
le64_to_cpu ( p . v - > idx ) ,
le32_to_cpu ( p . v - > front_pad ) ,
le32_to_cpu ( p . v - > back_pad ) ) ;
2019-08-16 09:59:56 -04:00
}
2021-04-28 23:49:30 -04:00
bool bch2_reflink_p_merge ( struct bch_fs * c , struct bkey_s _l , struct bkey_s_c _r )
2019-08-16 09:59:56 -04:00
{
struct bkey_s_reflink_p l = bkey_s_to_reflink_p ( _l ) ;
2021-04-28 23:49:30 -04:00
struct bkey_s_c_reflink_p r = bkey_s_c_to_reflink_p ( _r ) ;
2019-08-16 09:59:56 -04:00
2021-04-28 23:49:30 -04:00
/*
* Disabled for now , the triggers code needs to be reworked for merging
* of reflink pointers to work :
*/
return false ;
2019-08-16 09:59:56 -04:00
2021-04-28 23:49:30 -04:00
if ( le64_to_cpu ( l . v - > idx ) + l . k - > size ! = le64_to_cpu ( r . v - > idx ) )
return false ;
2019-08-16 09:59:56 -04:00
bch2_key_resize ( l . k , l . k - > size + r . k - > size ) ;
2021-04-28 23:49:30 -04:00
return true ;
2019-08-16 09:59:56 -04:00
}
/* indirect extents */
2023-10-24 20:44:36 -04:00
int bch2_reflink_v_invalid ( struct bch_fs * c , struct bkey_s_c k ,
2023-07-06 21:16:10 -04:00
enum bkey_invalid_flags flags ,
struct printbuf * err )
2019-08-16 09:59:56 -04:00
{
2022-12-20 19:58:16 -05:00
return bch2_bkey_ptrs_invalid ( c , k , flags , err ) ;
2019-08-16 09:59:56 -04:00
}
void bch2_reflink_v_to_text ( struct printbuf * out , struct bch_fs * c ,
struct bkey_s_c k )
{
struct bkey_s_c_reflink_v r = bkey_s_c_to_reflink_v ( k ) ;
2023-02-03 21:01:40 -05:00
prt_printf ( out , " refcount: %llu " , le64_to_cpu ( r . v - > refcount ) ) ;
2019-08-16 09:59:56 -04:00
bch2_bkey_ptrs_to_text ( out , c , k ) ;
}
2023-09-12 18:41:22 -04:00
#if 0
Currently disabled , needs to be debugged :
2021-05-15 15:04:08 -04:00
bool bch2_reflink_v_merge ( struct bch_fs * c , struct bkey_s _l , struct bkey_s_c _r )
{
struct bkey_s_reflink_v l = bkey_s_to_reflink_v ( _l ) ;
struct bkey_s_c_reflink_v r = bkey_s_c_to_reflink_v ( _r ) ;
return l . v - > refcount = = r . v - > refcount & & bch2_extent_merge ( c , _l , _r ) ;
}
2023-09-12 18:41:22 -04:00
# endif
2021-05-15 15:04:08 -04:00
2023-06-22 20:18:12 -04:00
static inline void check_indirect_extent_deleting ( struct bkey_i * new , unsigned * flags )
{
if ( ( * flags & BTREE_TRIGGER_INSERT ) & & ! * bkey_refcount ( new ) ) {
new - > k . type = KEY_TYPE_deleted ;
new - > k . size = 0 ;
set_bkey_val_u64s ( & new - > k , 0 ) ; ;
* flags & = ~ BTREE_TRIGGER_INSERT ;
}
}
2022-03-31 00:03:37 -04:00
int bch2_trans_mark_reflink_v ( struct btree_trans * trans ,
2022-03-31 21:44:55 -04:00
enum btree_id btree_id , unsigned level ,
2022-03-31 00:03:37 -04:00
struct bkey_s_c old , struct bkey_i * new ,
unsigned flags )
{
2023-06-22 20:18:12 -04:00
check_indirect_extent_deleting ( new , & flags ) ;
2022-03-31 00:03:37 -04:00
2023-12-03 13:05:21 -05:00
if ( old . k - > type = = KEY_TYPE_reflink_v & &
new - > k . type = = KEY_TYPE_reflink_v & &
old . k - > u64s = = new - > k . u64s & &
! memcmp ( bkey_s_c_to_reflink_v ( old ) . v - > start ,
bkey_i_to_reflink_v ( new ) - > v . start ,
bkey_val_bytes ( & new - > k ) - 8 ) )
return 0 ;
2022-03-31 21:44:55 -04:00
return bch2_trans_mark_extent ( trans , btree_id , level , old , new , flags ) ;
2022-03-31 00:03:37 -04:00
}
2020-10-24 19:51:34 -04:00
/* indirect inline data */
2023-10-24 20:44:36 -04:00
int bch2_indirect_inline_data_invalid ( struct bch_fs * c , struct bkey_s_c k ,
2023-07-06 21:16:10 -04:00
enum bkey_invalid_flags flags ,
struct printbuf * err )
2020-10-24 19:51:34 -04:00
{
2022-04-03 17:50:01 -04:00
return 0 ;
2020-10-24 19:51:34 -04:00
}
void bch2_indirect_inline_data_to_text ( struct printbuf * out ,
2023-06-22 20:18:12 -04:00
struct bch_fs * c , struct bkey_s_c k )
2020-10-24 19:51:34 -04:00
{
struct bkey_s_c_indirect_inline_data d = bkey_s_c_to_indirect_inline_data ( k ) ;
unsigned datalen = bkey_inline_data_bytes ( k . k ) ;
2023-02-03 21:01:40 -05:00
prt_printf ( out , " refcount %llu datalen %u: %*phN " ,
2020-10-24 19:51:34 -04:00
le64_to_cpu ( d . v - > refcount ) , datalen ,
min ( datalen , 32U ) , d . v - > data ) ;
}
2022-03-31 00:03:37 -04:00
int bch2_trans_mark_indirect_inline_data ( struct btree_trans * trans ,
2022-03-31 21:44:55 -04:00
enum btree_id btree_id , unsigned level ,
2022-03-31 00:03:37 -04:00
struct bkey_s_c old , struct bkey_i * new ,
unsigned flags )
{
2023-06-22 20:18:12 -04:00
check_indirect_extent_deleting ( new , & flags ) ;
2022-03-31 00:03:37 -04:00
return 0 ;
}
2019-08-16 09:59:56 -04:00
static int bch2_make_extent_indirect ( struct btree_trans * trans ,
struct btree_iter * extent_iter ,
2020-10-24 19:51:34 -04:00
struct bkey_i * orig )
2019-08-16 09:59:56 -04:00
{
struct bch_fs * c = trans - > c ;
2021-08-30 15:18:31 -04:00
struct btree_iter reflink_iter = { NULL } ;
2019-08-16 09:59:56 -04:00
struct bkey_s_c k ;
2020-10-24 19:51:34 -04:00
struct bkey_i * r_v ;
2019-08-16 09:59:56 -04:00
struct bkey_i_reflink_p * r_p ;
2020-10-24 19:51:34 -04:00
__le64 * refcount ;
2019-08-16 09:59:56 -04:00
int ret ;
2020-10-24 19:51:34 -04:00
if ( orig - > k . type = = KEY_TYPE_inline_data )
bch2_check_set_feature ( c , BCH_FEATURE_reflink_inline_data ) ;
2023-05-25 23:37:06 -04:00
bch2_trans_iter_init ( trans , & reflink_iter , BTREE_ID_reflink , POS_MAX ,
BTREE_ITER_INTENT ) ;
k = bch2_btree_iter_peek_prev ( & reflink_iter ) ;
ret = bkey_err ( k ) ;
2019-08-16 09:59:56 -04:00
if ( ret )
goto err ;
2021-06-10 13:21:39 -04:00
r_v = bch2_trans_kmalloc ( trans , sizeof ( __le64 ) + bkey_bytes ( & orig - > k ) ) ;
2019-08-16 09:59:56 -04:00
ret = PTR_ERR_OR_ZERO ( r_v ) ;
if ( ret )
goto err ;
2020-10-24 19:51:34 -04:00
bkey_init ( & r_v - > k ) ;
r_v - > k . type = bkey_type_to_indirect ( & orig - > k ) ;
2021-08-30 15:18:31 -04:00
r_v - > k . p = reflink_iter . pos ;
2020-10-24 19:51:34 -04:00
bch2_key_resize ( & r_v - > k , orig - > k . size ) ;
r_v - > k . version = orig - > k . version ;
set_bkey_val_bytes ( & r_v - > k , sizeof ( __le64 ) + bkey_val_bytes ( & orig - > k ) ) ;
2019-08-16 09:59:56 -04:00
2021-05-23 02:31:33 -04:00
refcount = bkey_refcount ( r_v ) ;
2020-10-24 19:51:34 -04:00
* refcount = 0 ;
memcpy ( refcount + 1 , & orig - > v , bkey_val_bytes ( & orig - > k ) ) ;
2019-08-16 09:59:56 -04:00
2021-08-30 15:18:31 -04:00
ret = bch2_trans_update ( trans , & reflink_iter , r_v , 0 ) ;
2021-05-18 23:17:03 -04:00
if ( ret )
goto err ;
2019-08-16 09:59:56 -04:00
2021-10-18 11:32:06 -04:00
/*
* orig is in a bkey_buf which statically allocates 5 64 s for the val ,
* so we know it will be big enough :
*/
2020-10-24 19:51:34 -04:00
orig - > k . type = KEY_TYPE_reflink_p ;
r_p = bkey_i_to_reflink_p ( orig ) ;
2019-08-16 09:59:56 -04:00
set_bkey_val_bytes ( & r_p - > k , sizeof ( r_p - > v ) ) ;
2023-03-04 23:05:55 -05:00
/* FORTIFY_SOURCE is broken here, and doesn't provide unsafe_memset() */
# if !defined(__NO_FORTIFY) && defined(__OPTIMIZE__) && defined(CONFIG_FORTIFY_SOURCE)
__underlying_memset ( & r_p - > v , 0 , sizeof ( r_p - > v ) ) ;
# else
2021-10-18 11:32:06 -04:00
memset ( & r_p - > v , 0 , sizeof ( r_p - > v ) ) ;
2023-03-04 23:05:55 -05:00
# endif
2021-10-18 11:32:06 -04:00
2019-08-16 09:59:56 -04:00
r_p - > v . idx = cpu_to_le64 ( bkey_start_offset ( & r_v - > k ) ) ;
2021-11-29 16:36:50 -05:00
ret = bch2_trans_update ( trans , extent_iter , & r_p - > k_i ,
BTREE_UPDATE_INTERNAL_SNAPSHOT_NODE ) ;
2019-08-16 09:59:56 -04:00
err :
2021-08-30 15:18:31 -04:00
bch2_trans_iter_exit ( trans , & reflink_iter ) ;
2019-08-16 09:59:56 -04:00
return ret ;
}
static struct bkey_s_c get_next_src ( struct btree_iter * iter , struct bpos end )
{
2021-03-20 22:14:10 -04:00
struct bkey_s_c k ;
2019-10-04 20:40:47 -04:00
int ret ;
2019-08-16 09:59:56 -04:00
2022-11-13 18:59:01 -05:00
for_each_btree_key_upto_continue_norestart ( * iter , end , 0 , k , ret ) {
if ( bkey_extent_is_unwritten ( k ) )
continue ;
2020-10-24 19:51:34 -04:00
if ( bkey_extent_is_data ( k . k ) )
2021-03-20 22:14:10 -04:00
return k ;
2022-11-13 18:59:01 -05:00
}
2019-10-04 20:40:47 -04:00
2022-11-24 03:12:22 -05:00
if ( bkey_ge ( iter - > pos , end ) )
2021-07-24 19:50:40 -04:00
bch2_btree_iter_set_pos ( iter , end ) ;
return ret ? bkey_s_c_err ( ret ) : bkey_s_c_null ;
2019-08-16 09:59:56 -04:00
}
s64 bch2_remap_range ( struct bch_fs * c ,
2021-03-16 00:28:17 -04:00
subvol_inum dst_inum , u64 dst_offset ,
subvol_inum src_inum , u64 src_offset ,
2021-11-05 15:17:13 -04:00
u64 remap_sectors ,
2019-10-10 12:47:22 -04:00
u64 new_i_size , s64 * i_sectors_delta )
2019-08-16 09:59:56 -04:00
{
2023-09-12 17:16:02 -04:00
struct btree_trans * trans ;
2021-08-30 15:18:31 -04:00
struct btree_iter dst_iter , src_iter ;
2019-08-16 09:59:56 -04:00
struct bkey_s_c src_k ;
2020-12-17 15:08:58 -05:00
struct bkey_buf new_dst , new_src ;
2021-03-16 00:28:17 -04:00
struct bpos dst_start = POS ( dst_inum . inum , dst_offset ) ;
struct bpos src_start = POS ( src_inum . inum , src_offset ) ;
2019-08-16 09:59:56 -04:00
struct bpos dst_end = dst_start , src_end = src_start ;
bcachefs: rebalance_work
This adds a new btree, rebalance_work, to eliminate scanning required
for finding extents that need work done on them in the background - i.e.
for the background_target and background_compression options.
rebalance_work is a bitset btree, where a KEY_TYPE_set corresponds to an
extent in the extents or reflink btree at the same pos.
A new extent field is added, bch_extent_rebalance, which indicates that
this extent has work that needs to be done in the background - and which
options to use. This allows per-inode options to be propagated to
indirect extents - at least in some circumstances. In this patch,
changing IO options on a file will not propagate the new options to
indirect extents pointed to by that file.
Updating (setting/clearing) the rebalance_work btree is done by the
extent trigger, which looks at the bch_extent_rebalance field.
Scanning is still requrired after changing IO path options - either just
for a given inode, or for the whole filesystem. We indicate that
scanning is required by adding a KEY_TYPE_cookie key to the
rebalance_work btree: the cookie counter is so that we can detect that
scanning is still required when an option has been flipped mid-way
through an existing scan.
Future possible work:
- Propagate options to indirect extents when being changed
- Add other IO path options - nr_replicas, ec, to rebalance_work so
they can be applied in the background when they change
- Add a counter, for bcachefs fs usage output, showing the pending
amount of rebalance work: we'll probably want to do this after the
disk space accounting rewrite (moving it to a new btree)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
2023-10-20 13:33:14 -04:00
struct bch_io_opts opts ;
2021-03-20 22:14:10 -04:00
struct bpos src_want ;
bcachefs: rebalance_work
This adds a new btree, rebalance_work, to eliminate scanning required
for finding extents that need work done on them in the background - i.e.
for the background_target and background_compression options.
rebalance_work is a bitset btree, where a KEY_TYPE_set corresponds to an
extent in the extents or reflink btree at the same pos.
A new extent field is added, bch_extent_rebalance, which indicates that
this extent has work that needs to be done in the background - and which
options to use. This allows per-inode options to be propagated to
indirect extents - at least in some circumstances. In this patch,
changing IO options on a file will not propagate the new options to
indirect extents pointed to by that file.
Updating (setting/clearing) the rebalance_work btree is done by the
extent trigger, which looks at the bch_extent_rebalance field.
Scanning is still requrired after changing IO path options - either just
for a given inode, or for the whole filesystem. We indicate that
scanning is required by adding a KEY_TYPE_cookie key to the
rebalance_work btree: the cookie counter is so that we can detect that
scanning is still required when an option has been flipped mid-way
through an existing scan.
Future possible work:
- Propagate options to indirect extents when being changed
- Add other IO path options - nr_replicas, ec, to rebalance_work so
they can be applied in the background when they change
- Add a counter, for bcachefs fs usage output, showing the pending
amount of rebalance work: we'll probably want to do this after the
disk space accounting rewrite (moving it to a new btree)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
2023-10-20 13:33:14 -04:00
u64 dst_done = 0 ;
2021-03-12 20:30:39 -05:00
u32 dst_snapshot , src_snapshot ;
2019-10-10 12:47:22 -04:00
int ret = 0 , ret2 = 0 ;
2019-08-16 09:59:56 -04:00
2023-02-09 12:21:45 -05:00
if ( ! bch2_write_ref_tryget ( c , BCH_WRITE_REF_reflink ) )
2022-12-11 20:37:11 -05:00
return - BCH_ERR_erofs_no_writes ;
2019-10-19 19:03:23 -04:00
2019-12-28 20:17:06 -05:00
bch2_check_set_feature ( c , BCH_FEATURE_reflink ) ;
2019-08-16 09:59:56 -04:00
dst_end . offset + = remap_sectors ;
src_end . offset + = remap_sectors ;
2020-12-17 15:08:58 -05:00
bch2_bkey_buf_init ( & new_dst ) ;
bch2_bkey_buf_init ( & new_src ) ;
2023-09-12 17:16:02 -04:00
trans = bch2_trans_get ( c ) ;
2019-08-16 09:59:56 -04:00
bcachefs: rebalance_work
This adds a new btree, rebalance_work, to eliminate scanning required
for finding extents that need work done on them in the background - i.e.
for the background_target and background_compression options.
rebalance_work is a bitset btree, where a KEY_TYPE_set corresponds to an
extent in the extents or reflink btree at the same pos.
A new extent field is added, bch_extent_rebalance, which indicates that
this extent has work that needs to be done in the background - and which
options to use. This allows per-inode options to be propagated to
indirect extents - at least in some circumstances. In this patch,
changing IO options on a file will not propagate the new options to
indirect extents pointed to by that file.
Updating (setting/clearing) the rebalance_work btree is done by the
extent trigger, which looks at the bch_extent_rebalance field.
Scanning is still requrired after changing IO path options - either just
for a given inode, or for the whole filesystem. We indicate that
scanning is required by adding a KEY_TYPE_cookie key to the
rebalance_work btree: the cookie counter is so that we can detect that
scanning is still required when an option has been flipped mid-way
through an existing scan.
Future possible work:
- Propagate options to indirect extents when being changed
- Add other IO path options - nr_replicas, ec, to rebalance_work so
they can be applied in the background when they change
- Add a counter, for bcachefs fs usage output, showing the pending
amount of rebalance work: we'll probably want to do this after the
disk space accounting rewrite (moving it to a new btree)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
2023-10-20 13:33:14 -04:00
ret = bch2_inum_opts_get ( trans , src_inum , & opts ) ;
if ( ret )
goto err ;
2023-09-12 17:16:02 -04:00
bch2_trans_iter_init ( trans , & src_iter , BTREE_ID_extents , src_start ,
2021-08-30 15:18:31 -04:00
BTREE_ITER_INTENT ) ;
2023-09-12 17:16:02 -04:00
bch2_trans_iter_init ( trans , & dst_iter , BTREE_ID_extents , dst_start ,
2021-08-30 15:18:31 -04:00
BTREE_ITER_INTENT ) ;
2019-08-16 09:59:56 -04:00
2022-07-17 23:06:38 -04:00
while ( ( ret = = 0 | |
bch2_err_matches ( ret , BCH_ERR_transaction_restart ) ) & &
2022-11-24 03:12:22 -05:00
bkey_lt ( dst_iter . pos , dst_end ) ) {
2021-05-17 00:08:06 -04:00
struct disk_reservation disk_res = { 0 } ;
2023-09-12 17:16:02 -04:00
bch2_trans_begin ( trans ) ;
2019-12-20 16:35:24 -05:00
2019-08-16 09:59:56 -04:00
if ( fatal_signal_pending ( current ) ) {
ret = - EINTR ;
2021-03-19 20:29:11 -04:00
break ;
2019-08-16 09:59:56 -04:00
}
2023-09-12 17:16:02 -04:00
ret = bch2_subvolume_get_snapshot ( trans , src_inum . subvol ,
2021-03-12 20:30:39 -05:00
& src_snapshot ) ;
2021-03-16 00:28:17 -04:00
if ( ret )
continue ;
2021-03-12 20:30:39 -05:00
bch2_btree_iter_set_snapshot ( & src_iter , src_snapshot ) ;
2023-09-12 17:16:02 -04:00
ret = bch2_subvolume_get_snapshot ( trans , dst_inum . subvol ,
2021-03-12 20:30:39 -05:00
& dst_snapshot ) ;
2021-03-16 00:28:17 -04:00
if ( ret )
continue ;
2021-03-12 20:30:39 -05:00
bch2_btree_iter_set_snapshot ( & dst_iter , dst_snapshot ) ;
2021-08-30 15:18:31 -04:00
dst_done = dst_iter . pos . offset - dst_start . offset ;
2021-03-20 22:14:10 -04:00
src_want = POS ( src_start . inode , src_start . offset + dst_done ) ;
2021-08-30 15:18:31 -04:00
bch2_btree_iter_set_pos ( & src_iter , src_want ) ;
2021-03-20 22:14:10 -04:00
2021-08-30 15:18:31 -04:00
src_k = get_next_src ( & src_iter , src_end ) ;
2019-08-16 09:59:56 -04:00
ret = bkey_err ( src_k ) ;
if ( ret )
2021-03-19 20:29:11 -04:00
continue ;
2019-08-16 09:59:56 -04:00
2022-11-24 03:12:22 -05:00
if ( bkey_lt ( src_want , src_iter . pos ) ) {
2023-09-12 17:16:02 -04:00
ret = bch2_fpunch_at ( trans , & dst_iter , dst_inum ,
2021-03-12 20:30:39 -05:00
min ( dst_end . offset ,
dst_iter . pos . offset +
src_iter . pos . offset - src_want . offset ) ,
2021-11-05 15:17:13 -04:00
i_sectors_delta ) ;
2019-08-16 09:59:56 -04:00
continue ;
}
2020-10-24 19:51:34 -04:00
if ( src_k . k - > type ! = KEY_TYPE_reflink_p ) {
2021-08-30 15:18:31 -04:00
bch2_btree_iter_set_pos_to_extent_start ( & src_iter ) ;
2021-06-14 18:16:10 -04:00
2020-12-17 15:08:58 -05:00
bch2_bkey_buf_reassemble ( & new_src , c , src_k ) ;
2019-11-09 16:01:15 -05:00
src_k = bkey_i_to_s_c ( new_src . k ) ;
2019-08-16 09:59:56 -04:00
2023-09-12 17:16:02 -04:00
ret = bch2_make_extent_indirect ( trans , & src_iter ,
2020-10-24 19:51:34 -04:00
new_src . k ) ;
2019-08-16 09:59:56 -04:00
if ( ret )
2021-03-19 20:29:11 -04:00
continue ;
2019-08-16 09:59:56 -04:00
BUG_ON ( src_k . k - > type ! = KEY_TYPE_reflink_p ) ;
}
if ( src_k . k - > type = = KEY_TYPE_reflink_p ) {
struct bkey_s_c_reflink_p src_p =
bkey_s_c_to_reflink_p ( src_k ) ;
struct bkey_i_reflink_p * dst_p =
2020-12-17 15:08:58 -05:00
bkey_reflink_p_init ( new_dst . k ) ;
2019-08-16 09:59:56 -04:00
u64 offset = le64_to_cpu ( src_p . v - > idx ) +
2021-03-20 22:14:10 -04:00
( src_want . offset -
2019-08-16 09:59:56 -04:00
bkey_start_offset ( src_k . k ) ) ;
dst_p - > v . idx = cpu_to_le64 ( offset ) ;
} else {
BUG ( ) ;
}
2021-08-30 15:18:31 -04:00
new_dst . k - > k . p = dst_iter . pos ;
2020-12-17 15:08:58 -05:00
bch2_key_resize ( & new_dst . k - > k ,
2021-03-20 22:14:10 -04:00
min ( src_k . k - > p . offset - src_want . offset ,
2021-08-30 15:18:31 -04:00
dst_end . offset - dst_iter . pos . offset ) ) ;
2021-03-12 20:30:39 -05:00
bcachefs: rebalance_work
This adds a new btree, rebalance_work, to eliminate scanning required
for finding extents that need work done on them in the background - i.e.
for the background_target and background_compression options.
rebalance_work is a bitset btree, where a KEY_TYPE_set corresponds to an
extent in the extents or reflink btree at the same pos.
A new extent field is added, bch_extent_rebalance, which indicates that
this extent has work that needs to be done in the background - and which
options to use. This allows per-inode options to be propagated to
indirect extents - at least in some circumstances. In this patch,
changing IO options on a file will not propagate the new options to
indirect extents pointed to by that file.
Updating (setting/clearing) the rebalance_work btree is done by the
extent trigger, which looks at the bch_extent_rebalance field.
Scanning is still requrired after changing IO path options - either just
for a given inode, or for the whole filesystem. We indicate that
scanning is required by adding a KEY_TYPE_cookie key to the
rebalance_work btree: the cookie counter is so that we can detect that
scanning is still required when an option has been flipped mid-way
through an existing scan.
Future possible work:
- Propagate options to indirect extents when being changed
- Add other IO path options - nr_replicas, ec, to rebalance_work so
they can be applied in the background when they change
- Add a counter, for bcachefs fs usage output, showing the pending
amount of rebalance work: we'll probably want to do this after the
disk space accounting rewrite (moving it to a new btree)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
2023-10-20 13:33:14 -04:00
ret = bch2_bkey_set_needs_rebalance ( c , new_dst . k ,
opts . background_target ,
opts . background_compression ) ? :
bch2_extent_update ( trans , dst_inum , & dst_iter ,
new_dst . k , & disk_res ,
new_i_size , i_sectors_delta ,
true ) ;
2021-05-17 00:08:06 -04:00
bch2_disk_reservation_put ( c , & disk_res ) ;
2019-08-16 09:59:56 -04:00
}
2023-09-12 17:16:02 -04:00
bch2_trans_iter_exit ( trans , & dst_iter ) ;
bch2_trans_iter_exit ( trans , & src_iter ) ;
2019-08-16 09:59:56 -04:00
2022-11-24 03:12:22 -05:00
BUG_ON ( ! ret & & ! bkey_eq ( dst_iter . pos , dst_end ) ) ;
BUG_ON ( bkey_gt ( dst_iter . pos , dst_end ) ) ;
2019-08-16 09:59:56 -04:00
2021-08-30 15:18:31 -04:00
dst_done = dst_iter . pos . offset - dst_start . offset ;
new_i_size = min ( dst_iter . pos . offset < < 9 , new_i_size ) ;
2019-08-16 09:59:56 -04:00
2019-10-10 12:47:22 -04:00
do {
struct bch_inode_unpacked inode_u ;
2021-08-30 15:18:31 -04:00
struct btree_iter inode_iter = { NULL } ;
2019-08-16 09:59:56 -04:00
2023-09-12 17:16:02 -04:00
bch2_trans_begin ( trans ) ;
2021-07-24 20:24:10 -04:00
2023-09-12 17:16:02 -04:00
ret2 = bch2_inode_peek ( trans , & inode_iter , & inode_u ,
2021-03-16 00:28:17 -04:00
dst_inum , BTREE_ITER_INTENT ) ;
2019-08-16 09:59:56 -04:00
2019-10-10 12:47:22 -04:00
if ( ! ret2 & &
2019-11-04 22:22:13 -05:00
inode_u . bi_size < new_i_size ) {
inode_u . bi_size = new_i_size ;
2023-09-12 17:16:02 -04:00
ret2 = bch2_inode_write ( trans , & inode_iter , & inode_u ) ? :
bch2_trans_commit ( trans , NULL , NULL ,
2021-11-09 17:20:06 -05:00
BTREE_INSERT_NOFAIL ) ;
2019-11-04 22:22:13 -05:00
}
2021-03-19 20:29:11 -04:00
2023-09-12 17:16:02 -04:00
bch2_trans_iter_exit ( trans , & inode_iter ) ;
2022-07-17 23:06:38 -04:00
} while ( bch2_err_matches ( ret2 , BCH_ERR_transaction_restart ) ) ;
bcachefs: rebalance_work
This adds a new btree, rebalance_work, to eliminate scanning required
for finding extents that need work done on them in the background - i.e.
for the background_target and background_compression options.
rebalance_work is a bitset btree, where a KEY_TYPE_set corresponds to an
extent in the extents or reflink btree at the same pos.
A new extent field is added, bch_extent_rebalance, which indicates that
this extent has work that needs to be done in the background - and which
options to use. This allows per-inode options to be propagated to
indirect extents - at least in some circumstances. In this patch,
changing IO options on a file will not propagate the new options to
indirect extents pointed to by that file.
Updating (setting/clearing) the rebalance_work btree is done by the
extent trigger, which looks at the bch_extent_rebalance field.
Scanning is still requrired after changing IO path options - either just
for a given inode, or for the whole filesystem. We indicate that
scanning is required by adding a KEY_TYPE_cookie key to the
rebalance_work btree: the cookie counter is so that we can detect that
scanning is still required when an option has been flipped mid-way
through an existing scan.
Future possible work:
- Propagate options to indirect extents when being changed
- Add other IO path options - nr_replicas, ec, to rebalance_work so
they can be applied in the background when they change
- Add a counter, for bcachefs fs usage output, showing the pending
amount of rebalance work: we'll probably want to do this after the
disk space accounting rewrite (moving it to a new btree)
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
2023-10-20 13:33:14 -04:00
err :
2023-09-12 17:16:02 -04:00
bch2_trans_put ( trans ) ;
2020-12-17 15:08:58 -05:00
bch2_bkey_buf_exit ( & new_src , c ) ;
bch2_bkey_buf_exit ( & new_dst , c ) ;
2019-10-10 12:47:22 -04:00
2023-02-09 12:21:45 -05:00
bch2_write_ref_put ( c , BCH_WRITE_REF_reflink ) ;
2019-10-19 19:03:23 -04:00
2019-10-10 12:47:22 -04:00
return dst_done ? : ret ? : ret2 ;
}