All of lore.kernel.org
 help / color / mirror / Atom feed
From: Hyunchul Lee <hyc.lee@gmail.com>
To: Chao Yu <yuchao0@huawei.com>, Chao Yu <chao@kernel.org>,
	Jaegeuk Kim <jaegeuk@kernel.org>
Cc: kernel-team@lge.com, Hyunchul Lee <cheol.lee@lge.com>,
	linux-kernel@vger.kernel.org,
	linux-f2fs-devel@lists.sourceforge.net
Subject: Re: [f2fs-dev] [RFC PATHC 2/2] f2fs: apply write hints to select the type of segment for direct write
Date: Mon, 13 Nov 2017 10:48:29 +0900	[thread overview]
Message-ID: <5A08F9ED.6070309@gmail.com> (raw)
In-Reply-To: <70bf8e31-9b5c-e2cc-107b-d699c02c843f@huawei.com>

On 11/13/2017 10:24 AM, Chao Yu wrote:
> On 2017/11/13 8:07, Hyunchul Lee wrote:
>> On 11/11/2017 09:38 AM, Chao Yu wrote:
>>> On 2017/11/9 13:51, Hyunchul Lee wrote:
>>>> From: Hyunchul Lee <cheol.lee@lge.com>
>>>>
>>>> Select the type of the segment using write hints, when blocks are
>>>> allocated for direct write.
>>>>
>>>> There are unhandled corner cases. Hints are not applied in
>>>> in-place update.  And if the blocks of a file is not pre-allocated
>>>> because of the invalid user buffer, CURSEG_WARM_DATA segment will
>>>> be selected.
>>>>
>>>> Signed-off-by: Hyunchul Lee <cheol.lee@lge.com>
>>>> ---
>>>>  fs/f2fs/data.c | 101 ++++++++++++++++++++++++++++++++++-----------------------
>>>>  fs/f2fs/f2fs.h |   1 +
>>>>  2 files changed, 61 insertions(+), 41 deletions(-)
>>>>
>>>> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
>>>> index 36b5352..d06048a 100644
>>>> --- a/fs/f2fs/data.c
>>>> +++ b/fs/f2fs/data.c
>>>> @@ -783,7 +783,7 @@ struct page *get_new_data_page(struct inode *inode,
>>>>  	return page;
>>>>  }
>>>>  
>>>> -static int __allocate_data_block(struct dnode_of_data *dn)
>>>> +static int __allocate_data_block(struct dnode_of_data *dn, int seg_type)
>>>>  {
>>>>  	struct f2fs_sb_info *sbi = F2FS_I_SB(dn->inode);
>>>>  	struct f2fs_summary sum;
>>>> @@ -808,7 +808,7 @@ static int __allocate_data_block(struct dnode_of_data *dn)
>>>>  	set_summary(&sum, dn->nid, dn->ofs_in_node, ni.version);
>>>>  
>>>>  	allocate_data_block(sbi, NULL, dn->data_blkaddr, &dn->data_blkaddr,
>>>> -					&sum, CURSEG_WARM_DATA, NULL, false);
>>>> +					&sum, seg_type, NULL, false);
>>>>  	set_data_blkaddr(dn);
>>>>  
>>>>  	/* update i_size */
>>>> @@ -827,42 +827,6 @@ static inline bool __force_buffered_io(struct inode *inode, int rw)
>>>>  			F2FS_I_SB(inode)->s_ndevs);
>>>>  }
>>>>  
>>>> -int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *from)
>>>> -{
>>>> -	struct inode *inode = file_inode(iocb->ki_filp);
>>>> -	struct f2fs_map_blocks map;
>>>> -	int err = 0;
>>>> -
>>>> -	if (is_inode_flag_set(inode, FI_NO_PREALLOC))
>>>> -		return 0;
>>>> -
>>>> -	map.m_lblk = F2FS_BLK_ALIGN(iocb->ki_pos);
>>>> -	map.m_len = F2FS_BYTES_TO_BLK(iocb->ki_pos + iov_iter_count(from));
>>>> -	if (map.m_len > map.m_lblk)
>>>> -		map.m_len -= map.m_lblk;
>>>> -	else
>>>> -		map.m_len = 0;
>>>> -
>>>> -	map.m_next_pgofs = NULL;
>>>> -
>>>> -	if (iocb->ki_flags & IOCB_DIRECT) {
>>>> -		err = f2fs_convert_inline_inode(inode);
>>>> -		if (err)
>>>> -			return err;
>>>> -		return f2fs_map_blocks(inode, &map, 1,
>>>> -			__force_buffered_io(inode, WRITE) ?
>>>> -				F2FS_GET_BLOCK_PRE_AIO :
>>>> -				F2FS_GET_BLOCK_PRE_DIO);
>>>> -	}
>>>> -	if (iocb->ki_pos + iov_iter_count(from) > MAX_INLINE_DATA(inode)) {
>>>> -		err = f2fs_convert_inline_inode(inode);
>>>> -		if (err)
>>>> -			return err;
>>>> -	}
>>>> -	if (!f2fs_has_inline_data(inode))
>>>> -		return f2fs_map_blocks(inode, &map, 1, F2FS_GET_BLOCK_PRE_AIO);
>>>> -	return err;
>>>> -}
>>>>  
>>>>  static inline void __do_map_lock(struct f2fs_sb_info *sbi, int flag, bool lock)
>>>>  {
>>>> @@ -888,8 +852,8 @@ static inline void __do_map_lock(struct f2fs_sb_info *sbi, int flag, bool lock)
>>>>   *     b. do not use extent cache for better performance
>>>>   *     c. give the block addresses to blockdev
>>>>   */
>>>> -int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
>>>> -						int create, int flag)
>>>> +static int __f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
>>>> +				int create, int flag, int seg_type)
>>>>  {
>>>>  	unsigned int maxblocks = map->m_len;
>>>>  	struct dnode_of_data dn;
>>>> @@ -957,7 +921,12 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
>>>>  					last_ofs_in_node = dn.ofs_in_node;
>>>>  				}
>>>>  			} else {
>>>> -				err = __allocate_data_block(&dn);
>>>> +				/* if this inode is marked with FI_NO_PREALLOC,
>>>> +				 * @seg_type is NO_CHECK_TYPE
>>>> +				 */
>>>> +				if (seg_type == NO_CHECK_TYPE)
>>>> +					seg_type = CURSEG_WARM_DATA;
>>>> +				err = __allocate_data_block(&dn, seg_type);
>>>
>>> We need to use inode.i_write_hint instead of ki_hint passed from file.f_write_hint?
>>>
>>
>> The following commit says to use file.f_write_hint if it is available. 
>> "c75b1d9 fs: add fcntl() interface for setting/getting write life time hints"
> 
> Oh, yes, f_write_hint is recommended. So, I'm OK with this.
> 
> One left question as below.
> 
>>
>> And ki_hint is assiged to file.f_write_hint or inode.i_write_hint 
>> by file_write_hint() in init_sync_kiocb().
>> So, I think we need to use ki_hint instead of inode.i_write_hint.
>>
>> Thanks
>>
>>> Thanks,
>>>
>>>>  				if (!err)
>>>>  					set_inode_flag(inode, FI_APPEND_WRITE);
>>>>  			}
>>>> @@ -1048,6 +1017,51 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
>>>>  	return err;
>>>>  }
>>>>  
>>>> +int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
>>>> +						int create, int flag)
>>>> +{
>>>> +	return __f2fs_map_blocks(inode, map, create, flag, NO_CHECK_TYPE);
>>>> +}
>>>> +
>>>> +int f2fs_preallocate_blocks(struct kiocb *iocb, struct iov_iter *from)
>>>> +{
>>>> +	struct inode *inode = file_inode(iocb->ki_filp);
>>>> +	struct f2fs_map_blocks map;
>>>> +	int err = 0;
>>>> +
>>>> +	if (is_inode_flag_set(inode, FI_NO_PREALLOC))
>>>> +		return 0;
>>>> +
>>>> +	map.m_lblk = F2FS_BLK_ALIGN(iocb->ki_pos);
>>>> +	map.m_len = F2FS_BYTES_TO_BLK(iocb->ki_pos + iov_iter_count(from));
>>>> +	if (map.m_len > map.m_lblk)
>>>> +		map.m_len -= map.m_lblk;
>>>> +	else
>>>> +		map.m_len = 0;
>>>> +
>>>> +	map.m_next_pgofs = NULL;
>>>> +
>>>> +	if (iocb->ki_flags & IOCB_DIRECT) {
>>>> +		err = f2fs_convert_inline_inode(inode);
>>>> +		if (err)
>>>> +			return err;
>>>> +		return __f2fs_map_blocks(inode, &map, 1,
>>>> +			__force_buffered_io(inode, WRITE) ?
>>>> +				F2FS_GET_BLOCK_PRE_AIO :
>>>> +				F2FS_GET_BLOCK_PRE_DIO,
>>>> +				rw_hint_to_seg_type(iocb->ki_hint));
>>>> +	}
>>>> +	if (iocb->ki_pos + iov_iter_count(from) > MAX_INLINE_DATA(inode)) {
>>>> +		err = f2fs_convert_inline_inode(inode);
>>>> +		if (err)
>>>> +			return err;
>>>> +	}
>>>> +	if (!f2fs_has_inline_data(inode))
>>>> +		return f2fs_map_blocks(inode, &map, 1, F2FS_GET_BLOCK_PRE_AIO);
>>>> +
>>>> +	return err;
>>>> +}
>>>> +
>>>>  static int __get_data_block(struct inode *inode, sector_t iblock,
>>>>  			struct buffer_head *bh, int create, int flag,
>>>>  			pgoff_t *next_pgofs)
>>>> @@ -2082,6 +2096,11 @@ static ssize_t f2fs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
>>>>  
>>>>  	trace_f2fs_direct_IO_enter(inode, offset, count, rw);
>>>>  
>>>> +	/* This is for avoiding the situation that the data of a segment is
>>>> +	 * passed down to devices with different hints
>>>> +	 */
>>>> +	iocb->ki_hint = WRITE_LIFE_NOT_SET;
> 
> Why we need to change this? I'm not sure this will be used later in somewhere,
> if it's not necessary, how about keeping it as it is?
> 

