From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752011AbdCANJ2 (ORCPT ); Wed, 1 Mar 2017 08:09:28 -0500 Received: from mail-it0-f67.google.com ([209.85.214.67]:33200 "EHLO mail-it0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751824AbdCANJY (ORCPT ); Wed, 1 Mar 2017 08:09:24 -0500 Subject: Re: [f2fs-dev] [PATCH RFC] f2fs: combine nat_bits and free_nid_bitmap cache To: Chao Yu , jaegeuk@kernel.org References: <20170301091013.82838-1-yuchao0@huawei.com> Cc: chao@kernel.org, linux-kernel@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, Kinglong Mee From: Kinglong Mee Message-ID: Date: Wed, 1 Mar 2017 21:09:14 +0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.7.1 MIME-Version: 1.0 In-Reply-To: <20170301091013.82838-1-yuchao0@huawei.com> Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 3/1/2017 17:10, Chao Yu wrote: > Both nat_bits cache and free_nid_bitmap cache provide same functionality > as a intermediate cache between free nid cache and disk, but with > different granularity of indicating free nid range, and different > persistence policy. nat_bits cache provides better persistence ability, > and free_nid_bitmap provides better granularity. > > In this patch we combine advantage of both caches, so finally policy of > the intermediate cache would be: > - init: load free nid status from nat_bits into free_nid_bitmap > - lookup: scan free_nid_bitmap before load NAT blocks Why not scan the full_nat_bits/empty_nat_bits before load NAT blocks here? If after an objects shrinker, the cached free nid will be empty quickly. thanks, Kinglong Mee > - update: update free_nid_bitmap in real-time > - persistence: udpate and persist nat_bits in checkpoint > > Signed-off-by: Chao Yu > --- > fs/f2fs/node.c | 109 +++++++++++++++++++++------------------------------------ > 1 file changed, 39 insertions(+), 70 deletions(-) > > diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c > index 1a759d45b7e4..6c027b6833f4 100644 > --- a/fs/f2fs/node.c > +++ b/fs/f2fs/node.c > @@ -338,9 +338,6 @@ static void set_node_addr(struct f2fs_sb_info *sbi, struct node_info *ni, > set_nat_flag(e, IS_CHECKPOINTED, false); > __set_nat_cache_dirty(nm_i, e); > > - if (enabled_nat_bits(sbi, NULL) && new_blkaddr == NEW_ADDR) > - clear_bit_le(NAT_BLOCK_OFFSET(ni->nid), nm_i->empty_nat_bits); > - > /* update fsync_mark if its inode nat entry is still alive */ > if (ni->nid != ni->ino) > e = __lookup_nat_cache(nm_i, ni->ino); > @@ -1920,58 +1917,6 @@ static void scan_free_nid_bits(struct f2fs_sb_info *sbi) > up_read(&nm_i->nat_tree_lock); > } > > -static int scan_nat_bits(struct f2fs_sb_info *sbi) > -{ > - struct f2fs_nm_info *nm_i = NM_I(sbi); > - struct page *page; > - unsigned int i = 0; > - nid_t nid; > - > - if (!enabled_nat_bits(sbi, NULL)) > - return -EAGAIN; > - > - down_read(&nm_i->nat_tree_lock); > -check_empty: > - i = find_next_bit_le(nm_i->empty_nat_bits, nm_i->nat_blocks, i); > - if (i >= nm_i->nat_blocks) { > - i = 0; > - goto check_partial; > - } > - > - for (nid = i * NAT_ENTRY_PER_BLOCK; nid < (i + 1) * NAT_ENTRY_PER_BLOCK; > - nid++) { > - if (unlikely(nid >= nm_i->max_nid)) > - break; > - add_free_nid(sbi, nid, true); > - } > - > - if (nm_i->nid_cnt[FREE_NID_LIST] >= MAX_FREE_NIDS) > - goto out; > - i++; > - goto check_empty; > - > -check_partial: > - i = find_next_zero_bit_le(nm_i->full_nat_bits, nm_i->nat_blocks, i); > - if (i >= nm_i->nat_blocks) { > - disable_nat_bits(sbi, true); > - up_read(&nm_i->nat_tree_lock); > - return -EINVAL; > - } > - > - nid = i * NAT_ENTRY_PER_BLOCK; > - page = get_current_nat_page(sbi, nid); > - scan_nat_page(sbi, page, nid); > - f2fs_put_page(page, 1); > - > - if (nm_i->nid_cnt[FREE_NID_LIST] < MAX_FREE_NIDS) { > - i++; > - goto check_partial; > - } > -out: > - up_read(&nm_i->nat_tree_lock); > - return 0; > -} > - > static void __build_free_nids(struct f2fs_sb_info *sbi, bool sync, bool mount) > { > struct f2fs_nm_info *nm_i = NM_I(sbi); > @@ -1993,21 +1938,6 @@ static void __build_free_nids(struct f2fs_sb_info *sbi, bool sync, bool mount) > > if (nm_i->nid_cnt[FREE_NID_LIST]) > return; > - > - /* try to find free nids with nat_bits */ > - if (!scan_nat_bits(sbi) && nm_i->nid_cnt[FREE_NID_LIST]) > - return; > - } > - > - /* find next valid candidate */ > - if (enabled_nat_bits(sbi, NULL)) { > - int idx = find_next_zero_bit_le(nm_i->full_nat_bits, > - nm_i->nat_blocks, 0); > - > - if (idx >= nm_i->nat_blocks) > - set_sbi_flag(sbi, SBI_NEED_FSCK); > - else > - nid = idx * NAT_ENTRY_PER_BLOCK; > } > > /* readahead nat pages to be scanned */ > @@ -2590,6 +2520,41 @@ static int __get_nat_bitmaps(struct f2fs_sb_info *sbi) > return 0; > } > > +inline void load_free_nid_bitmap(struct f2fs_sb_info *sbi) > +{ > + struct f2fs_nm_info *nm_i = NM_I(sbi); > + unsigned int i = 0; > + nid_t nid, last_nid; > + > + for (i = 0; i < nm_i->nat_blocks; i++) { > + i = find_next_bit_le(nm_i->empty_nat_bits, nm_i->nat_blocks, i); > + if (i >= nm_i->nat_blocks) > + break; > + > + set_bit_le(i, nm_i->nat_block_bitmap); > + > + nid = i * NAT_ENTRY_PER_BLOCK; > + last_nid = (i + 1) * NAT_ENTRY_PER_BLOCK; > + > + for (; nid < last_nid; nid++) > + update_free_nid_bitmap(sbi, nid, true, true); > + } > + > + for (i = 0; i < nm_i->nat_blocks; i++) { > + i = find_next_bit_le(nm_i->full_nat_bits, nm_i->nat_blocks, i); > + if (i >= nm_i->nat_blocks) > + break; > + > + set_bit_le(i, nm_i->nat_block_bitmap); > + > + nid = i * NAT_ENTRY_PER_BLOCK; > + last_nid = (i + 1) * NAT_ENTRY_PER_BLOCK; > + > + for (; nid < last_nid; nid++) > + update_free_nid_bitmap(sbi, nid, false, true); > + } > +} > + > static int init_node_manager(struct f2fs_sb_info *sbi) > { > struct f2fs_super_block *sb_raw = F2FS_RAW_SUPER(sbi); > @@ -2672,6 +2637,10 @@ int init_free_nid_cache(struct f2fs_sb_info *sbi) > > spin_lock_init(&nm_i->free_nid_lock); > > + /* load free nid status from nat_bits table */ > + if (enabled_nat_bits(sbi, NULL)) > + load_free_nid_bitmap(sbi); > + > return 0; > } > >