* [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 related [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 related [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, other threads:[~2020-07-01 4:22 UTC | newest]
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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).