blkdev_direct_IO will pass down this hint to block layer. But we need to control
the hint before this.
So I think that after we implement this control, passing down the hint is better. 

iocb->ki_hint needs to be re-assigned to the orignal hint after the write.
I will handle this.

Thanks

> Thanks,
> 
>>>> +
>>>>  	down_read(&F2FS_I(inode)->dio_rwsem[rw]);
>>>>  	err = blockdev_direct_IO(iocb, inode, iter, get_data_block_dio);
>>>>  	up_read(&F2FS_I(inode)->dio_rwsem[rw]);
>>>> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
>>>> index 4b4a72f..9be5658 100644
>>>> --- a/fs/f2fs/f2fs.h
>>>> +++ b/fs/f2fs/f2fs.h
>>>> @@ -2562,6 +2562,7 @@ int lookup_journal_in_cursum(struct f2fs_journal *journal, int type,
>>>>  void destroy_segment_manager(struct f2fs_sb_info *sbi);
>>>>  int __init create_segment_manager_caches(void);
>>>>  void destroy_segment_manager_caches(void);
>>>> +int rw_hint_to_seg_type(enum rw_hint hint);
>>>>  
>>>>  /*
>>>>   * checkpoint.c
>>>>
>>>
>>
>> .
>>
> 
> 

  reply	other threads:[~2017-11-13  1:48 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-09  5:51 [RFC PATCH 0/2] apply write hints to select the type of segments Hyunchul Lee
2017-11-09  5:51 ` [RFC PATHC 1/2] f2fs: apply write hints to select the type of segments for buffered write Hyunchul Lee
2017-11-09  8:21   ` Chao Yu
2017-11-09  8:21     ` Chao Yu
2017-11-09 18:19     ` Jaegeuk Kim
2017-11-09  5:51 ` [RFC PATHC 2/2] f2fs: apply write hints to select the type of segment for direct write Hyunchul Lee
2017-11-11  0:38   ` [f2fs-dev] " Chao Yu
2017-11-13  0:07     ` Hyunchul Lee
2017-11-13  0:07       ` Hyunchul Lee
2017-11-13  1:24       ` Chao Yu
2017-11-13  1:24         ` Chao Yu
2017-11-13  1:48         ` Hyunchul Lee [this message]
2017-11-09  9:12 ` [RFC PATCH 0/2] apply write hints to select the type of segments Chao Yu
2017-11-09  9:12   ` Chao Yu
2017-11-09 18:16   ` Jaegeuk Kim
2017-11-09 18:16     ` Jaegeuk Kim
2017-11-10  2:31     ` Chao Yu
2017-11-10  2:31       ` Chao Yu
2017-11-10  0:23   ` Hyunchul Lee
2017-11-10  6:42     ` Chao Yu
2017-11-10  6:42       ` Chao Yu
2017-11-13  0:24       ` Hyunchul Lee
2017-11-13  0:24         ` Hyunchul Lee
2017-11-13  1:26         ` Chao Yu
2017-11-13  1:26           ` Chao Yu
2017-11-13  1:35           ` Hyunchul Lee
2017-11-13  1:35             ` Hyunchul Lee
2017-11-13  1:59             ` Chao Yu
2017-11-13  1:59               ` Chao Yu
2017-11-13  2:25               ` Hyunchul Lee
2017-11-14  4:20                 ` Jaegeuk Kim
2017-11-14  4:20                   ` Jaegeuk Kim
2017-11-14  6:22                   ` Chao Yu
2017-11-14  6:22                     ` Chao Yu
2017-11-15 16:27                     ` Jaegeuk Kim
2017-11-15 16:27                       ` Jaegeuk Kim
2017-11-16  0:56                       ` Hyunchul Lee
2017-11-16  0:56                         ` Hyunchul Lee
2017-11-16  2:52                         ` Chao Yu
2017-11-16  2:52                           ` Chao Yu
2017-11-16  3:58                           ` Jaegeuk Kim
2017-11-16  3:58                             ` Jaegeuk Kim
2017-11-16  4:35                             ` Hyunchul Lee
2017-11-16  4:35                               ` Hyunchul Lee
2017-11-17 18:53                               ` Jaegeuk Kim
2017-11-20  2:12                                 ` Hyunchul Lee
2017-11-17 17:23 ` Christoph Hellwig
2017-11-17 17:23   ` Christoph Hellwig
2017-11-17 18:36   ` Jaegeuk Kim
2017-11-17 18:36     ` Jaegeuk Kim

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5A08F9ED.6070309@gmail.com \
    --to=hyc.lee@gmail.com \
    --cc=chao@kernel.org \
    --cc=cheol.lee@lge.com \
    --cc=jaegeuk@kernel.org \
    --cc=kernel-team@lge.com \
    --cc=linux-f2fs-devel@lists.sourceforge.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=yuchao0@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.