@@ -354,7 +354,8 @@ static int ext4_valid_extent_idx(struct inode *inode,
354
354
355
355
static int ext4_valid_extent_entries (struct inode * inode ,
356
356
struct ext4_extent_header * eh ,
357
- ext4_fsblk_t * pblk , int depth )
357
+ ext4_lblk_t lblk , ext4_fsblk_t * pblk ,
358
+ int depth )
358
359
{
359
360
unsigned short entries ;
360
361
ext4_lblk_t lblock = 0 ;
@@ -368,6 +369,14 @@ static int ext4_valid_extent_entries(struct inode *inode,
368
369
if (depth == 0 ) {
369
370
/* leaf entries */
370
371
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 ;
371
380
while (entries ) {
372
381
if (!ext4_valid_extent (inode , ext ))
373
382
return 0 ;
@@ -384,6 +393,14 @@ static int ext4_valid_extent_entries(struct inode *inode,
384
393
}
385
394
} else {
386
395
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 ;
387
404
while (entries ) {
388
405
if (!ext4_valid_extent_idx (inode , ext_idx ))
389
406
return 0 ;
@@ -404,7 +421,7 @@ static int ext4_valid_extent_entries(struct inode *inode,
404
421
405
422
static int __ext4_ext_check (const char * function , unsigned int line ,
406
423
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 )
408
425
{
409
426
const char * error_msg ;
410
427
int max = 0 , err = - EFSCORRUPTED ;
@@ -430,7 +447,7 @@ static int __ext4_ext_check(const char *function, unsigned int line,
430
447
error_msg = "invalid eh_entries" ;
431
448
goto corrupted ;
432
449
}
433
- if (!ext4_valid_extent_entries (inode , eh , & pblk , depth )) {
450
+ if (!ext4_valid_extent_entries (inode , eh , lblk , & pblk , depth )) {
434
451
error_msg = "invalid extent entries" ;
435
452
goto corrupted ;
436
453
}
@@ -460,7 +477,7 @@ static int __ext4_ext_check(const char *function, unsigned int line,
460
477
}
461
478
462
479
#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 )
464
481
465
482
int ext4_ext_check_inode (struct inode * inode )
466
483
{
@@ -493,16 +510,18 @@ static void ext4_cache_extents(struct inode *inode,
493
510
494
511
static struct buffer_head *
495
512
__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 )
498
515
{
499
516
struct buffer_head * bh ;
500
517
int err ;
501
518
gfp_t gfp_flags = __GFP_MOVABLE | GFP_NOFS ;
519
+ ext4_fsblk_t pblk ;
502
520
503
521
if (flags & EXT4_EX_NOFAIL )
504
522
gfp_flags |= __GFP_NOFAIL ;
505
523
524
+ pblk = ext4_idx_pblock (idx );
506
525
bh = sb_getblk_gfp (inode -> i_sb , pblk , gfp_flags );
507
526
if (unlikely (!bh ))
508
527
return ERR_PTR (- ENOMEM );
@@ -515,8 +534,8 @@ __read_extent_tree_block(const char *function, unsigned int line,
515
534
}
516
535
if (buffer_verified (bh ) && !(flags & EXT4_EX_FORCE_CACHE ))
517
536
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 ) );
520
539
if (err )
521
540
goto errout ;
522
541
set_buffer_verified (bh );
@@ -534,8 +553,8 @@ __read_extent_tree_block(const char *function, unsigned int line,
534
553
535
554
}
536
555
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), \
539
558
(depth), (flags))
540
559
541
560
/*
@@ -585,8 +604,7 @@ int ext4_ext_precache(struct inode *inode)
585
604
i -- ;
586
605
continue ;
587
606
}
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 ++ ,
590
608
depth - i - 1 ,
591
609
EXT4_EX_FORCE_CACHE );
592
610
if (IS_ERR (bh )) {
@@ -893,8 +911,7 @@ ext4_find_extent(struct inode *inode, ext4_lblk_t block,
893
911
path [ppos ].p_depth = i ;
894
912
path [ppos ].p_ext = NULL ;
895
913
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 );
898
915
if (IS_ERR (bh )) {
899
916
ret = PTR_ERR (bh );
900
917
goto err ;
@@ -1503,7 +1520,6 @@ static int ext4_ext_search_right(struct inode *inode,
1503
1520
struct ext4_extent_header * eh ;
1504
1521
struct ext4_extent_idx * ix ;
1505
1522
struct ext4_extent * ex ;
1506
- ext4_fsblk_t block ;
1507
1523
int depth ; /* Note, NOT eh_depth; depth from top of tree */
1508
1524
int ee_len ;
1509
1525
@@ -1570,20 +1586,17 @@ static int ext4_ext_search_right(struct inode *inode,
1570
1586
* follow it and find the closest allocated
1571
1587
* block to the right */
1572
1588
ix ++ ;
1573
- block = ext4_idx_pblock (ix );
1574
1589
while (++ depth < path -> p_depth ) {
1575
1590
/* 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 );
1578
1592
if (IS_ERR (bh ))
1579
1593
return PTR_ERR (bh );
1580
1594
eh = ext_block_hdr (bh );
1581
1595
ix = EXT_FIRST_INDEX (eh );
1582
- block = ext4_idx_pblock (ix );
1583
1596
put_bh (bh );
1584
1597
}
1585
1598
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 );
1587
1600
if (IS_ERR (bh ))
1588
1601
return PTR_ERR (bh );
1589
1602
eh = ext_block_hdr (bh );
@@ -2962,9 +2975,9 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
2962
2975
ext_debug (inode , "move to level %d (block %llu)\n" ,
2963
2976
i + 1 , ext4_idx_pblock (path [i ].p_idx ));
2964
2977
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 );
2968
2981
if (IS_ERR (bh )) {
2969
2982
/* should we reset i_size? */
2970
2983
err = PTR_ERR (bh );
0 commit comments