@@ -99,8 +99,12 @@ static struct fsync_inode_entry *add_fsync_inode(struct f2fs_sb_info *sbi,
99
99
return ERR_PTR (err );
100
100
}
101
101
102
- static void del_fsync_inode (struct fsync_inode_entry * entry )
102
+ static void del_fsync_inode (struct fsync_inode_entry * entry , int drop )
103
103
{
104
+ if (drop ) {
105
+ /* inode should not be recovered, drop it */
106
+ f2fs_inode_synced (entry -> inode );
107
+ }
104
108
iput (entry -> inode );
105
109
list_del (& entry -> list );
106
110
kmem_cache_free (fsync_entry_slab , entry );
@@ -321,12 +325,12 @@ static int find_fsync_dnodes(struct f2fs_sb_info *sbi, struct list_head *head,
321
325
return err ;
322
326
}
323
327
324
- static void destroy_fsync_dnodes (struct list_head * head )
328
+ static void destroy_fsync_dnodes (struct list_head * head , int drop )
325
329
{
326
330
struct fsync_inode_entry * entry , * tmp ;
327
331
328
332
list_for_each_entry_safe (entry , tmp , head , list )
329
- del_fsync_inode (entry );
333
+ del_fsync_inode (entry , drop );
330
334
}
331
335
332
336
static int check_index_in_prev_nodes (struct f2fs_sb_info * sbi ,
@@ -561,7 +565,7 @@ static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
561
565
}
562
566
563
567
static int recover_data (struct f2fs_sb_info * sbi , struct list_head * inode_list ,
564
- struct list_head * dir_list )
568
+ struct list_head * tmp_inode_list , struct list_head * dir_list )
565
569
{
566
570
struct curseg_info * curseg ;
567
571
struct page * page = NULL ;
@@ -615,7 +619,7 @@ static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list,
615
619
}
616
620
617
621
if (entry -> blkaddr == blkaddr )
618
- del_fsync_inode ( entry );
622
+ list_move_tail ( & entry -> list , tmp_inode_list );
619
623
next :
620
624
/* check next segment */
621
625
blkaddr = next_blkaddr_of_node (page );
@@ -628,7 +632,7 @@ static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list,
628
632
629
633
int f2fs_recover_fsync_data (struct f2fs_sb_info * sbi , bool check_only )
630
634
{
631
- struct list_head inode_list ;
635
+ struct list_head inode_list , tmp_inode_list ;
632
636
struct list_head dir_list ;
633
637
int err ;
634
638
int ret = 0 ;
@@ -659,6 +663,7 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only)
659
663
}
660
664
661
665
INIT_LIST_HEAD (& inode_list );
666
+ INIT_LIST_HEAD (& tmp_inode_list );
662
667
INIT_LIST_HEAD (& dir_list );
663
668
664
669
/* prevent checkpoint */
@@ -677,11 +682,16 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only)
677
682
need_writecp = true;
678
683
679
684
/* step #2: recover data */
680
- err = recover_data (sbi , & inode_list , & dir_list );
685
+ err = recover_data (sbi , & inode_list , & tmp_inode_list , & dir_list );
681
686
if (!err )
682
687
f2fs_bug_on (sbi , !list_empty (& inode_list ));
688
+ else {
689
+ /* restore s_flags to let iput() trash data */
690
+ sbi -> sb -> s_flags = s_flags ;
691
+ }
683
692
skip :
684
- destroy_fsync_dnodes (& inode_list );
693
+ destroy_fsync_dnodes (& inode_list , err );
694
+ destroy_fsync_dnodes (& tmp_inode_list , err );
685
695
686
696
/* truncate meta pages to be used by the recovery */
687
697
truncate_inode_pages_range (META_MAPPING (sbi ),
@@ -690,13 +700,13 @@ int f2fs_recover_fsync_data(struct f2fs_sb_info *sbi, bool check_only)
690
700
if (err ) {
691
701
truncate_inode_pages_final (NODE_MAPPING (sbi ));
692
702
truncate_inode_pages_final (META_MAPPING (sbi ));
703
+ } else {
704
+ clear_sbi_flag (sbi , SBI_POR_DOING );
693
705
}
694
-
695
- clear_sbi_flag (sbi , SBI_POR_DOING );
696
706
mutex_unlock (& sbi -> cp_mutex );
697
707
698
708
/* let's drop all the directory inodes for clean checkpoint */
699
- destroy_fsync_dnodes (& dir_list );
709
+ destroy_fsync_dnodes (& dir_list , err );
700
710
701
711
if (need_writecp ) {
702
712
set_sbi_flag (sbi , SBI_IS_RECOVERED );
0 commit comments