Linux-f2fs-devel Archive on lore.kernel.org
 help / color / Atom feed
* [f2fs-dev] [PATCH 1/2] f2fs: split f2fs_allocate_new_segments()
@ 2020-06-22  9:38 Chao Yu
  2020-06-22  9:38 ` [f2fs-dev] [PATCH 2/2] f2fs: introduce inmem curseg Chao Yu
  2020-06-29 20:19 ` [f2fs-dev] [PATCH 1/2] f2fs: split f2fs_allocate_new_segments() Jaegeuk Kim
  0 siblings, 2 replies; 6+ messages in thread
From: Chao Yu @ 2020-06-22  9:38 UTC (permalink / raw)
  To: jaegeuk; +Cc: linux-kernel, linux-f2fs-devel

to two independent functions:
- f2fs_allocate_new_segment() for specified type segment allocation
- f2fs_allocate_new_segments() for all data type segments allocation

Signed-off-by: Chao Yu <yuchao0@huawei.com>
---
 fs/f2fs/f2fs.h     |  3 ++-
 fs/f2fs/file.c     |  2 +-
 fs/f2fs/recovery.c |  2 +-
 fs/f2fs/segment.c  | 39 +++++++++++++++++++++++----------------
 4 files changed, 27 insertions(+), 19 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 70565d81320b..07290943e91d 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -3327,7 +3327,8 @@ void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
 int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
 void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
 					unsigned int start, unsigned int end);
-void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi, int type);
+void f2fs_allocate_new_segment(struct f2fs_sb_info *sbi, int type);
+void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi);
 int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range);
 bool f2fs_exist_trim_candidates(struct f2fs_sb_info *sbi,
 					struct cp_control *cpc);
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index f196187159e9..67c65e40b22b 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -1659,7 +1659,7 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
 		map.m_seg_type = CURSEG_COLD_DATA_PINNED;
 
 		f2fs_lock_op(sbi);
-		f2fs_allocate_new_segments(sbi, CURSEG_COLD_DATA);
+		f2fs_allocate_new_segment(sbi, CURSEG_COLD_DATA_PINNED);
 		f2fs_unlock_op(sbi);
 
 		err = f2fs_map_blocks(inode, &map, 1, F2FS_GET_BLOCK_PRE_DIO);
diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
index ae5310f02e7f..af974ba273b3 100644
--- a/fs/f2fs/recovery.c
+++ b/fs/f2fs/recovery.c
@@ -742,7 +742,7 @@ static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list,
 		f2fs_put_page(page, 1);
 	}
 	if (!err)
-		f2fs_allocate_new_segments(sbi, NO_CHECK_TYPE);
+		f2fs_allocate_new_segments(sbi);
 	return err;
 }
 
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 113114f98087..f15711e8ee5b 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -2707,28 +2707,35 @@ void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
 	up_read(&SM_I(sbi)->curseg_lock);
 }
 
-void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi, int type)
+void __allocate_new_segment(struct f2fs_sb_info *sbi, int type)
 {
-	struct curseg_info *curseg;
+	struct curseg_info *curseg = CURSEG_I(sbi, type);
 	unsigned int old_segno;
-	int i;
 
-	down_write(&SIT_I(sbi)->sentry_lock);
+	if (!curseg->next_blkoff &&
+		!get_valid_blocks(sbi, curseg->segno, false) &&
+		!get_ckpt_valid_blocks(sbi, curseg->segno))
+		return;
 
-	for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
-		if (type != NO_CHECK_TYPE && i != type)
-			continue;
+	old_segno = curseg->segno;
+	SIT_I(sbi)->s_ops->allocate_segment(sbi, type, true);
+	locate_dirty_segment(sbi, old_segno);
+}
 
-		curseg = CURSEG_I(sbi, i);
-		if (type == NO_CHECK_TYPE || curseg->next_blkoff ||
-				get_valid_blocks(sbi, curseg->segno, false) ||
-				get_ckpt_valid_blocks(sbi, curseg->segno)) {
-			old_segno = curseg->segno;
-			SIT_I(sbi)->s_ops->allocate_segment(sbi, i, true);
-			locate_dirty_segment(sbi, old_segno);
-		}
-	}
+void f2fs_allocate_new_segment(struct f2fs_sb_info *sbi, int type)
+{
+	down_write(&SIT_I(sbi)->sentry_lock);
+	__allocate_new_segment(sbi, type);
+	up_write(&SIT_I(sbi)->sentry_lock);
+}
 
+void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi)
+{
+	int i;
+
+	down_write(&SIT_I(sbi)->sentry_lock);
+	for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++)
+		__allocate_new_segment(sbi, i);
 	up_write(&SIT_I(sbi)->sentry_lock);
 }
 
-- 
2.26.2



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [f2fs-dev] [PATCH 2/2] f2fs: introduce inmem curseg
  2020-06-22  9:38 [f2fs-dev] [PATCH 1/2] f2fs: split f2fs_allocate_new_segments() Chao Yu
@ 2020-06-22  9:38 ` Chao Yu
  2020-06-29 20:19 ` [f2fs-dev] [PATCH 1/2] f2fs: split f2fs_allocate_new_segments() Jaegeuk Kim
  1 sibling, 0 replies; 6+ messages in thread
From: Chao Yu @ 2020-06-22  9:38 UTC (permalink / raw)
  To: jaegeuk; +Cc: linux-kernel, linux-f2fs-devel

Previous implementation of aligned pinfile allocation will:
- allocate new segment on cold data log no matter whether last used
segment is partially used or not, it makes IOs more random;
- force concurrent cold data/GCed IO going into warm data area, it
can make a bad effect on hot/cold data separation;

In this patch, we introduce a new type of log named 'inmem curseg',
the differents from normal curseg is:
- it reuses existed segment type (CURSEG_XXX_NODE/DATA);
- it only exists in memory, its segno, blkofs, summary will not b
 persisted into checkpoint area;

With this new feature, we can enhance scalability of log, special
allocators can be created for purposes:
- pure lfs allocator for aligned pinfile allocation or file
defragmentation
- pure ssr allocator for later feature

So that, let's update aligned pinfile allocation to use this new
inmem curseg fwk.

Signed-off-by: Chao Yu <yuchao0@huawei.com>
---
 fs/f2fs/checkpoint.c |   7 ++-
 fs/f2fs/debug.c      |   6 ++-
 fs/f2fs/f2fs.h       |  12 +++--
 fs/f2fs/file.c       |   3 +-
 fs/f2fs/gc.c         |   2 +-
 fs/f2fs/segment.c    | 107 ++++++++++++++++++++++++++++++-------------
 fs/f2fs/segment.h    |  17 ++++---
 fs/f2fs/super.c      |   9 ++--
 8 files changed, 112 insertions(+), 51 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 236064930251..bb9eb67d48f9 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -1616,11 +1616,16 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
 
 	f2fs_flush_sit_entries(sbi, cpc);
 
+	/* save inmem log status */
+	f2fs_save_inmem_curseg(sbi, CURSEG_COLD_DATA_PINNED);
+
 	err = do_checkpoint(sbi, cpc);
 	if (err)
 		f2fs_release_discard_addrs(sbi);
 	else
 		f2fs_clear_prefree_segments(sbi, cpc);
+
+	f2fs_restore_inmem_curseg(sbi, CURSEG_COLD_DATA_PINNED);
 stop:
 	unblock_operations(sbi);
 	stat_inc_cp_count(sbi->stat_info);
