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

-- 
--
Sent by a consultant of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.


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

Reply via email to