f2fs: obsolete free nid list approach
Chao Yu
maintainerPATCH v3 1/1 f2fs: obsolete free nid list approach
From: Chao Yu <[email protected]>
Previously, we use free nid list to manage free nid entry, so during nid allocation, we can just pick up one entry from list header, which has quite low overhead.
But sadly, during initialization of free nid list, we should do lookup combining with lots of different inner caches, including NAT page cache, nat entry cache, curseg journal cache and free nid bitmap, so flow became quite complicated.
In this patch, we choose to obsolete old free nid management approach, instead, we use existing free nid bitmap which has the same functionality to manage free nid, in order to make free nid management codes more easy to maintain.
---
v3:
- remove debug log.
fs/f2fs/checkpoint.c | 1 - fs/f2fs/debug.c | 7 +- fs/f2fs/f2fs.h | 10 +- fs/f2fs/inode.c | 2 + fs/f2fs/node.c | 483 +++++++++++++++++---------------------------------- fs/f2fs/node.h | 22 --- fs/f2fs/segment.c | 5 - fs/f2fs/shrinker.c | 14 -- 8 files changed, 162 insertions(+), 382 deletions(-)
fs/f2fs/checkpoint.c +0 -1
@@ -1024,7 +1024,6 @@ static void __prepare_cp_block(struct f2fs_sb_info *sbi)struct f2fs_nm_info *nm_i =NM_I (sbi);nid_t last_nid = nm_i->next_scan_nid; -next_free_nid (sbi, &last_nid); ckpt->valid_block_count =cpu_to_le64 (valid_user_blocks (sbi)); ckpt->valid_node_count =cpu_to_le32 (valid_node_count (sbi)); ckpt->valid_inode_count =cpu_to_le32 (valid_inode_count (sbi));
fs/f2fs/debug.c +1 -6
@@ -100,9 +100,8 @@ static void update_general_status(struct f2fs_sb_info *sbi) si->dirty_nats =NM_I (sbi)->dirty_nat_cnt; si->sits =MAIN_SEGS (sbi); si->dirty_sits =SIT_I (sbi)->dirty_sentries; - si->free_nids =NM_I (sbi)->nid_cnt[FREE_NID ]; + si->free_nids =NM_I (sbi)->total_free_nid_count; si->avail_nids =NM_I (sbi)->available_nids; - si->alloc_nids =NM_I (sbi)->nid_cnt[PREALLOC_NID ]; si->bg_gc = sbi->bg_gc; si->util_free = (int )(free_user_blocks (sbi) >> sbi->log_blocks_per_seg) *100 / (int )(sbi->user_block_count >> sbi->log_blocks_per_seg)
@@ -233,10 +232,6 @@ static void update_mem_info(struct f2fs_sb_info *sbi)atomic_read (&SM_I (sbi)->dcc_info->discard_cmd_cnt); } -/* free nids */ - si->cache_mem += (NM_I (sbi)->nid_cnt[FREE_NID ] + -NM_I (sbi)->nid_cnt[PREALLOC_NID ]) * -sizeof (struct free_nid ); si->cache_mem +=NM_I (sbi)->nat_cnt *sizeof (struct nat_entry ); si->cache_mem +=NM_I (sbi)->dirty_nat_cnt *sizeof (struct nat_entry_set );
fs/f2fs/f2fs.h +4 -6
@@ -721,14 +721,13 @@ struct f2fs_nm_info {unsigned int nat_blocks;/* # of nat blocks */ /* free node ids management */ -struct radix_tree_root free_nid_root;/* root of the free_nid cache */ -struct list_head free_nid_list;/* list for free nids excluding preallocated nids */ -unsigned int nid_cnt[MAX_NID_STATE ];/* the number of free node id */ -spinlock_t nid_list_lock;/* protect nid lists ops */ +spinlock_t free_nid_lock;/* protect nid lists ops */ struct mutex build_lock;/* lock for build free nids */ unsigned char (*free_nid_bitmap)[NAT_ENTRY_BITMAP_SIZE ]; +unsigned char (*prealloc_nid_bitmap)[NAT_ENTRY_BITMAP_SIZE ];unsigned char *nat_block_bitmap;unsigned short *free_nid_count;/* free nid count of NAT block */ +unsigned int total_free_nid_count;/* total free nid count in bitmap */ /* for checkpoint */ char *nat_bitmap;/* NAT bitmap pointer */
@@ -2602,11 +2601,10 @@ int fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode, struct writeback_control *wbc, bool atomic);int sync_node_pages (struct f2fs_sb_info *sbi,struct writeback_control *wbc,bool do_balance,enum iostat_type io_type); -void build_free_nids (struct f2fs_sb_info *sbi,bool sync,bool mount); +void build_free_nids (struct f2fs_sb_info *sbi,bool mount);bool alloc_nid (struct f2fs_sb_info *sbi,nid_t *nid);void alloc_nid_done (struct f2fs_sb_info *sbi,nid_t nid);void alloc_nid_failed (struct f2fs_sb_info *sbi,nid_t nid); -int try_to_free_nids (struct f2fs_sb_info *sbi,int nr_shrink);void recover_inline_xattr (struct inode *inode,struct page *page);int recover_xattr_data (struct inode *inode,struct page *page,block_t blkaddr);
fs/f2fs/inode.c +2 -0
@@ -559,7 +559,9 @@ void f2fs_evict_inode(struct inode *inode)add_ino_entry (sbi, inode->i_ino,UPDATE_INO ); }if (is_inode_flag_set (inode,FI_FREE_NID )) { +f2fs_lock_op (sbi);alloc_nid_failed (sbi, inode->i_ino); +f2fs_unlock_op (sbi);clear_inode_flag (inode,FI_FREE_NID ); }else { f2fs_bug_on(sbi, err &&
fs/f2fs/node.c +155 -328
745 lines not on this page · raw message
fs/f2fs/node.h +0 -22
@@ -135,7 +135,6 @@ static inline bool excess_cached_nats(struct f2fs_sb_info *sbi) }enum mem_type { -FREE_NIDS ,/* indicates the free nid list */ NAT_ENTRIES ,/* indicates the cached nat entry */ DIRTY_DENTS ,/* indicates dirty dentry pages */ INO_ENTRIES ,/* indicates inode entries */
@@ -151,27 +150,6 @@ struct nat_entry_set {unsigned int entry_cnt;/* the # of nat entries in set */ }; -struct free_nid { -struct list_head list;/* for free node id list */ -nid_t nid;/* node id */ -int state;/* in use or not: FREE_NID or PREALLOC_NID */ -}; - -static inline void next_free_nid (struct f2fs_sb_info *sbi,nid_t *nid) -{ -struct f2fs_nm_info *nm_i =NM_I (sbi); -struct free_nid *fnid; - -spin_lock (&nm_i->nid_list_lock); -if (nm_i->nid_cnt[FREE_NID ] <=0 ) { -spin_unlock (&nm_i->nid_list_lock); -return ; - } - fnid = list_first_entry(&nm_i->free_nid_list, struct free_nid, list); - *nid = fnid->nid; -spin_unlock (&nm_i->nid_list_lock); -} -/* * inline functions */
fs/f2fs/segment.c +0 -5
@@ -482,11 +482,6 @@ void f2fs_balance_fs_bg(struct f2fs_sb_info *sbi)if (!available_free_memory (sbi,NAT_ENTRIES ))try_to_free_nats (sbi,NAT_ENTRY_PER_BLOCK ); -if (!available_free_memory (sbi,FREE_NIDS )) -try_to_free_nids (sbi,MAX_FREE_NIDS ); -else -build_free_nids (sbi, false, false); -if (!is_idle (sbi) && !excess_dirty_nats (sbi))return ;
fs/f2fs/shrinker.c +0 -14
@@ -26,13 +26,6 @@ static unsigned long __count_nat_entries(struct f2fs_sb_info *sbi)return count >0 ? count :0 ; } -static unsigned long __count_free_nids (struct f2fs_sb_info *sbi) -{ -long count =NM_I (sbi)->nid_cnt[FREE_NID ] -MAX_FREE_NIDS ; - -return count >0 ? count :0 ; -} -static unsigned long __count_extent_cache (struct f2fs_sb_info *sbi) { return atomic_read(&sbi->total_zombie_tree) +
@@ -64,9 +57,6 @@ unsigned long f2fs_shrink_count(struct shrinker *shrink,/* shrink clean nat cache entries */ count +=__count_nat_entries (sbi); -/* count free nids cache entries */ - count +=__count_free_nids (sbi); -spin_lock (&f2fs_list_lock); p = p->next;mutex_unlock (&sbi->umount_mutex);
@@ -111,10 +101,6 @@ unsigned long f2fs_shrink_scan(struct shrinker *shrink,if (freed < nr) freed +=try_to_free_nats (sbi, nr - freed); -/* shrink free nids cache entries */ -if (freed < nr) - freed +=try_to_free_nids (sbi, nr - freed); -spin_lock (&f2fs_list_lock); p = p->next;list_move_tail (&sbi->s_list, &f2fs_list);
Signature · 1 line
2.14.1.145.gb3622a4ee