@@ -1651,7 +1656,7 @@ void f2fs_init_ino_entry_info(struct f2fs_sb_info *sbi)
 	}
 
 	sbi->max_orphans = (sbi->blocks_per_seg - F2FS_CP_PACKS -
-			NR_CURSEG_TYPE - __cp_payload(sbi)) *
+			NR_CURSEG_PERSIST_TYPE - __cp_payload(sbi)) *
 				F2FS_ORPHANS_PER_BLOCK;
 }
 
diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
index aa1fd2de11ba..2baee449ebb7 100644
--- a/fs/f2fs/debug.c
+++ b/fs/f2fs/debug.c
@@ -164,7 +164,7 @@ static void update_general_status(struct f2fs_sb_info *sbi)
 		* 100 / (int)(sbi->user_block_count >> sbi->log_blocks_per_seg)
 		/ 2;
 	si->util_invalid = 50 - si->util_free - si->util_valid;
-	for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_NODE; i++) {
+	for (i = CURSEG_HOT_DATA; i < NO_CHECK_TYPE; i++) {
 		struct curseg_info *curseg = CURSEG_I(sbi, i);
 		si->curseg[i] = curseg->segno;
 		si->cursec[i] = GET_SEC_FROM_SEG(sbi, curseg->segno);
@@ -396,6 +396,10 @@ static int stat_show(struct seq_file *s, void *v)
 			   si->dirty_seg[CURSEG_COLD_NODE],
 			   si->full_seg[CURSEG_COLD_NODE],
 			   si->valid_blks[CURSEG_COLD_NODE]);
+		seq_printf(s, "  - Pinned file: %8d %8d %8d\n",
+			   si->curseg[CURSEG_COLD_DATA_PINNED],
+			   si->cursec[CURSEG_COLD_DATA_PINNED],
+			   si->curzone[CURSEG_COLD_DATA_PINNED]);
 		seq_printf(s, "\n  - Valid: %d\n  - Dirty: %d\n",
 			   si->main_area_segs - si->dirty_count -
 			   si->prefree_count - si->free_segs,
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 07290943e91d..13ddcaf8aefe 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -980,7 +980,9 @@ static inline void set_new_dnode(struct dnode_of_data *dn, struct inode *inode,
  */
 #define	NR_CURSEG_DATA_TYPE	(3)
 #define NR_CURSEG_NODE_TYPE	(3)
-#define NR_CURSEG_TYPE	(NR_CURSEG_DATA_TYPE + NR_CURSEG_NODE_TYPE)
+#define NR_CURSEG_INMEM_TYPE	(1)
+#define NR_CURSEG_PERSIST_TYPE	(NR_CURSEG_DATA_TYPE + NR_CURSEG_NODE_TYPE)
+#define NR_CURSEG_TYPE		(NR_CURSEG_INMEM_TYPE + NR_CURSEG_PERSIST_TYPE)
 
 enum {
 	CURSEG_HOT_DATA	= 0,	/* directory entry blocks */
@@ -989,8 +991,10 @@ enum {
 	CURSEG_HOT_NODE,	/* direct node blocks of directory files */
 	CURSEG_WARM_NODE,	/* direct node blocks of normal files */
 	CURSEG_COLD_NODE,	/* indirect node blocks */
-	NO_CHECK_TYPE,
-	CURSEG_COLD_DATA_PINNED,/* cold data for pinned file */
+	NR_PERSISTENT_LOG,	/* number of persistent log */
+	CURSEG_COLD_DATA_PINNED = NR_PERSISTENT_LOG,
+				/* pinned file that needs consecutive block address */
+	NO_CHECK_TYPE,		/* number of persistent & inmem log */
 };
 
 struct flush_cmd {
@@ -3325,6 +3329,8 @@ block_t f2fs_get_unusable_blocks(struct f2fs_sb_info *sbi);
 int f2fs_disable_cp_again(struct f2fs_sb_info *sbi, block_t unusable);
 void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
 int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
+void f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi, int type);
+void f2fs_restore_inmem_curseg(struct f2fs_sb_info *sbi, int type);
 void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
 					unsigned int start, unsigned int end);
 void f2fs_allocate_new_segment(struct f2fs_sb_info *sbi, int type);
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 67c65e40b22b..882b5739072b 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -1656,13 +1656,14 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
 		}
 
 		down_write(&sbi->pin_sem);
-		map.m_seg_type = CURSEG_COLD_DATA_PINNED;
 
 		f2fs_lock_op(sbi);
 		f2fs_allocate_new_segment(sbi, CURSEG_COLD_DATA_PINNED);
 		f2fs_unlock_op(sbi);
 
+		map.m_seg_type = CURSEG_COLD_DATA_PINNED;
 		err = f2fs_map_blocks(inode, &map, 1, F2FS_GET_BLOCK_PRE_DIO);
+
 		up_write(&sbi->pin_sem);
 
 		done += map.m_len;
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index bfc4eb2d8038..138aa99b9903 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1433,7 +1433,7 @@ static int free_segment_range(struct f2fs_sb_info *sbi,
 	mutex_unlock(&DIRTY_I(sbi)->seglist_lock);
 
 	/* Move out cursegs from the target range */
-	for (type = CURSEG_HOT_DATA; type < NR_CURSEG_TYPE; type++)
+	for (type = CURSEG_HOT_DATA; type < NR_CURSEG_PERSIST_TYPE; type++)
 		f2fs_allocate_segment_for_resize(sbi, type, start, end);
 
 	/* do GC to move out valid blocks in the range */
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index f15711e8ee5b..d28db812c66b 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -1932,7 +1932,7 @@ static void set_prefree_as_free_segments(struct f2fs_sb_info *sbi)
 
 	mutex_lock(&dirty_i->seglist_lock);
 	for_each_set_bit(segno, dirty_i->dirty_segmap[PRE], MAIN_SEGS(sbi))
-		__set_test_and_free(sbi, segno);
+		__set_test_and_free(sbi, segno, false);
 	mutex_unlock(&dirty_i->seglist_lock);
 }
 
@@ -2470,6 +2470,7 @@ static void reset_curseg(struct f2fs_sb_info *sbi, int type, int modified)
 	struct curseg_info *curseg = CURSEG_I(sbi, type);
 	struct summary_footer *sum_footer;
 
+	curseg->inited = true;
 	curseg->segno = curseg->next_segno;
 	curseg->zone = GET_ZONE_FROM_SEG(sbi, curseg->segno);
 	curseg->next_blkoff = 0;
@@ -2477,24 +2478,31 @@ static void reset_curseg(struct f2fs_sb_info *sbi, int type, int modified)
 
 	sum_footer = &(curseg->sum_blk->footer);
 	memset(sum_footer, 0, sizeof(struct summary_footer));
-	if (IS_DATASEG(type))
+	if (IS_DATASEG(curseg->seg_type))
 		SET_SUM_TYPE(sum_footer, SUM_TYPE_DATA);
-	if (IS_NODESEG(type))
+	if (IS_NODESEG(curseg->seg_type))
 		SET_SUM_TYPE(sum_footer, SUM_TYPE_NODE);
-	__set_sit_entry_type(sbi, type, curseg->segno, modified);
+	__set_sit_entry_type(sbi, curseg->seg_type, curseg->segno, modified);
 }
 
 static unsigned int __get_next_segno(struct f2fs_sb_info *sbi, int type)
 {
+	struct curseg_info *curseg = CURSEG_I(sbi, type);
+
 	/* if segs_per_sec is large than 1, we need to keep original policy. */
 	if (__is_large_section(sbi))
-		return CURSEG_I(sbi, type)->segno;
+		return curseg->segno;
+
+	/* inmem log may not locate on any segment after mount */
+	if (!curseg->inited)
+		return 0;
 
 	if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED)))
 		return 0;
 
 	if (test_opt(sbi, NOHEAP) &&
-		(type == CURSEG_HOT_DATA || IS_NODESEG(type)))
+		(curseg->seg_type == CURSEG_HOT_DATA ||
+		IS_NODESEG(curseg->seg_type)))
 		return 0;
 
 	if (SIT_I(sbi)->last_victim[ALLOC_NEXT])
