In the case of out-of-place updating, the one valid data block will be invalid 
in seg S,
so S can be marked as PRE.

在 2019/3/4 12:48, Sahitya Tummala 写道:
> On Mon, Mar 04, 2019 at 09:32:25AM +0800, zhengliang wrote:
>> v4: Rearrange the previous three versions.
>>
>> The following scenario could lead to data block override by mistake.
>>
>> TASK A            |  TASK kworker                                            
>> |     TASK B                                            |       TASK C
>>                   |                                                          
>> |                                                       |
>> open              |                                                          
>> |                                                       |
>> write             |                                                          
>> |                                                       |
>> close             |                                                          
>> |                                                       |
>>                   |  f2fs_write_data_pages                                   
>> |                                                       |
>>                   |    f2fs_write_cache_pages                                
>> |                                                       |
>>                   |      f2fs_outplace_write_data                            
>> |                                                       |
>>                   |        f2fs_allocate_data_block (get block in seg S,     
>> |                                                       |
>>                   |                                  S is full, and only     
>> |                                                       |
>>                   |                                  have this valid data    
>> |                                                       |
>>                   |                                  block)                  
>> |                                                       |
>>                   |          allocate_segment                                
>> |                                                       |
>>                   |          locate_dirty_segment (mark S as PRE)            
>> |                                                       |
> 
> In Task kworker context, if there is one valid data block allocated from S, 
> then how can
> S be marked as PRE? Shouldn't it be DIRTY? Please clarify.
> 
>>                   |        f2fs_submit_page_write (submit but is not         
>> |                                                       |
>>                   |                                written on dev)           
>> |                                                       |
>> unlink            |                                                          
>> |                                                       |
>>  iput_final       |                                                          
>> |                                                       |
>>   f2fs_drop_inode |                                                          
>> |                                                       |
>>     f2fs_truncate |                                                          
>> |                                                       |
>>  (not evict)      |                                                          
>> |                                                       |
>>                   |                                                          
>> | write_checkpoint                                      |
>>                   |                                                          
>> |  flush merged bio but not wait file data writeback    |
>>                   |                                                          
>> |  set_prefree_as_free (mark S as FREE)                 |
>>                   |                                                          
>> |                                                       | update NODE/DATA
>>                   |                                                          
>> |                                                       | allocate_segment 
>> (select S)
>>                   |     writeback done                                       
>> |                                                       |
>>
>> So we need to guarantee io complete before truncate inode in f2fs_drop_inode.
>>
>> Reviewed-by: Chao Yu <[email protected]>
>> Signed-off-by: Zheng Liang <[email protected]>
>> --------
>> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
>> index c46a1d43..60f0599 100644
>> --- a/fs/f2fs/super.c
>> +++ b/fs/f2fs/super.c
>> @@ -915,6 +915,10 @@ static int f2fs_drop_inode(struct inode *inode)
>>                         sb_start_intwrite(inode->i_sb);
>>                         f2fs_i_size_write(inode, 0);
>>
>> +                       f2fs_submit_merged_write_cond(F2FS_I_SB(inode),
>> +                                       inode, NULL, 0, DATA);
>> +                       truncate_inode_pages_final(inode->i_mapping);
>> +
>>                         if (F2FS_HAS_BLOCKS(inode))
>>                                 f2fs_truncate(inode);
>>
>>
>>
>> _______________________________________________
>> Linux-f2fs-devel mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
> 



_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to