26
26
static struct kmem_cache * ino_entry_slab ;
27
27
struct kmem_cache * f2fs_inode_entry_slab ;
28
28
29
- void f2fs_stop_checkpoint (struct f2fs_sb_info * sbi , bool end_io )
29
+ void f2fs_stop_checkpoint (struct f2fs_sb_info * sbi , bool end_io ,
30
+ unsigned char reason )
30
31
{
31
32
f2fs_build_fault_attr (sbi , 0 , 0 );
32
33
set_ckpt_flags (sbi , CP_ERROR_FLAG );
33
- if (!end_io )
34
+ if (!end_io ) {
34
35
f2fs_flush_merged_writes (sbi );
36
+
37
+ f2fs_handle_stop (sbi , reason );
38
+ }
35
39
}
36
40
37
41
/*
@@ -122,7 +126,7 @@ struct page *f2fs_get_meta_page_retry(struct f2fs_sb_info *sbi, pgoff_t index)
122
126
if (PTR_ERR (page ) == - EIO &&
123
127
++ count <= DEFAULT_RETRY_IO_COUNT )
124
128
goto retry ;
125
- f2fs_stop_checkpoint (sbi , false);
129
+ f2fs_stop_checkpoint (sbi , false, STOP_CP_REASON_META_PAGE );
126
130
}
127
131
return page ;
128
132
}
@@ -140,14 +144,21 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr,
140
144
unsigned int segno , offset ;
141
145
bool exist ;
142
146
143
- if (type != DATA_GENERIC_ENHANCE && type != DATA_GENERIC_ENHANCE_READ )
147
+ if (type == DATA_GENERIC )
144
148
return true;
145
149
146
150
segno = GET_SEGNO (sbi , blkaddr );
147
151
offset = GET_BLKOFF_FROM_SEG0 (sbi , blkaddr );
148
152
se = get_seg_entry (sbi , segno );
149
153
150
154
exist = f2fs_test_bit (offset , se -> cur_valid_map );
155
+ if (exist && type == DATA_GENERIC_ENHANCE_UPDATE ) {
156
+ f2fs_err (sbi , "Inconsistent error blkaddr:%u, sit bitmap:%d" ,
157
+ blkaddr , exist );
158
+ set_sbi_flag (sbi , SBI_NEED_FSCK );
159
+ return exist ;
160
+ }
161
+
151
162
if (!exist && type == DATA_GENERIC_ENHANCE ) {
152
163
f2fs_err (sbi , "Inconsistent error blkaddr:%u, sit bitmap:%d" ,
153
164
blkaddr , exist );
@@ -160,6 +171,11 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr,
160
171
bool f2fs_is_valid_blkaddr (struct f2fs_sb_info * sbi ,
161
172
block_t blkaddr , int type )
162
173
{
174
+ if (time_to_inject (sbi , FAULT_BLKADDR )) {
175
+ f2fs_show_injection_info (sbi , FAULT_BLKADDR );
176
+ return false;
177
+ }
178
+
163
179
switch (type ) {
164
180
case META_NAT :
165
181
break ;
@@ -185,6 +201,7 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
185
201
case DATA_GENERIC :
186
202
case DATA_GENERIC_ENHANCE :
187
203
case DATA_GENERIC_ENHANCE_READ :
204
+ case DATA_GENERIC_ENHANCE_UPDATE :
188
205
if (unlikely (blkaddr >= MAX_BLKADDR (sbi ) ||
189
206
blkaddr < MAIN_BLKADDR (sbi ))) {
190
207
f2fs_warn (sbi , "access invalid blkaddr:%u" ,
@@ -447,8 +464,7 @@ static int f2fs_set_meta_page_dirty(struct page *page)
447
464
448
465
if (!PageUptodate (page ))
449
466
SetPageUptodate (page );
450
- if (!PageDirty (page )) {
451
- __set_page_dirty_nobuffers (page );
467
+ if (__set_page_dirty_nobuffers (page )) {
452
468
inc_page_count (F2FS_P_SB (page ), F2FS_DIRTY_META );
453
469
set_page_private_reference (page );
454
470
return 1 ;
@@ -1054,7 +1070,8 @@ void f2fs_remove_dirty_inode(struct inode *inode)
1054
1070
spin_unlock (& sbi -> inode_lock [type ]);
1055
1071
}
1056
1072
1057
- int f2fs_sync_dirty_inodes (struct f2fs_sb_info * sbi , enum inode_type type )
1073
+ int f2fs_sync_dirty_inodes (struct f2fs_sb_info * sbi , enum inode_type type ,
1074
+ bool from_cp )
1058
1075
{
1059
1076
struct list_head * head ;
1060
1077
struct inode * inode ;
@@ -1089,11 +1106,15 @@ int f2fs_sync_dirty_inodes(struct f2fs_sb_info *sbi, enum inode_type type)
1089
1106
if (inode ) {
1090
1107
unsigned long cur_ino = inode -> i_ino ;
1091
1108
1092
- F2FS_I (inode )-> cp_task = current ;
1109
+ if (from_cp )
1110
+ F2FS_I (inode )-> cp_task = current ;
1111
+ F2FS_I (inode )-> wb_task = current ;
1093
1112
1094
1113
filemap_fdatawrite (inode -> i_mapping );
1095
1114
1096
- F2FS_I (inode )-> cp_task = NULL ;
1115
+ F2FS_I (inode )-> wb_task = NULL ;
1116
+ if (from_cp )
1117
+ F2FS_I (inode )-> cp_task = NULL ;
1097
1118
1098
1119
iput (inode );
1099
1120
/* We need to give cpu to another writers. */
@@ -1222,7 +1243,7 @@ static int block_operations(struct f2fs_sb_info *sbi)
1222
1243
/* write all the dirty dentry pages */
1223
1244
if (get_pages (sbi , F2FS_DIRTY_DENTS )) {
1224
1245
f2fs_unlock_all (sbi );
1225
- err = f2fs_sync_dirty_inodes (sbi , DIR_INODE );
1246
+ err = f2fs_sync_dirty_inodes (sbi , DIR_INODE , true );
1226
1247
if (err )
1227
1248
return err ;
1228
1249
cond_resched ();
@@ -1889,8 +1910,10 @@ int f2fs_start_ckpt_thread(struct f2fs_sb_info *sbi)
1889
1910
cprc -> f2fs_issue_ckpt = kthread_run (issue_checkpoint_thread , sbi ,
1890
1911
"f2fs_ckpt-%u:%u" , MAJOR (dev ), MINOR (dev ));
1891
1912
if (IS_ERR (cprc -> f2fs_issue_ckpt )) {
1913
+ int err = PTR_ERR (cprc -> f2fs_issue_ckpt );
1914
+
1892
1915
cprc -> f2fs_issue_ckpt = NULL ;
1893
- return - ENOMEM ;
1916
+ return err ;
1894
1917
}
1895
1918
1896
1919
set_task_ioprio (cprc -> f2fs_issue_ckpt , cprc -> ckpt_thread_ioprio );
@@ -1901,15 +1924,27 @@ int f2fs_start_ckpt_thread(struct f2fs_sb_info *sbi)
1901
1924
void f2fs_stop_ckpt_thread (struct f2fs_sb_info * sbi )
1902
1925
{
1903
1926
struct ckpt_req_control * cprc = & sbi -> cprc_info ;
1927
+ struct task_struct * ckpt_task ;
1904
1928
1905
- if (cprc -> f2fs_issue_ckpt ) {
1906
- struct task_struct * ckpt_task = cprc -> f2fs_issue_ckpt ;
1929
+ if (! cprc -> f2fs_issue_ckpt )
1930
+ return ;
1907
1931
1908
- cprc -> f2fs_issue_ckpt = NULL ;
1909
- kthread_stop (ckpt_task );
1932
+ ckpt_task = cprc -> f2fs_issue_ckpt ;
1933
+ cprc -> f2fs_issue_ckpt = NULL ;
1934
+ kthread_stop (ckpt_task );
1910
1935
1911
- flush_remained_ckpt_reqs (sbi , NULL );
1912
- }
1936
+ f2fs_flush_ckpt_thread (sbi );
1937
+ }
1938
+
1939
+ void f2fs_flush_ckpt_thread (struct f2fs_sb_info * sbi )
1940
+ {
1941
+ struct ckpt_req_control * cprc = & sbi -> cprc_info ;
1942
+
1943
+ flush_remained_ckpt_reqs (sbi , NULL );
1944
+
1945
+ /* Let's wait for the previous dispatched checkpoint. */
1946
+ while (atomic_read (& cprc -> queued_ckpt ))
1947
+ io_schedule_timeout (DEFAULT_IO_TIMEOUT );
1913
1948
}
1914
1949
1915
1950
void f2fs_init_ckpt_req_control (struct f2fs_sb_info * sbi )
0 commit comments