@@ -96,8 +96,12 @@ static struct fsync_inode_entry *add_fsync_inode(struct f2fs_sb_info *sbi,
96
96
return ERR_PTR (err );
97
97
}
98
98
99
- static void del_fsync_inode (struct fsync_inode_entry * entry )
99
+ static void del_fsync_inode (struct fsync_inode_entry * entry , int drop )
100
100
{
101
+ if (drop ) {
102
+ /* inode should not be recovered, drop it */
103
+ f2fs_inode_synced (entry -> inode );
104
+ }
101
105
iput (entry -> inode );
102
106
list_del (& entry -> list );
103
107
kmem_cache_free (fsync_entry_slab , entry );
@@ -338,12 +342,12 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head,
338
342
return err ;
339
343
}
340
344
341
- static void destroy_fsync_dnodes (struct list_head * head )
345
+ static void destroy_fsync_dnodes (struct list_head * head , int drop )
342
346
{
343
347
struct fsync_inode_entry * entry , * tmp ;
344
348
345
349
list_for_each_entry_safe (entry , tmp , head , list )
346
- del_fsync_inode (entry );
350
+ del_fsync_inode (entry , drop );
347
351
}
348
352
349
353
static int check_index_in_prev_nodes (struct f2fs_sb_info * sbi ,
@@ -580,7 +584,7 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
580
584
}
581
585
582
586
static int recover_data (struct f2fs_sb_info * sbi , struct list_head * inode_list ,
583
- struct list_head * dir_list )
587
+ struct list_head * tmp_inode_list , struct list_head * dir_list )
584
588
{
585
589
struct curseg_info * curseg ;
586
590
struct page * page = NULL ;
@@ -634,7 +638,7 @@ static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list,
634
638
}
635
639
636
640
if (entry -> blkaddr == blkaddr )
637
- del_fsync_inode ( entry );
641
+ list_move_tail ( & entry -> list , tmp_inode_list );
638
642
next :
639
643
/* check next segment */
640
644
blkaddr = next_blkaddr_of_node (page );
@@ -647,7 +651,7 @@ static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list,
647
651
648
652
int f2fs_recover_fsync_data (struct f2fs_sb_info * sbi , bool check_only )
649
653
{
650
- struct list_head inode_list ;
654
+ struct list_head inode_list , tmp_inode_list ;
651
655
struct list_head dir_list ;
652
656
int err ;
653
657
int ret = 0 ;
@@ -678,6 +682,7 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only)
678
682
}
679
683
680
684
INIT_LIST_HEAD (& inode_list );
685
+ INIT_LIST_HEAD (& tmp_inode_list );
681
686
INIT_LIST_HEAD (& dir_list );
682
687
683
688
/* prevent checkpoint */
@@ -696,11 +701,16 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only)
696
701
need_writecp = true;
697
702
698
703
/* step #2: recover data */
699
- err = recover_data (sbi , & inode_list , & dir_list );
704
+ err = recover_data (sbi , & inode_list , & tmp_inode_list , & dir_list );
700
705
if (!err )
701
706
f2fs_bug_on (sbi , !list_empty (& inode_list ));
707
+ else {
708
+ /* restore s_flags to let iput() trash data */
709
+ sbi -> sb -> s_flags = s_flags ;
710
+ }
702
711
skip :
703
- destroy_fsync_dnodes (& inode_list );
712
+ destroy_fsync_dnodes (& inode_list , err );
713
+ destroy_fsync_dnodes (& tmp_inode_list , err );
704
714
705
715
/* truncate meta pages to be used by the recovery */
706
716
truncate_inode_pages_range (META_MAPPING (sbi ),
@@ -709,13 +719,13 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only)
709
719
if (err ) {
710
720
truncate_inode_pages_final (NODE_MAPPING (sbi ));
711
721
truncate_inode_pages_final (META_MAPPING (sbi ));
722
+ } else {
723
+ clear_sbi_flag (sbi , SBI_POR_DOING );
712
724
}
713
-
714
- clear_sbi_flag (sbi , SBI_POR_DOING );
715
725
mutex_unlock (& sbi -> cp_mutex );
716
726
717
727
/* let's drop all the directory inodes for clean checkpoint */
718
- destroy_fsync_dnodes (& dir_list );
728
+ destroy_fsync_dnodes (& dir_list , err );
719
729
720
730
if (need_writecp ) {
721
731
set_sbi_flag (sbi , SBI_IS_RECOVERED );
0 commit comments