@@ -22,7 +22,9 @@ struct find_btree_nodes_worker {
22
22
23
23
static void found_btree_node_to_text (struct printbuf * out , struct bch_fs * c , const struct found_btree_node * n )
24
24
{
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 );
26
28
bch2_bpos_to_text (out , n -> min_key );
27
29
prt_str (out , "-" );
28
30
bch2_bpos_to_text (out , n -> max_key );
@@ -63,19 +65,37 @@ static void found_btree_node_to_key(struct bkey_i *k, const struct found_btree_n
63
65
memcpy (bp -> v .start , f -> ptrs , sizeof (struct bch_extent_ptr ) * f -> nr_ptrs );
64
66
}
65
67
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
+
66
78
static bool found_btree_node_is_readable (struct btree_trans * trans ,
67
79
struct found_btree_node * f )
68
80
{
69
- struct { __BKEY_PADDED (k , BKEY_BTREE_PTR_VAL_U64s_MAX ); } k ;
81
+ struct { __BKEY_PADDED (k , BKEY_BTREE_PTR_VAL_U64s_MAX ); } tmp ;
70
82
71
- found_btree_node_to_key (& k .k , f );
83
+ found_btree_node_to_key (& tmp .k , f );
72
84
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);
74
86
bool ret = !IS_ERR_OR_NULL (b );
75
87
if (!ret )
76
88
return ret ;
77
89
78
90
f -> sectors_written = b -> written ;
91
+ 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
+
79
99
six_unlock_read (& b -> c .lock );
80
100
81
101
/*
@@ -84,7 +104,7 @@ static bool found_btree_node_is_readable(struct btree_trans *trans,
84
104
* this node
85
105
*/
86
106
if (b != btree_node_root (trans -> c , b ))
87
- bch2_btree_node_evict (trans , & k .k );
107
+ bch2_btree_node_evict (trans , & tmp .k );
88
108
return ret ;
89
109
}
90
110
@@ -105,7 +125,8 @@ static int found_btree_node_cmp_cookie(const void *_l, const void *_r)
105
125
static int found_btree_node_cmp_time (const struct found_btree_node * l ,
106
126
const struct found_btree_node * r )
107
127
{
108
- return cmp_int (l -> seq , r -> seq );
128
+ return cmp_int (l -> seq , r -> seq ) ?:
129
+ cmp_int (l -> journal_seq , r -> journal_seq );
109
130
}
110
131
111
132
static int found_btree_node_cmp_pos (const void * _l , const void * _r )
@@ -309,15 +330,15 @@ static int handle_overwrites(struct bch_fs *c,
309
330
} else if (n -> level ) {
310
331
n -> overwritten = true;
311
332
} else {
312
- struct printbuf buf = PRINTBUF ;
313
-
314
- prt_str ( & buf , "overlapping btree nodes with same seq! halting\n " );
315
- found_btree_node_to_text ( & buf , c , start ) ;
316
- prt_str ( & buf , "\n " );
317
- found_btree_node_to_text ( & buf , c , n ) ;
318
- bch_err ( c , "%s" , buf . buf );
319
- printbuf_exit ( & buf ) ;
320
- 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
+ }
321
342
}
322
343
}
323
344
0 commit comments