@@ -2504,7 +2512,7 @@ static unsigned int __get_next_segno(struct f2fs_sb_info *sbi, int type)
 	if (F2FS_OPTION(sbi).alloc_mode == ALLOC_MODE_REUSE)
 		return 0;
 
-	return CURSEG_I(sbi, type)->segno;
+	return curseg->segno;
 }
 
 /*
@@ -2514,12 +2522,14 @@ static unsigned int __get_next_segno(struct f2fs_sb_info *sbi, int type)
 static void new_curseg(struct f2fs_sb_info *sbi, int type, bool new_sec)
 {
 	struct curseg_info *curseg = CURSEG_I(sbi, type);
+	unsigned short seg_type = curseg->seg_type;
 	unsigned int segno = curseg->segno;
 	int dir = ALLOC_LEFT;
 
-	write_sum_page(sbi, curseg->sum_blk,
+	if (curseg->inited)
+		write_sum_page(sbi, curseg->sum_blk,
 				GET_SUM_BLOCK(sbi, segno));
-	if (type == CURSEG_WARM_DATA || type == CURSEG_COLD_DATA)
+	if (seg_type == CURSEG_WARM_DATA || seg_type == CURSEG_COLD_DATA)
 		dir = ALLOC_RIGHT;
 
 	if (test_opt(sbi, NOHEAP))
@@ -2596,6 +2606,43 @@ static void change_curseg(struct f2fs_sb_info *sbi, int type)
 	f2fs_put_page(sum_page, 1);
 }
 
+void f2fs_save_inmem_curseg(struct f2fs_sb_info *sbi, int type)
+{
+	struct curseg_info *curseg = CURSEG_I(sbi, type);
+
+	mutex_lock(&curseg->curseg_mutex);
+	if (!curseg->inited)
+		goto out;
+
+	if (get_valid_blocks(sbi, curseg->segno, false)) {
+		write_sum_page(sbi, curseg->sum_blk,
+				GET_SUM_BLOCK(sbi, curseg->segno));
+	} else {
+		mutex_lock(&DIRTY_I(sbi)->seglist_lock);
+		__set_test_and_free(sbi, curseg->segno, true);
+		mutex_unlock(&DIRTY_I(sbi)->seglist_lock);
+	}
+out:
+	mutex_unlock(&curseg->curseg_mutex);
+}
+
+void f2fs_restore_inmem_curseg(struct f2fs_sb_info *sbi, int type)
+{
+	struct curseg_info *curseg = CURSEG_I(sbi, type);
+
+	mutex_lock(&curseg->curseg_mutex);
+	if (!curseg->inited)
+		goto out;
+	if (get_valid_blocks(sbi, curseg->segno, false))
+		goto out;
+
+	mutex_lock(&DIRTY_I(sbi)->seglist_lock);
+	__set_test_and_inuse(sbi, curseg->segno);
+	mutex_unlock(&DIRTY_I(sbi)->seglist_lock);
+out:
+	mutex_unlock(&curseg->curseg_mutex);
+}
+
 static int get_ssr_segment(struct f2fs_sb_info *sbi, int type)
 {
 	struct curseg_info *curseg = CURSEG_I(sbi, type);
@@ -2712,11 +2759,15 @@ void __allocate_new_segment(struct f2fs_sb_info *sbi, int type)
 	struct curseg_info *curseg = CURSEG_I(sbi, type);
 	unsigned int old_segno;
 
+	if (!curseg->inited)
+		goto alloc;
+
 	if (!curseg->next_blkoff &&
 		!get_valid_blocks(sbi, curseg->segno, false) &&
 		!get_ckpt_valid_blocks(sbi, curseg->segno))
 		return;
 
+alloc:
 	old_segno = curseg->segno;
 	SIT_I(sbi)->s_ops->allocate_segment(sbi, type, true);
 	locate_dirty_segment(sbi, old_segno);
@@ -3100,19 +3151,6 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
 {
 	struct sit_info *sit_i = SIT_I(sbi);
 	struct curseg_info *curseg = CURSEG_I(sbi, type);
-	bool put_pin_sem = false;
-
-	if (type == CURSEG_COLD_DATA) {
-		/* GC during CURSEG_COLD_DATA_PINNED allocation */
-		if (down_read_trylock(&sbi->pin_sem)) {
-			put_pin_sem = true;
-		} else {
-			type = CURSEG_WARM_DATA;
-			curseg = CURSEG_I(sbi, type);
-		}
-	} else if (type == CURSEG_COLD_DATA_PINNED) {
-		type = CURSEG_COLD_DATA;
-	}
 
 	down_read(&SM_I(sbi)->curseg_lock);
 
@@ -3178,9 +3216,6 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
 	mutex_unlock(&curseg->curseg_mutex);
 
 	up_read(&SM_I(sbi)->curseg_lock);
-
-	if (put_pin_sem)
-		up_read(&sbi->pin_sem);
 }
 
 static void update_device_state(struct f2fs_io_info *fio)
@@ -3548,7 +3583,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
 		blk_off = le16_to_cpu(ckpt->cur_data_blkoff[type -
 							CURSEG_HOT_DATA]);
 		if (__exist_node_summaries(sbi))
-			blk_addr = sum_blk_addr(sbi, NR_CURSEG_TYPE, type);
+			blk_addr = sum_blk_addr(sbi, NR_CURSEG_PERSIST_TYPE, type);
 		else
 			blk_addr = sum_blk_addr(sbi, NR_CURSEG_DATA_TYPE, type);
 	} else {
@@ -3626,8 +3661,9 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi)
 	}
 
 	if (__exist_node_summaries(sbi))
