@@ -427,13 +427,59 @@ static int btrfs_check_super_csum(struct btrfs_fs_info *fs_info,
427427 return ret ;
428428}
429429
430+ static int verify_level_key (struct btrfs_fs_info * fs_info ,
431+ struct extent_buffer * eb , int level ,
432+ struct btrfs_key * first_key )
433+ {
434+ int found_level ;
435+ struct btrfs_key found_key ;
436+ int ret ;
437+
438+ found_level = btrfs_header_level (eb );
439+ if (found_level != level ) {
440+ #ifdef CONFIG_BTRFS_DEBUG
441+ WARN_ON (1 );
442+ btrfs_err (fs_info ,
443+ "tree level mismatch detected, bytenr=%llu level expected=%u has=%u" ,
444+ eb -> start , level , found_level );
445+ #endif
446+ return - EIO ;
447+ }
448+
449+ if (!first_key )
450+ return 0 ;
451+
452+ if (found_level )
453+ btrfs_node_key_to_cpu (eb , & found_key , 0 );
454+ else
455+ btrfs_item_key_to_cpu (eb , & found_key , 0 );
456+ ret = btrfs_comp_cpu_keys (first_key , & found_key );
457+
458+ #ifdef CONFIG_BTRFS_DEBUG
459+ if (ret ) {
460+ WARN_ON (1 );
461+ btrfs_err (fs_info ,
462+ "tree first key mismatch detected, bytenr=%llu key expected=(%llu, %u, %llu) has=(%llu, %u, %llu)" ,
463+ eb -> start , first_key -> objectid , first_key -> type ,
464+ first_key -> offset , found_key .objectid ,
465+ found_key .type , found_key .offset );
466+ }
467+ #endif
468+ return ret ;
469+ }
470+
430471/*
431472 * helper to read a given tree block, doing retries as required when
432473 * the checksums don't match and we have alternate mirrors to try.
474+ *
475+ * @parent_transid: expected transid, skip check if 0
476+ * @level: expected level, mandatory check
477+ * @first_key: expected key of first slot, skip check if NULL
433478 */
434479static int btree_read_extent_buffer_pages (struct btrfs_fs_info * fs_info ,
435480 struct extent_buffer * eb ,
436- u64 parent_transid )
481+ u64 parent_transid , int level ,
482+ struct btrfs_key * first_key )
437483{
438484 struct extent_io_tree * io_tree ;
439485 int failed = 0 ;
@@ -448,19 +494,23 @@ static int btree_read_extent_buffer_pages(struct btrfs_fs_info *fs_info,
448494 ret = read_extent_buffer_pages (io_tree , eb , WAIT_COMPLETE ,
449495 mirror_num );
450496 if (!ret ) {
451- if (! verify_parent_transid (io_tree , eb ,
497+ if (verify_parent_transid (io_tree , eb ,
452498 parent_transid , 0 ))
453- break ;
454- else
455499 ret = - EIO ;
500+ else if (verify_level_key (fs_info , eb , level ,
501+ first_key ))
502+ ret = - EUCLEAN ;
503+ else
504+ break ;
456505 }
457506
458507 /*
459508 * This buffer's crc is fine, but its contents are corrupted, so
460509 * there is no reason to read the other copies, they won't be
461510 * any less wrong.
462511 */
463- if (test_bit (EXTENT_BUFFER_CORRUPT , & eb -> bflags ))
512+ if (test_bit (EXTENT_BUFFER_CORRUPT , & eb -> bflags ) ||
513+ ret == - EUCLEAN )
464514 break ;
465515
466516 num_copies = btrfs_num_copies (fs_info ,
@@ -1049,8 +1099,17 @@ void btrfs_wait_tree_block_writeback(struct extent_buffer *buf)
10491099 buf -> start , buf -> start + buf -> len - 1 );
10501100}
10511101
1102+ /*
1103+ * Read tree block at logical address @bytenr and do variant basic but critical
1104+ * verification.
1105+ *
1106+ * @parent_transid: expected transid of this tree block, skip check if 0
1107+ * @level: expected level, mandatory check
1108+ * @first_key: expected key in slot 0, skip check if NULL
1109+ */
10521110struct extent_buffer * read_tree_block (struct btrfs_fs_info * fs_info , u64 bytenr ,
1053- u64 parent_transid )
1111+ u64 parent_transid , int level ,
1112+ struct btrfs_key * first_key )
10541113{
10551114 struct extent_buffer * buf = NULL ;
10561115 int ret ;
@@ -1059,7 +1118,8 @@ struct extent_buffer *read_tree_block(struct btrfs_fs_info *fs_info, u64 bytenr,
10591118 if (IS_ERR (buf ))
10601119 return buf ;
10611120
1062- ret = btree_read_extent_buffer_pages (fs_info , buf , parent_transid );
1121+ ret = btree_read_extent_buffer_pages (fs_info , buf , parent_transid ,
1122+ level , first_key );
10631123 if (ret ) {
10641124 free_extent_buffer (buf );
10651125 return ERR_PTR (ret );
@@ -1388,6 +1448,7 @@ static struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
13881448 struct btrfs_path * path ;
13891449 u64 generation ;
13901450 int ret ;
1451+ int level ;
13911452
13921453 path = btrfs_alloc_path ();
13931454 if (!path )
@@ -1410,9 +1471,10 @@ static struct btrfs_root *btrfs_read_tree_root(struct btrfs_root *tree_root,
14101471 }
14111472
14121473 generation = btrfs_root_generation (& root -> root_item );
1474+ level = btrfs_root_level (& root -> root_item );
14131475 root -> node = read_tree_block (fs_info ,
14141476 btrfs_root_bytenr (& root -> root_item ),
1415- generation );
1477+ generation , level , NULL );
14161478 if (IS_ERR (root -> node )) {
14171479 ret = PTR_ERR (root -> node );
14181480 goto find_fail ;
@@ -2261,6 +2323,7 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info,
22612323 struct btrfs_root * log_tree_root ;
22622324 struct btrfs_super_block * disk_super = fs_info -> super_copy ;
22632325 u64 bytenr = btrfs_super_log_root (disk_super );
2326+ int level = btrfs_super_log_root_level (disk_super );
22642327
22652328 if (fs_devices -> rw_devices == 0 ) {
22662329 btrfs_warn (fs_info , "log replay required on RO media" );
@@ -2274,7 +2337,8 @@ static int btrfs_replay_log(struct btrfs_fs_info *fs_info,
22742337 __setup_root (log_tree_root , fs_info , BTRFS_TREE_LOG_OBJECTID );
22752338
22762339 log_tree_root -> node = read_tree_block (fs_info , bytenr ,
2277- fs_info -> generation + 1 );
2340+ fs_info -> generation + 1 ,
2341+ level , NULL );
22782342 if (IS_ERR (log_tree_root -> node )) {
22792343 btrfs_warn (fs_info , "failed to read log tree" );
22802344 ret = PTR_ERR (log_tree_root -> node );
@@ -2390,6 +2454,7 @@ int open_ctree(struct super_block *sb,
23902454 int num_backups_tried = 0 ;
23912455 int backup_index = 0 ;
23922456 int clear_free_space_tree = 0 ;
2457+ int level ;
23932458
23942459 tree_root = fs_info -> tree_root = btrfs_alloc_root (fs_info , GFP_KERNEL );
23952460 chunk_root = fs_info -> chunk_root = btrfs_alloc_root (fs_info , GFP_KERNEL );
@@ -2725,12 +2790,13 @@ int open_ctree(struct super_block *sb,
27252790 }
27262791
27272792 generation = btrfs_super_chunk_root_generation (disk_super );
2793+ level = btrfs_super_chunk_root_level (disk_super );
27282794
27292795 __setup_root (chunk_root , fs_info , BTRFS_CHUNK_TREE_OBJECTID );
27302796
27312797 chunk_root -> node = read_tree_block (fs_info ,
27322798 btrfs_super_chunk_root (disk_super ),
2733- generation );
2799+ generation , level , NULL );
27342800 if (IS_ERR (chunk_root -> node ) ||
27352801 !extent_buffer_uptodate (chunk_root -> node )) {
27362802 btrfs_err (fs_info , "failed to read chunk root" );
@@ -2764,10 +2830,11 @@ int open_ctree(struct super_block *sb,
27642830
27652831retry_root_backup :
27662832 generation = btrfs_super_generation (disk_super );
2833+ level = btrfs_super_root_level (disk_super );
27672834
27682835 tree_root -> node = read_tree_block (fs_info ,
27692836 btrfs_super_root (disk_super ),
2770- generation );
2837+ generation , level , NULL );
27712838 if (IS_ERR (tree_root -> node ) ||
27722839 !extent_buffer_uptodate (tree_root -> node )) {
27732840 btrfs_warn (fs_info , "failed to read tree root" );
@@ -3887,12 +3954,14 @@ void btrfs_btree_balance_dirty_nodelay(struct btrfs_fs_info *fs_info)
38873954 __btrfs_btree_balance_dirty (fs_info , 0 );
38883955}
38893956
3890- int btrfs_read_buffer (struct extent_buffer * buf , u64 parent_transid )
3957+ int btrfs_read_buffer (struct extent_buffer * buf , u64 parent_transid , int level ,
3958+ struct btrfs_key * first_key )
38913959{
38923960 struct btrfs_root * root = BTRFS_I (buf -> pages [0 ]-> mapping -> host )-> root ;
38933961 struct btrfs_fs_info * fs_info = root -> fs_info ;
38943962
3895- return btree_read_extent_buffer_pages (fs_info , buf , parent_transid );
3963+ return btree_read_extent_buffer_pages (fs_info , buf , parent_transid ,
3964+ level , first_key );
38963965}
38973966
38983967static int btrfs_check_super_valid (struct btrfs_fs_info * fs_info )
0 commit comments