@@ -407,13 +407,17 @@ static inline bool bkey_and_val_eq(struct bkey_s_c l, struct bkey_s_c r)
407407 !memcmp (l .v , r .v , bkey_val_bytes (l .k ));
408408}
409409
410+ struct extents_to_bp_state {
411+ struct bpos bucket_start ;
412+ struct bpos bucket_end ;
413+ struct bkey_buf last_flushed ;
414+ };
415+
410416static int check_bp_exists (struct btree_trans * trans ,
417+ struct extents_to_bp_state * s ,
411418 struct bpos bucket ,
412419 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 )
417421{
418422 struct bch_fs * c = trans -> c ;
419423 struct btree_iter bp_iter = { NULL };
@@ -424,8 +428,8 @@ static int check_bp_exists(struct btree_trans *trans,
424428
425429 bch2_bkey_buf_init (& tmp );
426430
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 ))
429433 return 0 ;
430434
431435 if (!bch2_dev_bucket_exists (c , bucket ))
@@ -440,9 +444,9 @@ static int check_bp_exists(struct btree_trans *trans,
440444
441445 if (bp_k .k -> type != KEY_TYPE_backpointer ||
442446 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 );
445448
449+ if (!bkey_and_val_eq (orig_k , bkey_i_to_s_c (s -> last_flushed .k ))) {
446450 if (bp .level ) {
447451 bch2_trans_unlock (trans );
448452 bch2_btree_interior_updates_flush (c );
@@ -452,7 +456,7 @@ static int check_bp_exists(struct btree_trans *trans,
452456 if (ret )
453457 goto err ;
454458
455- bch2_bkey_buf_copy (last_flushed , c , tmp .k );
459+ bch2_bkey_buf_copy (& s -> last_flushed , c , tmp .k );
456460 ret = - BCH_ERR_transaction_restart_write_buffer_flush ;
457461 goto out ;
458462 }
@@ -480,10 +484,8 @@ static int check_bp_exists(struct btree_trans *trans,
480484}
481485
482486static int check_extent_to_backpointers (struct btree_trans * trans ,
487+ struct extents_to_bp_state * s ,
483488 enum btree_id btree , unsigned level ,
484- struct bpos bucket_start ,
485- struct bpos bucket_end ,
486- struct bkey_buf * last_flushed ,
487489 struct bkey_s_c k )
488490{
489491 struct bch_fs * c = trans -> c ;
@@ -503,9 +505,7 @@ static int check_extent_to_backpointers(struct btree_trans *trans,
503505 bch2_extent_ptr_to_bp (c , btree , level ,
504506 k , p , & bucket_pos , & bp );
505507
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 );
509509 if (ret )
510510 return ret ;
511511 }
@@ -514,10 +514,8 @@ static int check_extent_to_backpointers(struct btree_trans *trans,
514514}
515515
516516static int check_btree_root_to_backpointers (struct btree_trans * trans ,
517+ struct extents_to_bp_state * s ,
517518 enum btree_id btree_id ,
518- struct bpos bucket_start ,
519- struct bpos bucket_end ,
520- struct bkey_buf * last_flushed ,
521519 int * level )
522520{
523521 struct bch_fs * c = trans -> c ;
@@ -541,9 +539,7 @@ static int check_btree_root_to_backpointers(struct btree_trans *trans,
541539 * level = b -> c .level ;
542540
543541 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 );
547543err :
548544 bch2_trans_iter_exit (trans , & iter );
549545 return ret ;
@@ -615,43 +611,35 @@ static int bch2_get_btree_in_memory_pos(struct btree_trans *trans,
615611}
616612
617613static 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 )
620615{
621616 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 ;
626617 int ret = 0 ;
627618
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 ++ ) {
632622 int level , depth = btree_type_has_ptrs (btree_id ) ? 0 : 1 ;
633623
634624 ret = commit_do (trans , NULL , NULL ,
635625 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 ));
639627 if (ret )
640628 return ret ;
641629
642630 while (level >= depth ) {
631+ struct btree_iter iter ;
643632 bch2_trans_node_iter_init (trans , & iter , btree_id , POS_MIN , 0 ,
644633 level ,
645634 BTREE_ITER_PREFETCH );
646635 while (1 ) {
647636 bch2_trans_begin (trans );
648- k = bch2_btree_iter_peek (& iter );
637+
638+ struct bkey_s_c k = bch2_btree_iter_peek (& iter );
649639 if (!k .k )
650640 break ;
651641 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 ) ?:
655643 bch2_trans_commit (trans , NULL , NULL ,
656644 BCH_TRANS_COMMIT_no_enospc );
657645 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,
673661 }
674662 }
675663
676- bch2_bkey_buf_exit (& last_flushed , c );
677664 return 0 ;
678665}
679666
@@ -736,37 +723,43 @@ static int bch2_get_alloc_in_memory_pos(struct btree_trans *trans,
736723int bch2_check_extents_to_backpointers (struct bch_fs * c )
737724{
738725 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 } ;
740727 int ret ;
741728
729+ bch2_bkey_buf_init (& s .last_flushed );
730+ bkey_init (& s .last_flushed .k -> k );
731+
742732 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 );
744734 if (ret )
745735 break ;
746736
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 ))
748739 bch_verbose (c , "%s(): alloc info does not fit in ram, running in multiple passes with %zu nodes per pass" ,
749740 __func__ , btree_nodes_fit_in_ram (c ));
750741
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 )) {
752744 struct printbuf buf = PRINTBUF ;
753745
754746 prt_str (& buf , "check_extents_to_backpointers(): " );
755- bch2_bpos_to_text (& buf , start );
747+ bch2_bpos_to_text (& buf , s . bucket_start );
756748 prt_str (& buf , "-" );
757- bch2_bpos_to_text (& buf , end );
749+ bch2_bpos_to_text (& buf , s . bucket_end );
758750
759751 bch_verbose (c , "%s" , buf .buf );
760752 printbuf_exit (& buf );
761753 }
762754
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 ))
765757 break ;
766758
767- start = bpos_successor (end );
759+ s . bucket_start = bpos_successor (s . bucket_end );
768760 }
769761 bch2_trans_put (trans );
762+ bch2_bkey_buf_exit (& s .last_flushed , c );
770763
771764 bch_err_fn (c , ret );
772765 return ret ;
0 commit comments