-		f2fs_ra_meta_pages(sbi, sum_blk_addr(sbi, NR_CURSEG_TYPE, type),
-					NR_CURSEG_TYPE - type, META_CP, true);
+		f2fs_ra_meta_pages(sbi,
+				sum_blk_addr(sbi, NR_CURSEG_PERSIST_TYPE, type),
+				NR_CURSEG_PERSIST_TYPE - type, META_CP, true);
 
 	for (; type <= CURSEG_COLD_NODE; type++) {
 		err = read_normal_summaries(sbi, type);
@@ -4129,14 +4165,14 @@ static int build_curseg(struct f2fs_sb_info *sbi)
 	struct curseg_info *array;
 	int i;
 
-	array = f2fs_kzalloc(sbi, array_size(NR_CURSEG_TYPE, sizeof(*array)),
-			     GFP_KERNEL);
+	array = f2fs_kzalloc(sbi, array_size(NR_CURSEG_TYPE,
+					sizeof(*array)), GFP_KERNEL);
 	if (!array)
 		return -ENOMEM;
 
 	SM_I(sbi)->curseg_array = array;
 
-	for (i = 0; i < NR_CURSEG_TYPE; i++) {
+	for (i = 0; i < NO_CHECK_TYPE; i++) {
 		mutex_init(&array[i].curseg_mutex);
 		array[i].sum_blk = f2fs_kzalloc(sbi, PAGE_SIZE, GFP_KERNEL);
 		if (!array[i].sum_blk)
@@ -4146,8 +4182,13 @@ static int build_curseg(struct f2fs_sb_info *sbi)
 				sizeof(struct f2fs_journal), GFP_KERNEL);
 		if (!array[i].journal)
 			return -ENOMEM;
+		if (i < NR_PERSISTENT_LOG)
+			array[i].seg_type = CURSEG_HOT_DATA + i;
+		else if (i == CURSEG_COLD_DATA_PINNED)
+			array[i].seg_type = CURSEG_COLD_DATA;
 		array[i].segno = NULL_SEGNO;
 		array[i].next_blkoff = 0;
+		array[i].inited = false;
 	}
 	return restore_curseg_summaries(sbi);
 }
@@ -4357,7 +4398,7 @@ static int sanity_check_curseg(struct f2fs_sb_info *sbi)
 	 * In LFS/SSR curseg, .next_blkoff should point to an unused blkaddr;
 	 * In LFS curseg, all blkaddr after .next_blkoff should be unused.
 	 */
