@@ -22,7 +22,9 @@ struct find_btree_nodes_worker {
2222
2323static void found_btree_node_to_text (struct printbuf * out , struct bch_fs * c , const struct found_btree_node * n )
2424{
25- prt_printf (out , "%s l=%u seq=%u cookie=%llx " , bch2_btree_id_str (n -> btree_id ), n -> level , n -> seq , n -> cookie );
25+ prt_printf (out , "%s l=%u seq=%u journal_seq=%llu cookie=%llx " ,
26+ bch2_btree_id_str (n -> btree_id ), n -> level , n -> seq ,
27+ n -> journal_seq , n -> cookie );
2628 bch2_bpos_to_text (out , n -> min_key );
2729 prt_str (out , "-" );
2830 bch2_bpos_to_text (out , n -> max_key );
@@ -63,20 +65,37 @@ static void found_btree_node_to_key(struct bkey_i *k, const struct found_btree_n
6365 memcpy (bp -> v .start , f -> ptrs , sizeof (struct bch_extent_ptr ) * f -> nr_ptrs );
6466}
6567
68+ static inline u64 bkey_journal_seq (struct bkey_s_c k )
69+ {
70+ switch (k .k -> type ) {
71+ case KEY_TYPE_inode_v3 :
72+ return le64_to_cpu (bkey_s_c_to_inode_v3 (k ).v -> bi_journal_seq );
73+ default :
74+ return 0 ;
75+ }
76+ }
77+
6678static bool found_btree_node_is_readable (struct btree_trans * trans ,
6779 struct found_btree_node * f )
6880{
69- struct { __BKEY_PADDED (k , BKEY_BTREE_PTR_VAL_U64s_MAX ); } k ;
81+ struct { __BKEY_PADDED (k , BKEY_BTREE_PTR_VAL_U64s_MAX ); } tmp ;
7082
71- found_btree_node_to_key (& k .k , f );
83+ found_btree_node_to_key (& tmp .k , f );
7284
73- struct btree * b = bch2_btree_node_get_noiter (trans , & k .k , f -> btree_id , f -> level , false);
85+ struct btree * b = bch2_btree_node_get_noiter (trans , & tmp .k , f -> btree_id , f -> level , false);
7486 bool ret = !IS_ERR_OR_NULL (b );
7587 if (!ret )
7688 return ret ;
7789
7890 f -> sectors_written = b -> written ;
7991 f -> journal_seq = le64_to_cpu (b -> data -> keys .journal_seq );
92+
93+ struct bkey_s_c k ;
94+ struct bkey unpacked ;
95+ struct btree_node_iter iter ;
96+ for_each_btree_node_key_unpack (b , k , & iter , & unpacked )
97+ f -> journal_seq = max (f -> journal_seq , bkey_journal_seq (k ));
98+
8099 six_unlock_read (& b -> c .lock );
81100
82101 /*
@@ -85,7 +104,7 @@ static bool found_btree_node_is_readable(struct btree_trans *trans,
85104 * this node
86105 */
87106 if (b != btree_node_root (trans -> c , b ))
88- bch2_btree_node_evict (trans , & k .k );
107+ bch2_btree_node_evict (trans , & tmp .k );
89108 return ret ;
90109}
91110
@@ -107,7 +126,7 @@ static int found_btree_node_cmp_time(const struct found_btree_node *l,
107126 const struct found_btree_node * r )
108127{
109128 return cmp_int (l -> seq , r -> seq ) ?:
110- cmp_int (l -> journal_seq , r -> seq );
129+ cmp_int (l -> journal_seq , r -> journal_seq );
111130}
112131
113132static int found_btree_node_cmp_pos (const void * _l , const void * _r )
@@ -311,15 +330,15 @@ static int handle_overwrites(struct bch_fs *c,
311330 } else if (n -> level ) {
312331 n -> overwritten = true;
313332 } else {
314- struct printbuf buf = PRINTBUF ;
315-
316- prt_str ( & buf , "overlapping btree nodes with same seq! halting\n " );
317- found_btree_node_to_text ( & buf , c , start ) ;
318- prt_str ( & buf , "\n " );
319- found_btree_node_to_text ( & buf , c , n ) ;
320- bch_err ( c , "%s" , buf . buf );
321- printbuf_exit ( & buf ) ;
322- return - BCH_ERR_fsck_repair_unimplemented ;
333+ if ( bpos_cmp ( start -> max_key , n -> max_key ) >= 0 )
334+ n -> overwritten = true;
335+ else {
336+ n -> range_updated = true ;
337+ n -> min_key = bpos_successor ( start -> max_key );
338+ n -> range_updated = true ;
339+ bubble_up ( n , end );
340+ goto again ;
341+ }
323342 }
324343 }
325344
0 commit comments