• Chao Yu's avatar
    f2fs: fix out-place-update DIO write · f9d6d059
    Chao Yu authored
    In get_more_blocks(), we may override @create as below code:
    
    	create = dio->op == REQ_OP_WRITE;
    	if (dio->flags & DIO_SKIP_HOLES) {
    		if (fs_startblk <= ((i_size_read(dio->inode) - 1) >>
    						i_blkbits))
    			create = 0;
    	}
    
    But in f2fs_map_blocks(), we only trigger f2fs_balance_fs() if @create
    is 1, so in LFS mode, dio overwrite under LFS mode can easily run out
    of free segments, result in below panic.
    
     Call Trace:
      allocate_segment_by_default+0xa8/0x270 [f2fs]
      f2fs_allocate_data_block+0x1ea/0x5c0 [f2fs]
      __allocate_data_block+0x306/0x480 [f2fs]
      f2fs_map_blocks+0x6f6/0x920 [f2fs]
      __get_data_block+0x4f/0xb0 [f2fs]
      get_data_block_dio_write+0x50/0x60 [f2fs]
      do_blockdev_direct_IO+0xcd5/0x21e0
      __blockdev_direct_IO+0x3a/0x3c
      f2fs_direct_IO+0x1ff/0x4a0 [f2fs]
      generic_file_direct_write+0xd9/0x160
      __generic_file_write_iter+0xbb/0x1e0
      f2fs_file_write_iter+0xaf/0x220 [f2fs]
      __vfs_write+0xd0/0x130
      vfs_write+0xb2/0x1b0
      SyS_pwrite64+0x69/0xa0
      ? vtime_user_exit+0x29/0x70
      do_syscall_64+0x6e/0x160
      entry_SYSCALL64_slow_path+0x25/0x25
     RIP: new_curseg+0x36f/0x380 [f2fs] RSP: ffffac570393f7a8
    
    So this patch introduces a parameter map.m_may_create to indicate that
    f2fs_map_blocks() is called from write or read path, which can give the
    right hint to let f2fs_map_blocks() trigger OPU allocation and call
    f2fs_balanc_fs() correctly.
    
    BTW, it disables physical address preallocation for direct IO in
    f2fs_preallocate_blocks, which is redundant to OPU allocation of
    f2fs_map_blocks.
    Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
    Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
    f9d6d059
f2fs.h 114 KB