-	for (i = 0; i < NO_CHECK_TYPE; i++) {
+	for (i = 0; i < NR_PERSISTENT_LOG; i++) {
 		struct curseg_info *curseg = CURSEG_I(sbi, i);
 		struct seg_entry *se = get_seg_entry(sbi, curseg->segno);
 		unsigned int blkofs = curseg->next_blkoff;
@@ -4586,7 +4627,7 @@ int f2fs_fix_curseg_write_pointer(struct f2fs_sb_info *sbi)
 {
 	int i, ret;
 
-	for (i = 0; i < NO_CHECK_TYPE; i++) {
+	for (i = 0; i < NR_PERSISTENT_LOG; i++) {
 		ret = fix_curseg_write_pointer(sbi, i);
 		if (ret)
 			return ret;
diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index cba16cca5189..8171fb5ac7e9 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -22,7 +22,7 @@
 #define GET_R2L_SEGNO(free_i, segno)	((segno) + (free_i)->start_segno)
 
 #define IS_DATASEG(t)	((t) <= CURSEG_COLD_DATA)
-#define IS_NODESEG(t)	((t) >= CURSEG_HOT_NODE)
+#define IS_NODESEG(t)	((t) >= CURSEG_HOT_NODE && (t) <= CURSEG_COLD_NODE)
 
 #define IS_HOT(t)	((t) == CURSEG_HOT_NODE || (t) == CURSEG_HOT_DATA)
 #define IS_WARM(t)	((t) == CURSEG_WARM_NODE || (t) == CURSEG_WARM_DATA)
@@ -34,7 +34,8 @@
 	 ((seg) == CURSEG_I(sbi, CURSEG_COLD_DATA)->segno) ||	\
 	 ((seg) == CURSEG_I(sbi, CURSEG_HOT_NODE)->segno) ||	\
 	 ((seg) == CURSEG_I(sbi, CURSEG_WARM_NODE)->segno) ||	\
-	 ((seg) == CURSEG_I(sbi, CURSEG_COLD_NODE)->segno))
+	 ((seg) == CURSEG_I(sbi, CURSEG_COLD_NODE)->segno) ||	\
+	 ((seg) == CURSEG_I(sbi, CURSEG_COLD_DATA_PINNED)->segno))
 
 #define IS_CURSEC(sbi, secno)						\
 	(((secno) == CURSEG_I(sbi, CURSEG_HOT_DATA)->segno /		\
@@ -48,7 +49,9 @@
 	 ((secno) == CURSEG_I(sbi, CURSEG_WARM_NODE)->segno /		\
 	  (sbi)->segs_per_sec) ||	\
 	 ((secno) == CURSEG_I(sbi, CURSEG_COLD_NODE)->segno /		\
-	  (sbi)->segs_per_sec))	\
+	  (sbi)->segs_per_sec) ||	\
+	 ((secno) == CURSEG_I(sbi, CURSEG_COLD_DATA_PINNED)->segno /	\
+	  (sbi)->segs_per_sec))
 
 #define MAIN_BLKADDR(sbi)						\
 	(SM_I(sbi) ? SM_I(sbi)->main_blkaddr : 				\
@@ -284,10 +287,12 @@ struct curseg_info {
 	struct rw_semaphore journal_rwsem;	/* protect journal area */
 	struct f2fs_journal *journal;		/* cached journal info */
 	unsigned char alloc_type;		/* current allocation type */
+	unsigned short seg_type;		/* segment type like CURSEG_XXX_TYPE */
 	unsigned int segno;			/* current segment number */
 	unsigned short next_blkoff;		/* next block offset to write */
 	unsigned int zone;			/* current zone number */
 	unsigned int next_segno;		/* preallocated segment */
+	bool inited;				/* indicate inmem log is inited */
 };
 
 struct sit_entry_set {
@@ -301,8 +306,6 @@ struct sit_entry_set {
  */
 static inline struct curseg_info *CURSEG_I(struct f2fs_sb_info *sbi, int type)
 {
-	if (type == CURSEG_COLD_DATA_PINNED)
-		type = CURSEG_COLD_DATA;
 	return (struct curseg_info *)(SM_I(sbi)->curseg_array + type);
 }
 
@@ -434,7 +437,7 @@ static inline void __set_inuse(struct f2fs_sb_info *sbi,
 }
 
 static inline void __set_test_and_free(struct f2fs_sb_info *sbi,
-		unsigned int segno)
+		unsigned int segno, bool inmem)
 {
 	struct free_segmap_info *free_i = FREE_I(sbi);
 	unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
@@ -445,7 +448,7 @@ static inline void __set_test_and_free(struct f2fs_sb_info *sbi,
 	if (test_and_clear_bit(segno, free_i->free_segmap)) {
 		free_i->free_segments++;
 
-		if (IS_CURSEC(sbi, secno))
+		if (!inmem && IS_CURSEC(sbi, secno))
 			goto skip_free;
 		next = find_next_bit(free_i->free_segmap,
 				start_segno + sbi->segs_per_sec, start_segno);
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 426cebdd84e5..218df80273e2 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -575,7 +575,8 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
 		case Opt_active_logs:
 			if (args->from && match_int(args, &arg))
 				return -EINVAL;
-			if (arg != 2 && arg != 4 && arg != NR_CURSEG_TYPE)
+			if (arg != 2 && arg != 4 &&
+				arg != NR_CURSEG_PERSIST_TYPE)
 				return -EINVAL;
 			F2FS_OPTION(sbi).active_logs = arg;
 			break;
@@ -981,7 +982,7 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
 	}
 
 	/* Not pass down write hints if the number of active logs is lesser
-	 * than NR_CURSEG_TYPE.
+	 * than NR_CURSEG_PERSIST_TYPE.
 	 */
 	if (F2FS_OPTION(sbi).active_logs != NR_CURSEG_TYPE)
 		F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF;
@@ -1612,7 +1613,7 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
 static void default_options(struct f2fs_sb_info *sbi)
 {
 	/* init some FS parameters */
-	F2FS_OPTION(sbi).active_logs = NR_CURSEG_TYPE;
+	F2FS_OPTION(sbi).active_logs = NR_CURSEG_PERSIST_TYPE;
 	F2FS_OPTION(sbi).inline_xattr_size = DEFAULT_INLINE_XATTR_ADDRS;
 	F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF;
 	F2FS_OPTION(sbi).alloc_mode = ALLOC_MODE_DEFAULT;
@@ -2944,7 +2945,7 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi)
 	cp_payload = __cp_payload(sbi);
 	if (cp_pack_start_sum < cp_payload + 1 ||
 		cp_pack_start_sum > blocks_per_seg - 1 -
-			NR_CURSEG_TYPE) {
+			NR_CURSEG_PERSIST_TYPE) {
 		f2fs_err(sbi, "Wrong cp_pack_start_sum: %u",
 			 cp_pack_start_sum);
 		return 1;
-- 
2.26.2



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [f2fs-dev] [PATCH 1/2] f2fs: split f2fs_allocate_new_segments()
  2020-06-22  9:38 [f2fs-dev] [PATCH 1/2] f2fs: split f2fs_allocate_new_segments() Chao Yu
  2020-06-22  9:38 ` [f2fs-dev] [PATCH 2/2] f2fs: introduce inmem curseg Chao Yu
@ 2020-06-29 20:19 ` Jaegeuk Kim
  2020-06-30  1:21   ` Chao Yu
  2020-07-01  1:31   ` Chao Yu
  1 sibling, 2 replies; 6+ messages in thread
From: Jaegeuk Kim @ 2020-06-29 20:19 UTC (permalink / raw)
  To: Chao Yu; +Cc: linux-kernel, linux-f2fs-devel

On 06/22, Chao Yu wrote:
> to two independent functions:
> - f2fs_allocate_new_segment() for specified type segment allocation
> - f2fs_allocate_new_segments() for all data type segments allocation
> 
> Signed-off-by: Chao Yu <yuchao0@huawei.com>
> ---
>  fs/f2fs/f2fs.h     |  3 ++-
>  fs/f2fs/file.c     |  2 +-
>  fs/f2fs/recovery.c |  2 +-
>  fs/f2fs/segment.c  | 39 +++++++++++++++++++++++----------------
>  4 files changed, 27 insertions(+), 19 deletions(-)
> 
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 70565d81320b..07290943e91d 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -3327,7 +3327,8 @@ void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
>  int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
>  void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
>  					unsigned int start, unsigned int end);
> -void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi, int type);
> +void f2fs_allocate_new_segment(struct f2fs_sb_info *sbi, int type);
> +void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi);
>  int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range);
>  bool f2fs_exist_trim_candidates(struct f2fs_sb_info *sbi,
>  					struct cp_control *cpc);
> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> index f196187159e9..67c65e40b22b 100644
> --- a/fs/f2fs/file.c
> +++ b/fs/f2fs/file.c
> @@ -1659,7 +1659,7 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
>  		map.m_seg_type = CURSEG_COLD_DATA_PINNED;
>  
>  		f2fs_lock_op(sbi);
> -		f2fs_allocate_new_segments(sbi, CURSEG_COLD_DATA);
> +		f2fs_allocate_new_segment(sbi, CURSEG_COLD_DATA_PINNED);

This should be CURSEG_COLD_DATA. Otherwise it causes the below kernel panic.
I fixed this in the -dev, so let me know, if you have other concern.

  259 Unable to handle kernel NULL pointer dereference at virtual address 00000008
  259 task: 0000000082b4de99 task.stack: 00000000c6b39dbf
  259 pc : f2fs_do_write_data_page+0x2b4/0x794
  259 lr : f2fs_do_write_data_page+0x290/0x794
  259 sp : ffffff800c83b5a0 pstate : 60c00145
  259 Call trace:
  259  f2fs_do_write_data_page+0x2b4/0x794
  259  f2fs_write_single_data_page+0x4a4/0x764
  259  f2fs_write_data_pages+0x4dc/0x968
  259  do_writepages+0x60/0x124
  259  __writeback_single_inode+0xd8/0x490
  259  writeback_sb_inodes+0x3a8/0x6e4
  259  __writeback_inodes_wb+0xa4/0x14c
  259  wb_writeback+0x218/0x434
  259  wb_workfn+0x2bc/0x57c
  259  process_one_work+0x25c/0x440
  259  worker_thread+0x24c/0x480
  259  kthread+0x11c/0x12c
  259  ret_from_fork+0x10/0x18

>  		f2fs_unlock_op(sbi);
>  
>  		err = f2fs_map_blocks(inode, &map, 1, F2FS_GET_BLOCK_PRE_DIO);
> diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
> index ae5310f02e7f..af974ba273b3 100644
> --- a/fs/f2fs/recovery.c
> +++ b/fs/f2fs/recovery.c
> @@ -742,7 +742,7 @@ static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list,
>  		f2fs_put_page(page, 1);
>  	}
>  	if (!err)
> -		f2fs_allocate_new_segments(sbi, NO_CHECK_TYPE);
> +		f2fs_allocate_new_segments(sbi);
>  	return err;
>  }
>  
> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> index 113114f98087..f15711e8ee5b 100644
> --- a/fs/f2fs/segment.c
> +++ b/fs/f2fs/segment.c
> @@ -2707,28 +2707,35 @@ void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
>  	up_read(&SM_I(sbi)->curseg_lock);
>  }
>  
> -void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi, int type)
> +void __allocate_new_segment(struct f2fs_sb_info *sbi, int type)
>  {
> -	struct curseg_info *curseg;
> +	struct curseg_info *curseg = CURSEG_I(sbi, type);
>  	unsigned int old_segno;
> -	int i;
>  
> -	down_write(&SIT_I(sbi)->sentry_lock);
> +	if (!curseg->next_blkoff &&
> +		!get_valid_blocks(sbi, curseg->segno, false) &&
> +		!get_ckpt_valid_blocks(sbi, curseg->segno))
> +		return;
>  
> -	for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
> -		if (type != NO_CHECK_TYPE && i != type)
> -			continue;
> +	old_segno = curseg->segno;
> +	SIT_I(sbi)->s_ops->allocate_segment(sbi, type, true);
> +	locate_dirty_segment(sbi, old_segno);
> +}
>  
> -		curseg = CURSEG_I(sbi, i);
> -		if (type == NO_CHECK_TYPE || curseg->next_blkoff ||
> -				get_valid_blocks(sbi, curseg->segno, false) ||
> -				get_ckpt_valid_blocks(sbi, curseg->segno)) {
> -			old_segno = curseg->segno;
> -			SIT_I(sbi)->s_ops->allocate_segment(sbi, i, true);
> -			locate_dirty_segment(sbi, old_segno);
> -		}
> -	}
> +void f2fs_allocate_new_segment(struct f2fs_sb_info *sbi, int type)
> +{
> +	down_write(&SIT_I(sbi)->sentry_lock);
> +	__allocate_new_segment(sbi, type);
> +	up_write(&SIT_I(sbi)->sentry_lock);
> +}
>  
> +void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi)
> +{
> +	int i;
> +
> +	down_write(&SIT_I(sbi)->sentry_lock);
> +	for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++)
> +		__allocate_new_segment(sbi, i);
>  	up_write(&SIT_I(sbi)->sentry_lock);
>  }
>  
> -- 
> 2.26.2


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [f2fs-dev] [PATCH 1/2] f2fs: split f2fs_allocate_new_segments()
  2020-06-29 20:19 ` [f2fs-dev] [PATCH 1/2] f2fs: split f2fs_allocate_new_segments() Jaegeuk Kim
@ 2020-06-30  1:21   ` Chao Yu
  2020-07-01  1:31   ` Chao Yu
  1 sibling, 0 replies; 6+ messages in thread
From: Chao Yu @ 2020-06-30  1:21 UTC (permalink / raw)
  To: Jaegeuk Kim; +Cc: linux-kernel, linux-f2fs-devel

On 2020/6/30 4:19, Jaegeuk Kim wrote:
> On 06/22, Chao Yu wrote:
>> to two independent functions:
>> - f2fs_allocate_new_segment() for specified type segment allocation
>> - f2fs_allocate_new_segments() for all data type segments allocation
>>
>> Signed-off-by: Chao Yu <yuchao0@huawei.com>
>> ---
>>  fs/f2fs/f2fs.h     |  3 ++-
>>  fs/f2fs/file.c     |  2 +-
>>  fs/f2fs/recovery.c |  2 +-
>>  fs/f2fs/segment.c  | 39 +++++++++++++++++++++++----------------
>>  4 files changed, 27 insertions(+), 19 deletions(-)
>>
>> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
>> index 70565d81320b..07290943e91d 100644
>> --- a/fs/f2fs/f2fs.h
>> +++ b/fs/f2fs/f2fs.h
>> @@ -3327,7 +3327,8 @@ void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
>>  int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
>>  void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
>>  					unsigned int start, unsigned int end);
>> -void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi, int type);
>> +void f2fs_allocate_new_segment(struct f2fs_sb_info *sbi, int type);
>> +void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi);
>>  int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range);
>>  bool f2fs_exist_trim_candidates(struct f2fs_sb_info *sbi,
>>  					struct cp_control *cpc);
>> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
>> index f196187159e9..67c65e40b22b 100644
>> --- a/fs/f2fs/file.c
>> +++ b/fs/f2fs/file.c
>> @@ -1659,7 +1659,7 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
>>  		map.m_seg_type = CURSEG_COLD_DATA_PINNED;
>>  
>>  		f2fs_lock_op(sbi);
>> -		f2fs_allocate_new_segments(sbi, CURSEG_COLD_DATA);
>> +		f2fs_allocate_new_segment(sbi, CURSEG_COLD_DATA_PINNED);
> 
> This should be CURSEG_COLD_DATA. Otherwise it causes the below kernel panic.
> I fixed this in the -dev, so let me know, if you have other concern.

It looks I made a mistake when spliting this cleanup patch from
"f2fs: introduce inmem curseg", thanks for fixing this.

Thanks,

> 
>   259 Unable to handle kernel NULL pointer dereference at virtual address 00000008
>   259 task: 0000000082b4de99 task.stack: 00000000c6b39dbf
>   259 pc : f2fs_do_write_data_page+0x2b4/0x794
>   259 lr : f2fs_do_write_data_page+0x290/0x794
>   259 sp : ffffff800c83b5a0 pstate : 60c00145
>   259 Call trace:
>   259  f2fs_do_write_data_page+0x2b4/0x794
>   259  f2fs_write_single_data_page+0x4a4/0x764
>   259  f2fs_write_data_pages+0x4dc/0x968
>   259  do_writepages+0x60/0x124
>   259  __writeback_single_inode+0xd8/0x490
>   259  writeback_sb_inodes+0x3a8/0x6e4
>   259  __writeback_inodes_wb+0xa4/0x14c
>   259  wb_writeback+0x218/0x434
>   259  wb_workfn+0x2bc/0x57c
>   259  process_one_work+0x25c/0x440
>   259  worker_thread+0x24c/0x480
>   259  kthread+0x11c/0x12c
>   259  ret_from_fork+0x10/0x18
> 
>>  		f2fs_unlock_op(sbi);
>>  
>>  		err = f2fs_map_blocks(inode, &map, 1, F2FS_GET_BLOCK_PRE_DIO);
>> diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
>> index ae5310f02e7f..af974ba273b3 100644
>> --- a/fs/f2fs/recovery.c
>> +++ b/fs/f2fs/recovery.c
>> @@ -742,7 +742,7 @@ static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list,
>>  		f2fs_put_page(page, 1);
>>  	}
>>  	if (!err)
>> -		f2fs_allocate_new_segments(sbi, NO_CHECK_TYPE);
>> +		f2fs_allocate_new_segments(sbi);
>>  	return err;
>>  }
>>  
>> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
>> index 113114f98087..f15711e8ee5b 100644
>> --- a/fs/f2fs/segment.c
>> +++ b/fs/f2fs/segment.c
>> @@ -2707,28 +2707,35 @@ void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
>>  	up_read(&SM_I(sbi)->curseg_lock);
>>  }
>>  
>> -void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi, int type)
>> +void __allocate_new_segment(struct f2fs_sb_info *sbi, int type)
>>  {
>> -	struct curseg_info *curseg;
>> +	struct curseg_info *curseg = CURSEG_I(sbi, type);
>>  	unsigned int old_segno;
>> -	int i;
>>  
>> -	down_write(&SIT_I(sbi)->sentry_lock);
>> +	if (!curseg->next_blkoff &&
>> +		!get_valid_blocks(sbi, curseg->segno, false) &&
>> +		!get_ckpt_valid_blocks(sbi, curseg->segno))
>> +		return;
>>  
>> -	for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
>> -		if (type != NO_CHECK_TYPE && i != type)
>> -			continue;
>> +	old_segno = curseg->segno;
>> +	SIT_I(sbi)->s_ops->allocate_segment(sbi, type, true);
>> +	locate_dirty_segment(sbi, old_segno);
>> +}
>>  
>> -		curseg = CURSEG_I(sbi, i);
>> -		if (type == NO_CHECK_TYPE || curseg->next_blkoff ||
>> -				get_valid_blocks(sbi, curseg->segno, false) ||
>> -				get_ckpt_valid_blocks(sbi, curseg->segno)) {
>> -			old_segno = curseg->segno;
>> -			SIT_I(sbi)->s_ops->allocate_segment(sbi, i, true);
>> -			locate_dirty_segment(sbi, old_segno);
>> -		}
>> -	}
>> +void f2fs_allocate_new_segment(struct f2fs_sb_info *sbi, int type)
>> +{
>> +	down_write(&SIT_I(sbi)->sentry_lock);
>> +	__allocate_new_segment(sbi, type);
>> +	up_write(&SIT_I(sbi)->sentry_lock);
>> +}
>>  
>> +void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi)
>> +{
>> +	int i;
>> +
>> +	down_write(&SIT_I(sbi)->sentry_lock);
>> +	for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++)
>> +		__allocate_new_segment(sbi, i);
>>  	up_write(&SIT_I(sbi)->sentry_lock);
>>  }
>>  
>> -- 
>> 2.26.2
> .
> 


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [f2fs-dev] [PATCH 1/2] f2fs: split f2fs_allocate_new_segments()
  2020-06-29 20:19 ` [f2fs-dev] [PATCH 1/2] f2fs: split f2fs_allocate_new_segments() Jaegeuk Kim
  2020-06-30  1:21   ` Chao Yu
@ 2020-07-01  1:31   ` Chao Yu
  2020-07-01  4:22     ` Jaegeuk Kim
  1 sibling, 1 reply; 6+ messages in thread
From: Chao Yu @ 2020-07-01  1:31 UTC (permalink / raw)
  To: Jaegeuk Kim; +Cc: linux-kernel, linux-f2fs-devel

Jaegeuk, could you please help to change __allocate_new_segment() to static
in your tree?

On 2020/6/30 4:19, Jaegeuk Kim wrote:
> On 06/22, Chao Yu wrote:
>> to two independent functions:
>> - f2fs_allocate_new_segment() for specified type segment allocation
>> - f2fs_allocate_new_segments() for all data type segments allocation
>>
>> Signed-off-by: Chao Yu <yuchao0@huawei.com>
>> ---
>>  fs/f2fs/f2fs.h     |  3 ++-
>>  fs/f2fs/file.c     |  2 +-
>>  fs/f2fs/recovery.c |  2 +-
>>  fs/f2fs/segment.c  | 39 +++++++++++++++++++++++----------------
>>  4 files changed, 27 insertions(+), 19 deletions(-)
>>
>> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
>> index 70565d81320b..07290943e91d 100644
>> --- a/fs/f2fs/f2fs.h
>> +++ b/fs/f2fs/f2fs.h
>> @@ -3327,7 +3327,8 @@ void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
>>  int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
>>  void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
>>  					unsigned int start, unsigned int end);
>> -void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi, int type);
>> +void f2fs_allocate_new_segment(struct f2fs_sb_info *sbi, int type);
>> +void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi);
>>  int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range);
>>  bool f2fs_exist_trim_candidates(struct f2fs_sb_info *sbi,
>>  					struct cp_control *cpc);
>> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
>> index f196187159e9..67c65e40b22b 100644
>> --- a/fs/f2fs/file.c
>> +++ b/fs/f2fs/file.c
>> @@ -1659,7 +1659,7 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
>>  		map.m_seg_type = CURSEG_COLD_DATA_PINNED;
>>  
>>  		f2fs_lock_op(sbi);
>> -		f2fs_allocate_new_segments(sbi, CURSEG_COLD_DATA);
>> +		f2fs_allocate_new_segment(sbi, CURSEG_COLD_DATA_PINNED);
> 
> This should be CURSEG_COLD_DATA. Otherwise it causes the below kernel panic.
> I fixed this in the -dev, so let me know, if you have other concern.
> 
>   259 Unable to handle kernel NULL pointer dereference at virtual address 00000008
>   259 task: 0000000082b4de99 task.stack: 00000000c6b39dbf
>   259 pc : f2fs_do_write_data_page+0x2b4/0x794
>   259 lr : f2fs_do_write_data_page+0x290/0x794
>   259 sp : ffffff800c83b5a0 pstate : 60c00145
>   259 Call trace:
>   259  f2fs_do_write_data_page+0x2b4/0x794
>   259  f2fs_write_single_data_page+0x4a4/0x764
>   259  f2fs_write_data_pages+0x4dc/0x968
>   259  do_writepages+0x60/0x124
>   259  __writeback_single_inode+0xd8/0x490
>   259  writeback_sb_inodes+0x3a8/0x6e4
>   259  __writeback_inodes_wb+0xa4/0x14c
>   259  wb_writeback+0x218/0x434
>   259  wb_workfn+0x2bc/0x57c
>   259  process_one_work+0x25c/0x440
>   259  worker_thread+0x24c/0x480
>   259  kthread+0x11c/0x12c
>   259  ret_from_fork+0x10/0x18
> 
>>  		f2fs_unlock_op(sbi);
>>  
>>  		err = f2fs_map_blocks(inode, &map, 1, F2FS_GET_BLOCK_PRE_DIO);
>> diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
>> index ae5310f02e7f..af974ba273b3 100644
>> --- a/fs/f2fs/recovery.c
>> +++ b/fs/f2fs/recovery.c
>> @@ -742,7 +742,7 @@ static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list,
>>  		f2fs_put_page(page, 1);
>>  	}
>>  	if (!err)
>> -		f2fs_allocate_new_segments(sbi, NO_CHECK_TYPE);
>> +		f2fs_allocate_new_segments(sbi);
>>  	return err;
>>  }
>>  
>> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
>> index 113114f98087..f15711e8ee5b 100644
>> --- a/fs/f2fs/segment.c
>> +++ b/fs/f2fs/segment.c
>> @@ -2707,28 +2707,35 @@ void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
>>  	up_read(&SM_I(sbi)->curseg_lock);
>>  }
>>  
>> -void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi, int type)
>> +void __allocate_new_segment(struct f2fs_sb_info *sbi, int type)
>>  {
>> -	struct curseg_info *curseg;
>> +	struct curseg_info *curseg = CURSEG_I(sbi, type);
>>  	unsigned int old_segno;
>> -	int i;
>>  
>> -	down_write(&SIT_I(sbi)->sentry_lock);
>> +	if (!curseg->next_blkoff &&
>> +		!get_valid_blocks(sbi, curseg->segno, false) &&
>> +		!get_ckpt_valid_blocks(sbi, curseg->segno))
>> +		return;
>>  
>> -	for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
>> -		if (type != NO_CHECK_TYPE && i != type)
>> -			continue;
>> +	old_segno = curseg->segno;
>> +	SIT_I(sbi)->s_ops->allocate_segment(sbi, type, true);
>> +	locate_dirty_segment(sbi, old_segno);
>> +}
>>  
>> -		curseg = CURSEG_I(sbi, i);
>> -		if (type == NO_CHECK_TYPE || curseg->next_blkoff ||
>> -				get_valid_blocks(sbi, curseg->segno, false) ||
>> -				get_ckpt_valid_blocks(sbi, curseg->segno)) {
>> -			old_segno = curseg->segno;
>> -			SIT_I(sbi)->s_ops->allocate_segment(sbi, i, true);
>> -			locate_dirty_segment(sbi, old_segno);
>> -		}
>> -	}
>> +void f2fs_allocate_new_segment(struct f2fs_sb_info *sbi, int type)
>> +{
>> +	down_write(&SIT_I(sbi)->sentry_lock);
>> +	__allocate_new_segment(sbi, type);
>> +	up_write(&SIT_I(sbi)->sentry_lock);
>> +}
>>  
>> +void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi)
>> +{
>> +	int i;
>> +
>> +	down_write(&SIT_I(sbi)->sentry_lock);
>> +	for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++)
>> +		__allocate_new_segment(sbi, i);
>>  	up_write(&SIT_I(sbi)->sentry_lock);
>>  }
>>  
>> -- 
>> 2.26.2
> .
> 


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [f2fs-dev] [PATCH 1/2] f2fs: split f2fs_allocate_new_segments()
  2020-07-01  1:31   ` Chao Yu
