On 2020/7/16 3:07, Jaegeuk Kim wrote:
> On 07/15, Chao Yu wrote:
>> On 2020/7/7 11:51, Jaegeuk Kim wrote:
>>> On 07/07, Chao Yu wrote:
>>>> On 2020/7/7 11:21, Jaegeuk Kim wrote:
>>>>> Hi Chao,
>>>>>
>>>>> Do you have any brief design doc to present the idea?
>>>>
>>>> Hi Jaegeuk,
>>>>
>>>> You mean this whole patchset, right?
>>>>
>>>> I can add a brief design description in patch 0/5.
>>>
>>> Yeah, it's a bit hard to understand the whole flow.
>>
>> Jaegeuk,
>>
>> Do you have time to take a look at this idea summarized in
>> [PATCH 0/5]'s cover letter?
> 
> Sorry, I couldn't afford to sitting down to review the design.
> Let me give it a try soon.

Alright, let me know if you have any question about the idea.

> 
>>
>>>
>>> Thanks,
>>>
>>>>
>>>>>
>>>>> Thanks,
>>>>>
>>>>> On 06/30, Chao Yu wrote:
>>>>>> 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 <[email protected]>
>>>>>> ---
>>>>>>  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 1bb8278a1c4a..644a914af25a 100644
>>>>>> --- a/fs/f2fs/checkpoint.c
>>>>>> +++ b/fs/f2fs/checkpoint.c
>>>>>> @@ -1623,11 +1623,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);
>>>>>> @@ -1658,7 +1663,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 4276c0f79beb..41a91aa8c262 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);
>>>>>> @@ -393,6 +393,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 7d6c5f8ce16b..f06c77066284 100644
>>>>>> --- a/fs/f2fs/f2fs.h
>>>>>> +++ b/fs/f2fs/f2fs.h
>>>>>> @@ -996,7 +996,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 */
>>>>>> @@ -1005,8 +1007,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 {
>>>>>> @@ -3359,6 +3363,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 c10e82806c2a..8611ade06018 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);
>>>>>>                  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 3b718da69910..84807abe4e00 100644
>>>>>> --- a/fs/f2fs/gc.c
>>>>>> +++ b/fs/f2fs/gc.c
>>>>>> @@ -1448,7 +1448,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 5924b3965ae4..863ec6f1fb87 100644
>>>>>> --- a/fs/f2fs/segment.c
>>>>>> +++ b/fs/f2fs/segment.c
>>>>>> @@ -1958,7 +1958,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);
>>>>>>  }
>>>>>>  
>>>>>> @@ -2496,6 +2496,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;
>>>>>> @@ -2503,24 +2504,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])
>>>>>> @@ -2530,7 +2538,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;
>>>>>>  }
>>>>>>  
>>>>>>  /*
>>>>>> @@ -2540,12 +2548,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))
>>>>>> @@ -2622,6 +2632,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);
>>>>>> @@ -2738,11 +2785,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);
>>>>>> @@ -3126,19 +3177,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);
>>>>>>  
>>>>>> @@ -3204,9 +3242,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)
>>>>>> @@ -3574,7 +3609,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 {
>>>>>> @@ -3652,8 +3687,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);
>>>>>> @@ -4155,14 +4191,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)
>>>>>> @@ -4172,8 +4208,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);
>>>>>>  }
>>>>>> @@ -4408,7 +4449,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;
>>>>>> @@ -4637,7 +4678,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 f261e3e6a69b..8ff261550cbb 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 :                          
>>>>>> \
>>>>>> @@ -288,10 +291,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 {
>>>>>> @@ -305,8 +310,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);
>>>>>>  }
>>>>>>  
>>>>>> @@ -438,7 +441,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);
>>>>>> @@ -449,7 +452,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 80cb7cd358f8..0fefa130585f 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;
>>>>>> @@ -1614,7 +1615,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;
>>>>>> @@ -2946,7 +2947,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
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to