@@ -407,13 +407,17 @@ static inline bool bkey_and_val_eq(struct bkey_s_c l, struct bkey_s_c r)
407
407
!memcmp (l .v , r .v , bkey_val_bytes (l .k ));
408
408
}
409
409
410
+ struct extents_to_bp_state {
411
+ struct bpos bucket_start ;
412
+ struct bpos bucket_end ;
413
+ struct bkey_buf last_flushed ;
414
+ };
415
+
410
416
static int check_bp_exists (struct btree_trans * trans ,
417
+ struct extents_to_bp_state * s ,
411
418
struct bpos bucket ,
412
419
struct bch_backpointer bp ,
413
- struct bkey_s_c orig_k ,
414
- struct bpos bucket_start ,
415
- struct bpos bucket_end ,
416
- struct bkey_buf * last_flushed )
420
+ struct bkey_s_c orig_k )
417
421
{
418
422
struct bch_fs * c = trans -> c ;
419
423
struct btree_iter bp_iter = { NULL };
@@ -424,8 +428,8 @@ static int check_bp_exists(struct btree_trans *trans,
424
428
425
429
bch2_bkey_buf_init (& tmp );
426
430
427
- if (bpos_lt (bucket , bucket_start ) ||
428
- bpos_gt (bucket , bucket_end ))
431
+ if (bpos_lt (bucket , s -> bucket_start ) ||
432
+ bpos_gt (bucket , s -> bucket_end ))
429
433
return 0 ;
430
434
431
435
if (!bch2_dev_bucket_exists (c , bucket ))
@@ -440,9 +444,9 @@ static int check_bp_exists(struct btree_trans *trans,
440
444
441
445
if (bp_k .k -> type != KEY_TYPE_backpointer ||
442
446
memcmp (bkey_s_c_to_backpointer (bp_k ).v , & bp , sizeof (bp ))) {
443
- if (!bkey_and_val_eq (orig_k , bkey_i_to_s_c (last_flushed -> k ))) {
444
- bch2_bkey_buf_reassemble (& tmp , c , orig_k );
447
+ bch2_bkey_buf_reassemble (& tmp , c , orig_k );
445
448
449
+ if (!bkey_and_val_eq (orig_k , bkey_i_to_s_c (s -> last_flushed .k ))) {
446
450
if (bp .level ) {
447
451
bch2_trans_unlock (trans );
448
452
bch2_btree_interior_updates_flush (c );
@@ -452,7 +456,7 @@ static int check_bp_exists(struct btree_trans *trans,
452
456
if (ret )
453
457
goto err ;
454
458
455
- bch2_bkey_buf_copy (last_flushed , c , tmp .k );
459
+ bch2_bkey_buf_copy (& s -> last_flushed , c , tmp .k );
456
460
ret = - BCH_ERR_transaction_restart_write_buffer_flush ;
457
461
goto out ;
458
462
}
@@ -480,10 +484,8 @@ static int check_bp_exists(struct btree_trans *trans,
480
484
}
481
485
482
486
static int check_extent_to_backpointers (struct btree_trans * trans ,
487
+ struct extents_to_bp_state * s ,
483
488
enum btree_id btree , unsigned level ,
484
- struct bpos bucket_start ,
485
- struct bpos bucket_end ,
486
- struct bkey_buf * last_flushed ,
487
489
struct bkey_s_c k )
488
490
{
489
491
struct bch_fs * c = trans -> c ;
@@ -503,9 +505,7 @@ static int check_extent_to_backpointers(struct btree_trans *trans,
503
505
bch2_extent_ptr_to_bp (c , btree , level ,
504
506
k , p , & bucket_pos , & bp );
505
507
506
- ret = check_bp_exists (trans , bucket_pos , bp , k ,
507
- bucket_start , bucket_end ,
508
- last_flushed );
508
+ ret = check_bp_exists (trans , s , bucket_pos , bp , k );
509
509
if (ret )
510
510
return ret ;
511
511
}
@@ -514,10 +514,8 @@ static int check_extent_to_backpointers(struct btree_trans *trans,
514
514
}
515
515
516
516
static int check_btree_root_to_backpointers (struct btree_trans * trans ,
517
+ struct extents_to_bp_state * s ,
517
518
enum btree_id btree_id ,
518
- struct bpos bucket_start ,
519
- struct bpos bucket_end ,
520
- struct bkey_buf * last_flushed ,
521
519
int * level )
522
520
{
523
521
struct bch_fs * c = trans -> c ;
@@ -541,9 +539,7 @@ static int check_btree_root_to_backpointers(struct btree_trans *trans,
541
539
* level = b -> c .level ;
542
540
543
541
k = bkey_i_to_s_c (& b -> key );
544
- ret = check_extent_to_backpointers (trans , btree_id , b -> c .level + 1 ,
545
- bucket_start , bucket_end ,
546
- last_flushed , k );
542
+ ret = check_extent_to_backpointers (trans , s , btree_id , b -> c .level + 1 , k );
547
543
err :
548
544
bch2_trans_iter_exit (trans , & iter );
549
545
return ret ;
@@ -615,43 +611,35 @@ static int bch2_get_btree_in_memory_pos(struct btree_trans *trans,
615
611
}
616
612
617
613
static int bch2_check_extents_to_backpointers_pass (struct btree_trans * trans ,
618
- struct bpos bucket_start ,
619
- struct bpos bucket_end )
614
+ struct extents_to_bp_state * s )
620
615
{
621
616
struct bch_fs * c = trans -> c ;
622
- struct btree_iter iter ;
623
- enum btree_id btree_id ;
624
- struct bkey_s_c k ;
625
- struct bkey_buf last_flushed ;
626
617
int ret = 0 ;
627
618
628
- bch2_bkey_buf_init (& last_flushed );
629
- bkey_init (& last_flushed .k -> k );
630
-
631
- for (btree_id = 0 ; btree_id < btree_id_nr_alive (c ); btree_id ++ ) {
619
+ for (enum btree_id btree_id = 0 ;
620
+ btree_id < btree_id_nr_alive (c );
621
+ btree_id ++ ) {
632
622
int level , depth = btree_type_has_ptrs (btree_id ) ? 0 : 1 ;
633
623
634
624
ret = commit_do (trans , NULL , NULL ,
635
625
BCH_TRANS_COMMIT_no_enospc ,
636
- check_btree_root_to_backpointers (trans , btree_id ,
637
- bucket_start , bucket_end ,
638
- & last_flushed , & level ));
626
+ check_btree_root_to_backpointers (trans , s , btree_id , & level ));
639
627
if (ret )
640
628
return ret ;
641
629
642
630
while (level >= depth ) {
631
+ struct btree_iter iter ;
643
632
bch2_trans_node_iter_init (trans , & iter , btree_id , POS_MIN , 0 ,
644
633
level ,
645
634
BTREE_ITER_PREFETCH );
646
635
while (1 ) {
647
636
bch2_trans_begin (trans );
648
- k = bch2_btree_iter_peek (& iter );
637
+
638
+ struct bkey_s_c k = bch2_btree_iter_peek (& iter );
649
639
if (!k .k )
650
640
break ;
651
641
ret = bkey_err (k ) ?:
652
- check_extent_to_backpointers (trans , btree_id , level ,
653
- bucket_start , bucket_end ,
654
- & last_flushed , k ) ?:
642
+ check_extent_to_backpointers (trans , s , btree_id , level , k ) ?:
655
643
bch2_trans_commit (trans , NULL , NULL ,
656
644
BCH_TRANS_COMMIT_no_enospc );
657
645
if (bch2_err_matches (ret , BCH_ERR_transaction_restart )) {
@@ -673,7 +661,6 @@ static int bch2_check_extents_to_backpointers_pass(struct btree_trans *trans,
673
661
}
674
662
}
675
663
676
- bch2_bkey_buf_exit (& last_flushed , c );
677
664
return 0 ;
678
665
}
679
666
@@ -736,37 +723,43 @@ static int bch2_get_alloc_in_memory_pos(struct btree_trans *trans,
736
723
int bch2_check_extents_to_backpointers (struct bch_fs * c )
737
724
{
738
725
struct btree_trans * trans = bch2_trans_get (c );
739
- struct bpos start = POS_MIN , end ;
726
+ struct extents_to_bp_state s = { . bucket_start = POS_MIN } ;
740
727
int ret ;
741
728
729
+ bch2_bkey_buf_init (& s .last_flushed );
730
+ bkey_init (& s .last_flushed .k -> k );
731
+
742
732
while (1 ) {
743
- ret = bch2_get_alloc_in_memory_pos (trans , start , & end );
733
+ ret = bch2_get_alloc_in_memory_pos (trans , s . bucket_start , & s . bucket_end );
744
734
if (ret )
745
735
break ;
746
736
747
- if (bpos_eq (start , POS_MIN ) && !bpos_eq (end , SPOS_MAX ))
737
+ if ( bpos_eq (s .bucket_start , POS_MIN ) &&
738
+ !bpos_eq (s .bucket_end , SPOS_MAX ))
748
739
bch_verbose (c , "%s(): alloc info does not fit in ram, running in multiple passes with %zu nodes per pass" ,
749
740
__func__ , btree_nodes_fit_in_ram (c ));
750
741
751
- if (!bpos_eq (start , POS_MIN ) || !bpos_eq (end , SPOS_MAX )) {
742
+ if (!bpos_eq (s .bucket_start , POS_MIN ) ||
743
+ !bpos_eq (s .bucket_end , SPOS_MAX )) {
752
744
struct printbuf buf = PRINTBUF ;
753
745
754
746
prt_str (& buf , "check_extents_to_backpointers(): " );
755
- bch2_bpos_to_text (& buf , start );
747
+ bch2_bpos_to_text (& buf , s . bucket_start );
756
748
prt_str (& buf , "-" );
757
- bch2_bpos_to_text (& buf , end );
749
+ bch2_bpos_to_text (& buf , s . bucket_end );
758
750
759
751
bch_verbose (c , "%s" , buf .buf );
760
752
printbuf_exit (& buf );
761
753
}
762
754
763
- ret = bch2_check_extents_to_backpointers_pass (trans , start , end );
764
- if (ret || bpos_eq (end , SPOS_MAX ))
755
+ ret = bch2_check_extents_to_backpointers_pass (trans , & s );
756
+ if (ret || bpos_eq (s . bucket_end , SPOS_MAX ))
765
757
break ;
766
758
767
- start = bpos_successor (end );
759
+ s . bucket_start = bpos_successor (s . bucket_end );
768
760
}
769
761
bch2_trans_put (trans );
762
+ bch2_bkey_buf_exit (& s .last_flushed , c );
770
763
771
764
bch_err_fn (c , ret );
772
765
return ret ;
0 commit comments