@@ -354,7 +354,8 @@ static int ext4_valid_extent_idx(struct inode *inode,
354354
355355static int ext4_valid_extent_entries (struct inode * inode ,
356356 struct ext4_extent_header * eh ,
357- ext4_fsblk_t * pblk , int depth )
357+ ext4_lblk_t lblk , ext4_fsblk_t * pblk ,
358+ int depth )
358359{
359360 unsigned short entries ;
360361 ext4_lblk_t lblock = 0 ;
@@ -368,6 +369,14 @@ static int ext4_valid_extent_entries(struct inode *inode,
368369 if (depth == 0 ) {
369370 /* leaf entries */
370371 struct ext4_extent * ext = EXT_FIRST_EXTENT (eh );
372+
373+ /*
374+ * The logical block in the first entry should equal to
375+ * the number in the index block.
376+ */
377+ if (depth != ext_depth (inode ) &&
378+ lblk != le32_to_cpu (ext -> ee_block ))
379+ return 0 ;
371380 while (entries ) {
372381 if (!ext4_valid_extent (inode , ext ))
373382 return 0 ;
@@ -384,6 +393,14 @@ static int ext4_valid_extent_entries(struct inode *inode,
384393 }
385394 } else {
386395 struct ext4_extent_idx * ext_idx = EXT_FIRST_INDEX (eh );
396+
397+ /*
398+ * The logical block in the first entry should equal to
399+ * the number in the parent index block.
400+ */
401+ if (depth != ext_depth (inode ) &&
402+ lblk != le32_to_cpu (ext_idx -> ei_block ))
403+ return 0 ;
387404 while (entries ) {
388405 if (!ext4_valid_extent_idx (inode , ext_idx ))
389406 return 0 ;
@@ -404,7 +421,7 @@ static int ext4_valid_extent_entries(struct inode *inode,
404421
405422static int __ext4_ext_check (const char * function , unsigned int line ,
406423 struct inode * inode , struct ext4_extent_header * eh ,
407- int depth , ext4_fsblk_t pblk )
424+ int depth , ext4_fsblk_t pblk , ext4_lblk_t lblk )
408425{
409426 const char * error_msg ;
410427 int max = 0 , err = - EFSCORRUPTED ;
@@ -430,7 +447,7 @@ static int __ext4_ext_check(const char *function, unsigned int line,
430447 error_msg = "invalid eh_entries" ;
431448 goto corrupted ;
432449 }
433- if (!ext4_valid_extent_entries (inode , eh , & pblk , depth )) {
450+ if (!ext4_valid_extent_entries (inode , eh , lblk , & pblk , depth )) {
434451 error_msg = "invalid extent entries" ;
435452 goto corrupted ;
436453 }
@@ -460,7 +477,7 @@ static int __ext4_ext_check(const char *function, unsigned int line,
460477}
461478
462479#define ext4_ext_check (inode , eh , depth , pblk ) \
463- __ext4_ext_check(__func__, __LINE__, (inode), (eh), (depth), (pblk))
480+ __ext4_ext_check(__func__, __LINE__, (inode), (eh), (depth), (pblk), 0 )
464481
465482int ext4_ext_check_inode (struct inode * inode )
466483{
@@ -493,16 +510,18 @@ static void ext4_cache_extents(struct inode *inode,
493510
494511static struct buffer_head *
495512__read_extent_tree_block (const char * function , unsigned int line ,
496- struct inode * inode , ext4_fsblk_t pblk , int depth ,
497- int flags )
513+ struct inode * inode , struct ext4_extent_idx * idx ,
514+ int depth , int flags )
498515{
499516 struct buffer_head * bh ;
500517 int err ;
501518 gfp_t gfp_flags = __GFP_MOVABLE | GFP_NOFS ;
519+ ext4_fsblk_t pblk ;
502520
503521 if (flags & EXT4_EX_NOFAIL )
504522 gfp_flags |= __GFP_NOFAIL ;
505523
524+ pblk = ext4_idx_pblock (idx );
506525 bh = sb_getblk_gfp (inode -> i_sb , pblk , gfp_flags );
507526 if (unlikely (!bh ))
508527 return ERR_PTR (- ENOMEM );
@@ -515,8 +534,8 @@ __read_extent_tree_block(const char *function, unsigned int line,
515534 }
516535 if (buffer_verified (bh ) && !(flags & EXT4_EX_FORCE_CACHE ))
517536 return bh ;
518- err = __ext4_ext_check (function , line , inode ,
519- ext_block_hdr ( bh ), depth , pblk );
537+ err = __ext4_ext_check (function , line , inode , ext_block_hdr ( bh ),
538+ depth , pblk , le32_to_cpu ( idx -> ei_block ) );
520539 if (err )
521540 goto errout ;
522541 set_buffer_verified (bh );
@@ -534,8 +553,8 @@ __read_extent_tree_block(const char *function, unsigned int line,
534553
535554}
536555
537- #define read_extent_tree_block (inode , pblk , depth , flags ) \
538- __read_extent_tree_block(__func__, __LINE__, (inode), (pblk), \
556+ #define read_extent_tree_block (inode , idx , depth , flags ) \
557+ __read_extent_tree_block(__func__, __LINE__, (inode), (idx), \
539558 (depth), (flags))
540559
541560/*
@@ -585,8 +604,7 @@ int ext4_ext_precache(struct inode *inode)
585604 i -- ;
586605 continue ;
587606 }
588- bh = read_extent_tree_block (inode ,
589- ext4_idx_pblock (path [i ].p_idx ++ ),
607+ bh = read_extent_tree_block (inode , path [i ].p_idx ++ ,
590608 depth - i - 1 ,
591609 EXT4_EX_FORCE_CACHE );
592610 if (IS_ERR (bh )) {
@@ -893,8 +911,7 @@ ext4_find_extent(struct inode *inode, ext4_lblk_t block,
893911 path [ppos ].p_depth = i ;
894912 path [ppos ].p_ext = NULL ;
895913
896- bh = read_extent_tree_block (inode , path [ppos ].p_block , -- i ,
897- flags );
914+ bh = read_extent_tree_block (inode , path [ppos ].p_idx , -- i , flags );
898915 if (IS_ERR (bh )) {
899916 ret = PTR_ERR (bh );
900917 goto err ;
@@ -1503,7 +1520,6 @@ static int ext4_ext_search_right(struct inode *inode,
15031520 struct ext4_extent_header * eh ;
15041521 struct ext4_extent_idx * ix ;
15051522 struct ext4_extent * ex ;
1506- ext4_fsblk_t block ;
15071523 int depth ; /* Note, NOT eh_depth; depth from top of tree */
15081524 int ee_len ;
15091525
@@ -1570,20 +1586,17 @@ static int ext4_ext_search_right(struct inode *inode,
15701586 * follow it and find the closest allocated
15711587 * block to the right */
15721588 ix ++ ;
1573- block = ext4_idx_pblock (ix );
15741589 while (++ depth < path -> p_depth ) {
15751590 /* subtract from p_depth to get proper eh_depth */
1576- bh = read_extent_tree_block (inode , block ,
1577- path -> p_depth - depth , 0 );
1591+ bh = read_extent_tree_block (inode , ix , path -> p_depth - depth , 0 );
15781592 if (IS_ERR (bh ))
15791593 return PTR_ERR (bh );
15801594 eh = ext_block_hdr (bh );
15811595 ix = EXT_FIRST_INDEX (eh );
1582- block = ext4_idx_pblock (ix );
15831596 put_bh (bh );
15841597 }
15851598
1586- bh = read_extent_tree_block (inode , block , path -> p_depth - depth , 0 );
1599+ bh = read_extent_tree_block (inode , ix , path -> p_depth - depth , 0 );
15871600 if (IS_ERR (bh ))
15881601 return PTR_ERR (bh );
15891602 eh = ext_block_hdr (bh );
@@ -2962,9 +2975,9 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
29622975 ext_debug (inode , "move to level %d (block %llu)\n" ,
29632976 i + 1 , ext4_idx_pblock (path [i ].p_idx ));
29642977 memset (path + i + 1 , 0 , sizeof (* path ));
2965- bh = read_extent_tree_block (inode ,
2966- ext4_idx_pblock ( path [ i ]. p_idx ), depth - i - 1 ,
2967- EXT4_EX_NOCACHE );
2978+ bh = read_extent_tree_block (inode , path [ i ]. p_idx ,
2979+ depth - i - 1 ,
2980+ EXT4_EX_NOCACHE );
29682981 if (IS_ERR (bh )) {
29692982 /* should we reset i_size? */
29702983 err = PTR_ERR (bh );
0 commit comments