Skip to contentSkip to conversation

f2fs: obsolete free nid list approach

PATCH New Chao Yu 1 participant 1 message Nov 23, 2017 F2FS file system

lore
Share & tools
lore

Chao Yu

author maintainer
#0 lore raw

PATCH 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
index a30024f2a567..69559b199983 100644
@@ -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
index 674f9bbe98d9..600a7d0b236c 100644
@@ -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
index 70a982435960..3364036f95b8 100644
@@ -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
index 9684d53563f1..82f543e5c35b 100644
@@ -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
index 0ee3e5ff49a3..d5cf8af70c90 100644
@@ -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
index c117e0913f2a..1fec35ee096d 100644
@@ -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
index 0b5664a1a6cc..7123bcb3cb62 100644
@@ -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