Commit d0b9e42a authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim

f2fs: introduce inmem curseg

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: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 376207af
...@@ -1619,11 +1619,16 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) ...@@ -1619,11 +1619,16 @@ int f2fs_write_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc)
f2fs_flush_sit_entries(sbi, 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); err = do_checkpoint(sbi, cpc);
if (err) if (err)
f2fs_release_discard_addrs(sbi); f2fs_release_discard_addrs(sbi);
else else
f2fs_clear_prefree_segments(sbi, cpc); f2fs_clear_prefree_segments(sbi, cpc);
f2fs_restore_inmem_curseg(sbi, CURSEG_COLD_DATA_PINNED);
stop: stop:
unblock_operations(sbi); unblock_operations(sbi);
stat_inc_cp_count(sbi->stat_info); stat_inc_cp_count(sbi->stat_info);
...@@ -1654,7 +1659,7 @@ void f2fs_init_ino_entry_info(struct f2fs_sb_info *sbi) ...@@ -1654,7 +1659,7 @@ void f2fs_init_ino_entry_info(struct f2fs_sb_info *sbi)
} }
sbi->max_orphans = (sbi->blocks_per_seg - F2FS_CP_PACKS - 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; F2FS_ORPHANS_PER_BLOCK;
} }
......
...@@ -164,7 +164,7 @@ static void update_general_status(struct f2fs_sb_info *sbi) ...@@ -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) * 100 / (int)(sbi->user_block_count >> sbi->log_blocks_per_seg)
/ 2; / 2;
si->util_invalid = 50 - si->util_free - si->util_valid; 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); struct curseg_info *curseg = CURSEG_I(sbi, i);
si->curseg[i] = curseg->segno; si->curseg[i] = curseg->segno;
si->cursec[i] = GET_SEC_FROM_SEG(sbi, curseg->segno); si->cursec[i] = GET_SEC_FROM_SEG(sbi, curseg->segno);
...@@ -393,6 +393,10 @@ static int stat_show(struct seq_file *s, void *v) ...@@ -393,6 +393,10 @@ static int stat_show(struct seq_file *s, void *v)
si->dirty_seg[CURSEG_COLD_NODE], si->dirty_seg[CURSEG_COLD_NODE],
si->full_seg[CURSEG_COLD_NODE], si->full_seg[CURSEG_COLD_NODE],
si->valid_blks[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", seq_printf(s, "\n - Valid: %d\n - Dirty: %d\n",
si->main_area_segs - si->dirty_count - si->main_area_segs - si->dirty_count -
si->prefree_count - si->free_segs, si->prefree_count - si->free_segs,
......
...@@ -973,7 +973,9 @@ static inline void set_new_dnode(struct dnode_of_data *dn, struct inode *inode, ...@@ -973,7 +973,9 @@ static inline void set_new_dnode(struct dnode_of_data *dn, struct inode *inode,
*/ */
#define NR_CURSEG_DATA_TYPE (3) #define NR_CURSEG_DATA_TYPE (3)
#define NR_CURSEG_NODE_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 { enum {
CURSEG_HOT_DATA = 0, /* directory entry blocks */ CURSEG_HOT_DATA = 0, /* directory entry blocks */
...@@ -982,8 +984,10 @@ enum { ...@@ -982,8 +984,10 @@ enum {
CURSEG_HOT_NODE, /* direct node blocks of directory files */ CURSEG_HOT_NODE, /* direct node blocks of directory files */
CURSEG_WARM_NODE, /* direct node blocks of normal files */ CURSEG_WARM_NODE, /* direct node blocks of normal files */
CURSEG_COLD_NODE, /* indirect node blocks */ CURSEG_COLD_NODE, /* indirect node blocks */
NO_CHECK_TYPE, NR_PERSISTENT_LOG, /* number of persistent log */
CURSEG_COLD_DATA_PINNED,/* cold data for pinned file */ 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 { struct flush_cmd {
...@@ -3333,6 +3337,8 @@ block_t f2fs_get_unusable_blocks(struct f2fs_sb_info *sbi); ...@@ -3333,6 +3337,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); int f2fs_disable_cp_again(struct f2fs_sb_info *sbi, block_t unusable);
void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi); void f2fs_release_discard_addrs(struct f2fs_sb_info *sbi);
int f2fs_npages_for_summary_flush(struct f2fs_sb_info *sbi, bool for_ra); 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, void f2fs_allocate_segment_for_resize(struct f2fs_sb_info *sbi, int type,
unsigned int start, unsigned int end); unsigned int start, unsigned int end);
void f2fs_allocate_new_segment(struct f2fs_sb_info *sbi, int type); void f2fs_allocate_new_segment(struct f2fs_sb_info *sbi, int type);
......
...@@ -1656,13 +1656,14 @@ static int expand_inode_data(struct inode *inode, loff_t offset, ...@@ -1656,13 +1656,14 @@ static int expand_inode_data(struct inode *inode, loff_t offset,
} }
down_write(&sbi->pin_sem); down_write(&sbi->pin_sem);
map.m_seg_type = CURSEG_COLD_DATA_PINNED;
f2fs_lock_op(sbi); f2fs_lock_op(sbi);
f2fs_allocate_new_segment(sbi, CURSEG_COLD_DATA); f2fs_allocate_new_segment(sbi, CURSEG_COLD_DATA_PINNED);
f2fs_unlock_op(sbi); f2fs_unlock_op(sbi);
map.m_seg_type = CURSEG_COLD_DATA_PINNED;
err = f2fs_map_blocks(inode, &map, 1, F2FS_GET_BLOCK_PRE_DIO); err = f2fs_map_blocks(inode, &map, 1, F2FS_GET_BLOCK_PRE_DIO);
up_write(&sbi->pin_sem); up_write(&sbi->pin_sem);
done += map.m_len; done += map.m_len;
......
...@@ -1463,7 +1463,7 @@ static int free_segment_range(struct f2fs_sb_info *sbi, ...@@ -1463,7 +1463,7 @@ static int free_segment_range(struct f2fs_sb_info *sbi,
mutex_unlock(&DIRTY_I(sbi)->seglist_lock); mutex_unlock(&DIRTY_I(sbi)->seglist_lock);
/* Move out cursegs from the target range */ /* 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); f2fs_allocate_segment_for_resize(sbi, type, start, end);
/* do GC to move out valid blocks in the range */ /* do GC to move out valid blocks in the range */
......
...@@ -1962,7 +1962,7 @@ static void set_prefree_as_free_segments(struct f2fs_sb_info *sbi) ...@@ -1962,7 +1962,7 @@ static void set_prefree_as_free_segments(struct f2fs_sb_info *sbi)
mutex_lock(&dirty_i->seglist_lock); mutex_lock(&dirty_i->seglist_lock);
for_each_set_bit(segno, dirty_i->dirty_segmap[PRE], MAIN_SEGS(sbi)) 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); mutex_unlock(&dirty_i->seglist_lock);
} }
...@@ -2500,6 +2500,7 @@ static void reset_curseg(struct f2fs_sb_info *sbi, int type, int modified) ...@@ -2500,6 +2500,7 @@ static void reset_curseg(struct f2fs_sb_info *sbi, int type, int modified)
struct curseg_info *curseg = CURSEG_I(sbi, type); struct curseg_info *curseg = CURSEG_I(sbi, type);
struct summary_footer *sum_footer; struct summary_footer *sum_footer;
curseg->inited = true;
curseg->segno = curseg->next_segno; curseg->segno = curseg->next_segno;
curseg->zone = GET_ZONE_FROM_SEG(sbi, curseg->segno); curseg->zone = GET_ZONE_FROM_SEG(sbi, curseg->segno);
curseg->next_blkoff = 0; curseg->next_blkoff = 0;
...@@ -2507,24 +2508,31 @@ static void reset_curseg(struct f2fs_sb_info *sbi, int type, int modified) ...@@ -2507,24 +2508,31 @@ static void reset_curseg(struct f2fs_sb_info *sbi, int type, int modified)
sum_footer = &(curseg->sum_blk->footer); sum_footer = &(curseg->sum_blk->footer);
memset(sum_footer, 0, sizeof(struct summary_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); 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_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) 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 segs_per_sec is large than 1, we need to keep original policy. */
if (__is_large_section(sbi)) 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))) if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED)))
return 0; return 0;
if (test_opt(sbi, NOHEAP) && 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; return 0;
if (SIT_I(sbi)->last_victim[ALLOC_NEXT]) if (SIT_I(sbi)->last_victim[ALLOC_NEXT])
...@@ -2534,7 +2542,7 @@ static unsigned int __get_next_segno(struct f2fs_sb_info *sbi, int type) ...@@ -2534,7 +2542,7 @@ static unsigned int __get_next_segno(struct f2fs_sb_info *sbi, int type)
if (F2FS_OPTION(sbi).alloc_mode == ALLOC_MODE_REUSE) if (F2FS_OPTION(sbi).alloc_mode == ALLOC_MODE_REUSE)
return 0; return 0;
return CURSEG_I(sbi, type)->segno; return curseg->segno;
} }
/* /*
...@@ -2544,12 +2552,14 @@ static unsigned int __get_next_segno(struct f2fs_sb_info *sbi, int type) ...@@ -2544,12 +2552,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) static void new_curseg(struct f2fs_sb_info *sbi, int type, bool new_sec)
{ {
struct curseg_info *curseg = CURSEG_I(sbi, type); struct curseg_info *curseg = CURSEG_I(sbi, type);
unsigned short seg_type = curseg->seg_type;
unsigned int segno = curseg->segno; unsigned int segno = curseg->segno;
int dir = ALLOC_LEFT; 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)); 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; dir = ALLOC_RIGHT;
if (test_opt(sbi, NOHEAP)) if (test_opt(sbi, NOHEAP))
...@@ -2626,6 +2636,43 @@ static void change_curseg(struct f2fs_sb_info *sbi, int type) ...@@ -2626,6 +2636,43 @@ static void change_curseg(struct f2fs_sb_info *sbi, int type)
f2fs_put_page(sum_page, 1); 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) static int get_ssr_segment(struct f2fs_sb_info *sbi, int type)
{ {
struct curseg_info *curseg = CURSEG_I(sbi, type); struct curseg_info *curseg = CURSEG_I(sbi, type);
...@@ -2742,11 +2789,15 @@ static void __allocate_new_segment(struct f2fs_sb_info *sbi, int type) ...@@ -2742,11 +2789,15 @@ static void __allocate_new_segment(struct f2fs_sb_info *sbi, int type)
struct curseg_info *curseg = CURSEG_I(sbi, type); struct curseg_info *curseg = CURSEG_I(sbi, type);
unsigned int old_segno; unsigned int old_segno;
if (!curseg->inited)
goto alloc;
if (!curseg->next_blkoff && if (!curseg->next_blkoff &&
!get_valid_blocks(sbi, curseg->segno, false) && !get_valid_blocks(sbi, curseg->segno, false) &&
!get_ckpt_valid_blocks(sbi, curseg->segno)) !get_ckpt_valid_blocks(sbi, curseg->segno))
return; return;
alloc:
old_segno = curseg->segno; old_segno = curseg->segno;
SIT_I(sbi)->s_ops->allocate_segment(sbi, type, true); SIT_I(sbi)->s_ops->allocate_segment(sbi, type, true);
locate_dirty_segment(sbi, old_segno); locate_dirty_segment(sbi, old_segno);
...@@ -3130,19 +3181,6 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page, ...@@ -3130,19 +3181,6 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
{ {
struct sit_info *sit_i = SIT_I(sbi); struct sit_info *sit_i = SIT_I(sbi);
struct curseg_info *curseg = CURSEG_I(sbi, type); 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); down_read(&SM_I(sbi)->curseg_lock);
...@@ -3208,9 +3246,6 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page, ...@@ -3208,9 +3246,6 @@ void f2fs_allocate_data_block(struct f2fs_sb_info *sbi, struct page *page,
mutex_unlock(&curseg->curseg_mutex); mutex_unlock(&curseg->curseg_mutex);
up_read(&SM_I(sbi)->curseg_lock); 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) static void update_device_state(struct f2fs_io_info *fio)
...@@ -3578,7 +3613,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type) ...@@ -3578,7 +3613,7 @@ static int read_normal_summaries(struct f2fs_sb_info *sbi, int type)
blk_off = le16_to_cpu(ckpt->cur_data_blkoff[type - blk_off = le16_to_cpu(ckpt->cur_data_blkoff[type -
CURSEG_HOT_DATA]); CURSEG_HOT_DATA]);
if (__exist_node_summaries(sbi)) 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 else
blk_addr = sum_blk_addr(sbi, NR_CURSEG_DATA_TYPE, type); blk_addr = sum_blk_addr(sbi, NR_CURSEG_DATA_TYPE, type);
} else { } else {
...@@ -3656,8 +3691,9 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi) ...@@ -3656,8 +3691,9 @@ static int restore_curseg_summaries(struct f2fs_sb_info *sbi)
} }
if (__exist_node_summaries(sbi)) if (__exist_node_summaries(sbi))
f2fs_ra_meta_pages(sbi, sum_blk_addr(sbi, NR_CURSEG_TYPE, type), f2fs_ra_meta_pages(sbi,
NR_CURSEG_TYPE - type, META_CP, true); sum_blk_addr(sbi, NR_CURSEG_PERSIST_TYPE, type),
NR_CURSEG_PERSIST_TYPE - type, META_CP, true);
for (; type <= CURSEG_COLD_NODE; type++) { for (; type <= CURSEG_COLD_NODE; type++) {
err = read_normal_summaries(sbi, type); err = read_normal_summaries(sbi, type);
...@@ -4159,14 +4195,14 @@ static int build_curseg(struct f2fs_sb_info *sbi) ...@@ -4159,14 +4195,14 @@ static int build_curseg(struct f2fs_sb_info *sbi)
struct curseg_info *array; struct curseg_info *array;
int i; int i;
array = f2fs_kzalloc(sbi, array_size(NR_CURSEG_TYPE, sizeof(*array)), array = f2fs_kzalloc(sbi, array_size(NR_CURSEG_TYPE,
GFP_KERNEL); sizeof(*array)), GFP_KERNEL);
if (!array) if (!array)
return -ENOMEM; return -ENOMEM;
SM_I(sbi)->curseg_array = array; 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); mutex_init(&array[i].curseg_mutex);
array[i].sum_blk = f2fs_kzalloc(sbi, PAGE_SIZE, GFP_KERNEL); array[i].sum_blk = f2fs_kzalloc(sbi, PAGE_SIZE, GFP_KERNEL);
if (!array[i].sum_blk) if (!array[i].sum_blk)
...@@ -4176,8 +4212,13 @@ static int build_curseg(struct f2fs_sb_info *sbi) ...@@ -4176,8 +4212,13 @@ static int build_curseg(struct f2fs_sb_info *sbi)
sizeof(struct f2fs_journal), GFP_KERNEL); sizeof(struct f2fs_journal), GFP_KERNEL);
if (!array[i].journal) if (!array[i].journal)
return -ENOMEM; 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].segno = NULL_SEGNO;
array[i].next_blkoff = 0; array[i].next_blkoff = 0;
array[i].inited = false;
} }
return restore_curseg_summaries(sbi); return restore_curseg_summaries(sbi);
} }
...@@ -4416,7 +4457,7 @@ static int sanity_check_curseg(struct f2fs_sb_info *sbi) ...@@ -4416,7 +4457,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/SSR curseg, .next_blkoff should point to an unused blkaddr;
* In LFS curseg, all blkaddr after .next_blkoff should be unused. * 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 curseg_info *curseg = CURSEG_I(sbi, i);
struct seg_entry *se = get_seg_entry(sbi, curseg->segno); struct seg_entry *se = get_seg_entry(sbi, curseg->segno);
unsigned int blkofs = curseg->next_blkoff; unsigned int blkofs = curseg->next_blkoff;
...@@ -4645,7 +4686,7 @@ int f2fs_fix_curseg_write_pointer(struct f2fs_sb_info *sbi) ...@@ -4645,7 +4686,7 @@ int f2fs_fix_curseg_write_pointer(struct f2fs_sb_info *sbi)
{ {
int i, ret; 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); ret = fix_curseg_write_pointer(sbi, i);
if (ret) if (ret)
return ret; return ret;
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#define GET_R2L_SEGNO(free_i, segno) ((segno) + (free_i)->start_segno) #define GET_R2L_SEGNO(free_i, segno) ((segno) + (free_i)->start_segno)
#define IS_DATASEG(t) ((t) <= CURSEG_COLD_DATA) #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_HOT(t) ((t) == CURSEG_HOT_NODE || (t) == CURSEG_HOT_DATA)
#define IS_WARM(t) ((t) == CURSEG_WARM_NODE || (t) == CURSEG_WARM_DATA) #define IS_WARM(t) ((t) == CURSEG_WARM_NODE || (t) == CURSEG_WARM_DATA)
...@@ -34,7 +34,8 @@ ...@@ -34,7 +34,8 @@
((seg) == CURSEG_I(sbi, CURSEG_COLD_DATA)->segno) || \ ((seg) == CURSEG_I(sbi, CURSEG_COLD_DATA)->segno) || \
((seg) == CURSEG_I(sbi, CURSEG_HOT_NODE)->segno) || \ ((seg) == CURSEG_I(sbi, CURSEG_HOT_NODE)->segno) || \
((seg) == CURSEG_I(sbi, CURSEG_WARM_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) \ #define IS_CURSEC(sbi, secno) \
(((secno) == CURSEG_I(sbi, CURSEG_HOT_DATA)->segno / \ (((secno) == CURSEG_I(sbi, CURSEG_HOT_DATA)->segno / \
...@@ -48,7 +49,9 @@ ...@@ -48,7 +49,9 @@
((secno) == CURSEG_I(sbi, CURSEG_WARM_NODE)->segno / \ ((secno) == CURSEG_I(sbi, CURSEG_WARM_NODE)->segno / \
(sbi)->segs_per_sec) || \ (sbi)->segs_per_sec) || \
((secno) == CURSEG_I(sbi, CURSEG_COLD_NODE)->segno / \ ((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) \ #define MAIN_BLKADDR(sbi) \
(SM_I(sbi) ? SM_I(sbi)->main_blkaddr : \ (SM_I(sbi) ? SM_I(sbi)->main_blkaddr : \
...@@ -288,10 +291,12 @@ struct curseg_info { ...@@ -288,10 +291,12 @@ struct curseg_info {
struct rw_semaphore journal_rwsem; /* protect journal area */ struct rw_semaphore journal_rwsem; /* protect journal area */
struct f2fs_journal *journal; /* cached journal info */ struct f2fs_journal *journal; /* cached journal info */
unsigned char alloc_type; /* current allocation type */ unsigned char alloc_type; /* current allocation type */
unsigned short seg_type; /* segment type like CURSEG_XXX_TYPE */
unsigned int segno; /* current segment number */ unsigned int segno; /* current segment number */
unsigned short next_blkoff; /* next block offset to write */ unsigned short next_blkoff; /* next block offset to write */
unsigned int zone; /* current zone number */ unsigned int zone; /* current zone number */
unsigned int next_segno; /* preallocated segment */ unsigned int next_segno; /* preallocated segment */
bool inited; /* indicate inmem log is inited */
}; };
struct sit_entry_set { struct sit_entry_set {
...@@ -305,8 +310,6 @@ struct sit_entry_set { ...@@ -305,8 +310,6 @@ struct sit_entry_set {
*/ */
static inline struct curseg_info *CURSEG_I(struct f2fs_sb_info *sbi, int type) 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); return (struct curseg_info *)(SM_I(sbi)->curseg_array + type);
} }
...@@ -439,7 +442,7 @@ static inline void __set_inuse(struct f2fs_sb_info *sbi, ...@@ -439,7 +442,7 @@ static inline void __set_inuse(struct f2fs_sb_info *sbi,
} }
static inline void __set_test_and_free(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); struct free_segmap_info *free_i = FREE_I(sbi);
unsigned int secno = GET_SEC_FROM_SEG(sbi, segno); unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
...@@ -451,7 +454,7 @@ static inline void __set_test_and_free(struct f2fs_sb_info *sbi, ...@@ -451,7 +454,7 @@ static inline void __set_test_and_free(struct f2fs_sb_info *sbi,
if (test_and_clear_bit(segno, free_i->free_segmap)) { if (test_and_clear_bit(segno, free_i->free_segmap)) {
free_i->free_segments++; free_i->free_segments++;
if (IS_CURSEC(sbi, secno)) if (!inmem && IS_CURSEC(sbi, secno))
goto skip_free; goto skip_free;
next = find_next_bit(free_i->free_segmap, next = find_next_bit(free_i->free_segmap,
start_segno + sbi->segs_per_sec, start_segno); start_segno + sbi->segs_per_sec, start_segno);
......
...@@ -580,7 +580,8 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) ...@@ -580,7 +580,8 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount)
case Opt_active_logs: case Opt_active_logs:
if (args->from && match_int(args, &arg)) if (args->from && match_int(args, &arg))
return -EINVAL; return -EINVAL;
if (arg != 2 && arg != 4 && arg != NR_CURSEG_TYPE) if (arg != 2 && arg != 4 &&
arg != NR_CURSEG_PERSIST_TYPE)
return -EINVAL; return -EINVAL;
F2FS_OPTION(sbi).active_logs = arg; F2FS_OPTION(sbi).active_logs = arg;
break; break;
...@@ -1001,7 +1002,7 @@ static int parse_options(struct super_block *sb, char *options, bool is_remount) ...@@ -1001,7 +1002,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 /* 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) if (F2FS_OPTION(sbi).active_logs != NR_CURSEG_TYPE)
F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF; F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF;
...@@ -1641,7 +1642,7 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root) ...@@ -1641,7 +1642,7 @@ static int f2fs_show_options(struct seq_file *seq, struct dentry *root)
static void default_options(struct f2fs_sb_info *sbi) static void default_options(struct f2fs_sb_info *sbi)
{ {
/* init some FS parameters */ /* 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).inline_xattr_size = DEFAULT_INLINE_XATTR_ADDRS;
F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF; F2FS_OPTION(sbi).whint_mode = WHINT_MODE_OFF;
F2FS_OPTION(sbi).alloc_mode = ALLOC_MODE_DEFAULT; F2FS_OPTION(sbi).alloc_mode = ALLOC_MODE_DEFAULT;
...@@ -2996,7 +2997,7 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi) ...@@ -2996,7 +2997,7 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi)
cp_payload = __cp_payload(sbi); cp_payload = __cp_payload(sbi);
if (cp_pack_start_sum < cp_payload + 1 || if (cp_pack_start_sum < cp_payload + 1 ||
cp_pack_start_sum > blocks_per_seg - 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", f2fs_err(sbi, "Wrong cp_pack_start_sum: %u",
cp_pack_start_sum); cp_pack_start_sum);
return 1; return 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment