mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 16:54:21 +00:00 
			
		
		
		
	bcachefs: Ensure btree node scan runs before checking for scanned nodes
Previously, calling bch2_btree_has_scanned_nodes() when btree node scan hadn't actually run would erroniously return false - causing us to think a btree was entirely gone. This fixes a 6.16 regression from moving the scheduling of btree node scan out of bch2_btree_lost_data() (fixing the bug where we'd schedule it persistently in the superblock) and only scheduling it when check_toploogy() is asking for scanned btree nodes. Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
		
							parent
							
								
									1dcea07810
								
							
						
					
					
						commit
						3e72acb78b
					
				
					 3 changed files with 24 additions and 13 deletions
				
			
		|  | @ -534,32 +534,39 @@ fsck_err: | |||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static int bch2_check_root(struct btree_trans *trans, enum btree_id i, | ||||
| static int bch2_check_root(struct btree_trans *trans, enum btree_id btree, | ||||
| 			   bool *reconstructed_root) | ||||
| { | ||||
| 	struct bch_fs *c = trans->c; | ||||
| 	struct btree_root *r = bch2_btree_id_root(c, i); | ||||
| 	struct btree_root *r = bch2_btree_id_root(c, btree); | ||||
| 	struct printbuf buf = PRINTBUF; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	bch2_btree_id_to_text(&buf, i); | ||||
| 	bch2_btree_id_to_text(&buf, btree); | ||||
| 
 | ||||
| 	if (r->error) { | ||||
| 		bch_info(c, "btree root %s unreadable, must recover from scan", buf.buf); | ||||
| 
 | ||||
| 		r->alive = false; | ||||
| 		r->error = 0; | ||||
| 		ret = bch2_btree_has_scanned_nodes(c, btree); | ||||
| 		if (ret < 0) | ||||
| 			goto err; | ||||
| 
 | ||||
| 		if (!bch2_btree_has_scanned_nodes(c, i)) { | ||||
| 		if (!ret) { | ||||
| 			__fsck_err(trans, | ||||
| 				   FSCK_CAN_FIX|(!btree_id_important(i) ? FSCK_AUTOFIX : 0), | ||||
| 				   FSCK_CAN_FIX|(!btree_id_important(btree) ? FSCK_AUTOFIX : 0), | ||||
| 				   btree_root_unreadable_and_scan_found_nothing, | ||||
| 				   "no nodes found for btree %s, continue?", buf.buf); | ||||
| 			bch2_btree_root_alloc_fake_trans(trans, i, 0); | ||||
| 
 | ||||
| 			r->alive = false; | ||||
| 			r->error = 0; | ||||
| 			bch2_btree_root_alloc_fake_trans(trans, btree, 0); | ||||
| 		} else { | ||||
| 			bch2_btree_root_alloc_fake_trans(trans, i, 1); | ||||
| 			bch2_shoot_down_journal_keys(c, i, 1, BTREE_MAX_DEPTH, POS_MIN, SPOS_MAX); | ||||
| 			ret = bch2_get_scanned_nodes(c, i, 0, POS_MIN, SPOS_MAX); | ||||
| 			r->alive = false; | ||||
| 			r->error = 0; | ||||
| 			bch2_btree_root_alloc_fake_trans(trans, btree, 1); | ||||
| 
 | ||||
| 			bch2_shoot_down_journal_keys(c, btree, 1, BTREE_MAX_DEPTH, POS_MIN, SPOS_MAX); | ||||
| 			ret = bch2_get_scanned_nodes(c, btree, 0, POS_MIN, SPOS_MAX); | ||||
| 			if (ret) | ||||
| 				goto err; | ||||
| 		} | ||||
|  |  | |||
|  | @ -521,8 +521,12 @@ bool bch2_btree_node_is_stale(struct bch_fs *c, struct btree *b) | |||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| bool bch2_btree_has_scanned_nodes(struct bch_fs *c, enum btree_id btree) | ||||
| int bch2_btree_has_scanned_nodes(struct bch_fs *c, enum btree_id btree) | ||||
| { | ||||
| 	int ret = bch2_run_print_explicit_recovery_pass(c, BCH_RECOVERY_PASS_scan_for_btree_nodes); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	struct found_btree_node search = { | ||||
| 		.btree_id	= btree, | ||||
| 		.level		= 0, | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
| 
 | ||||
| int bch2_scan_for_btree_nodes(struct bch_fs *); | ||||
| bool bch2_btree_node_is_stale(struct bch_fs *, struct btree *); | ||||
| bool bch2_btree_has_scanned_nodes(struct bch_fs *, enum btree_id); | ||||
| int bch2_btree_has_scanned_nodes(struct bch_fs *, enum btree_id); | ||||
| int bch2_get_scanned_nodes(struct bch_fs *, enum btree_id, unsigned, struct bpos, struct bpos); | ||||
| void bch2_find_btree_nodes_exit(struct find_btree_nodes *); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Kent Overstreet
						Kent Overstreet