@ 2020-07-01  4:22     ` Jaegeuk Kim
  0 siblings, 0 replies; 6+ messages in thread
From: Jaegeuk Kim @ 2020-07-01  4:22 UTC (permalink / raw)
  To: Chao Yu; +Cc: linux-kernel, linux-f2fs-devel

On 07/01, Chao Yu wrote:
> Jaegeuk, could you please help to change __allocate_new_segment() to static
> in your tree?

Sure. :)

> 
> On 2020/6/30 4:19, Jaegeuk Kim wrote:
> > On 06/22, Chao Yu wrote:
> >> to two independent functions:
> >> - f2fs_allocate_new_segment() for specified type segment allocation
> >> - f2fs_allocate_new_segments() for all data type segments allocation
> >>
> >> Signed-off-by: Chao Yu <yuchao0@huawei.com>
> >> ---
> >>  fs/f2fs/f2fs.h     |  3 ++-
> >>  fs/f2fs/file.c     |  2 +-
> >>  fs/f2fs/recovery.c |  2 +-
> >>  fs/f2fs/segment.c  | 39 +++++++++++++++++++++++----------------
> >>  4 files changed, 27 insertions(+), 19 deletions(-)
> >>
> >> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> >> index 70565d81320b..07290943e91d 100644
> >> --- a/fs/f2fs/f2fs.h
> >> +++ b/fs/f2fs/f2fs.h
> >> @@ -3327,7 +3327,8 @@ void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
> >>  int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra);
> >>  void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
> >>  					unsigned int start, unsigned int end);
> >> -void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi, int type);
> >> +void f2fs_allocate_new_segment(struct f2fs_sb_info *sbi, int type);
> >> +void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi);
> >>  int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range);
> >>  bool f2fs_exist_trim_candidates(struct f2fs_sb_info *sbi,
> >>  					struct cp_control *cpc);
> >> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> >> index f196187159e9..67c65e40b22b 100644
> >> --- a/fs/f2fs/file.c
> >> +++ b/fs/f2fs/file.c
> >> @@ -1659,7 +1659,7 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
> >>  		map.m_seg_type = CURSEG_COLD_DATA_PINNED;
> >>  
> >>  		f2fs_lock_op(sbi);
> >> -		f2fs_allocate_new_segments(sbi, CURSEG_COLD_DATA);
> >> +		f2fs_allocate_new_segment(sbi, CURSEG_COLD_DATA_PINNED);
> > 
> > This should be CURSEG_COLD_DATA. Otherwise it causes the below kernel panic.
> > I fixed this in the -dev, so let me know, if you have other concern.
> > 
> >   259 Unable to handle kernel NULL pointer dereference at virtual address 00000008
> >   259 task: 0000000082b4de99 task.stack: 00000000c6b39dbf
> >   259 pc : f2fs_do_write_data_page+0x2b4/0x794
> >   259 lr : f2fs_do_write_data_page+0x290/0x794
> >   259 sp : ffffff800c83b5a0 pstate : 60c00145
> >   259 Call trace:
> >   259  f2fs_do_write_data_page+0x2b4/0x794
> >   259  f2fs_write_single_data_page+0x4a4/0x764
> >   259  f2fs_write_data_pages+0x4dc/0x968
> >   259  do_writepages+0x60/0x124
> >   259  __writeback_single_inode+0xd8/0x490
> >   259  writeback_sb_inodes+0x3a8/0x6e4
> >   259  __writeback_inodes_wb+0xa4/0x14c
> >   259  wb_writeback+0x218/0x434
> >   259  wb_workfn+0x2bc/0x57c
> >   259  process_one_work+0x25c/0x440
> >   259  worker_thread+0x24c/0x480
> >   259  kthread+0x11c/0x12c
> >   259  ret_from_fork+0x10/0x18
> > 
> >>  		f2fs_unlock_op(sbi);
> >>  
> >>  		err = f2fs_map_blocks(inode, &map, 1, F2FS_GET_BLOCK_PRE_DIO);
> >> diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c
> >> index ae5310f02e7f..af974ba273b3 100644
> >> --- a/fs/f2fs/recovery.c
> >> +++ b/fs/f2fs/recovery.c
> >> @@ -742,7 +742,7 @@ static int recover_data(struct f2fs_sb_info *sbi, struct list_head *inode_list,
> >>  		f2fs_put_page(page, 1);
> >>  	}
> >>  	if (!err)
> >> -		f2fs_allocate_new_segments(sbi, NO_CHECK_TYPE);
> >> +		f2fs_allocate_new_segments(sbi);
> >>  	return err;
> >>  }
> >>  
> >> diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
> >> index 113114f98087..f15711e8ee5b 100644
> >> --- a/fs/f2fs/segment.c
> >> +++ b/fs/f2fs/segment.c
> >> @@ -2707,28 +2707,35 @@ void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
> >>  	up_read(&SM_I(sbi)->curseg_lock);
> >>  }
> >>  
> >> -void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi, int type)
> >> +void __allocate_new_segment(struct f2fs_sb_info *sbi, int type)
> >>  {
> >> -	struct curseg_info *curseg;
> >> +	struct curseg_info *curseg = CURSEG_I(sbi, type);
> >>  	unsigned int old_segno;
> >> -	int i;
> >>  
> >> -	down_write(&SIT_I(sbi)->sentry_lock);
> >> +	if (!curseg->next_blkoff &&
> >> +		!get_valid_blocks(sbi, curseg->segno, false) &&
> >> +		!get_ckpt_valid_blocks(sbi, curseg->segno))
> >> +		return;
> >>  
> >> -	for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
> >> -		if (type != NO_CHECK_TYPE && i != type)
> >> -			continue;
> >> +	old_segno = curseg->segno;
> >> +	SIT_I(sbi)->s_ops->allocate_segment(sbi, type, true);
> >> +	locate_dirty_segment(sbi, old_segno);
> >> +}
> >>  
> >> -		curseg = CURSEG_I(sbi, i);
> >> -		if (type == NO_CHECK_TYPE || curseg->next_blkoff ||
> >> -				get_valid_blocks(sbi, curseg->segno, false) ||
> >> -				get_ckpt_valid_blocks(sbi, curseg->segno)) {
> >> -			old_segno = curseg->segno;
> >> -			SIT_I(sbi)->s_ops->allocate_segment(sbi, i, true);
> >> -			locate_dirty_segment(sbi, old_segno);
> >> -		}
> >> -	}
> >> +void f2fs_allocate_new_segment(struct f2fs_sb_info *sbi, int type)
> >> +{
> >> +	down_write(&SIT_I(sbi)->sentry_lock);
> >> +	__allocate_new_segment(sbi, type);
> >> +	up_write(&SIT_I(sbi)->sentry_lock);
> >> +}
> >>  
> >> +void f2fs_allocate_new_segments(struct f2fs_sb_info *sbi)
> >> +{
> >> +	int i;
> >> +
> >> +	down_write(&SIT_I(sbi)->sentry_lock);
> >> +	for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++)
> >> +		__allocate_new_segment(sbi, i);
> >>  	up_write(&SIT_I(sbi)->sentry_lock);
> >>  }
> >>  
> >> -- 
> >> 2.26.2
> > .
> > 


_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, back to index

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-22  9:38 [f2fs-dev] [PATCH 1/2] f2fs: split f2fs_allocate_new_segments() Chao Yu
2020-06-22  9:38 ` [f2fs-dev] [PATCH 2/2] f2fs: introduce inmem curseg Chao Yu
2020-06-29 20:19 ` [f2fs-dev] [PATCH 1/2] f2fs: split f2fs_allocate_new_segments() Jaegeuk Kim
2020-06-30  1:21   ` Chao Yu
2020-07-01  1:31   ` Chao Yu
2020-07-01  4:22     ` Jaegeuk Kim

Linux-f2fs-devel Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-f2fs-devel/0 linux-f2fs-devel/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-f2fs-devel linux-f2fs-devel/ https://lore.kernel.org/linux-f2fs-devel \
		linux-f2fs-devel@lists.sourceforge.net
	public-inbox-index linux-f2fs-devel

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/net.sourceforge.lists.linux-f2fs-devel


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git