LCOV - code coverage report
Current view: top level - fs/f2fs - segment.h (source / functions) Hit Total Coverage
Test: Real Lines: 0 196 0.0 %
Date: 2020-10-17 15:46:43 Functions: 0 21 0.0 %
Legend: Neither, QEMU, Real, Both Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0
       2                 :            : /*
       3                 :            :  * fs/f2fs/segment.h
       4                 :            :  *
       5                 :            :  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
       6                 :            :  *             http://www.samsung.com/
       7                 :            :  */
       8                 :            : #include <linux/blkdev.h>
       9                 :            : #include <linux/backing-dev.h>
      10                 :            : 
      11                 :            : /* constant macro */
      12                 :            : #define NULL_SEGNO                      ((unsigned int)(~0))
      13                 :            : #define NULL_SECNO                      ((unsigned int)(~0))
      14                 :            : 
      15                 :            : #define DEF_RECLAIM_PREFREE_SEGMENTS    5       /* 5% over total segments */
      16                 :            : #define DEF_MAX_RECLAIM_PREFREE_SEGMENTS        4096    /* 8GB in maximum */
      17                 :            : 
      18                 :            : #define F2FS_MIN_SEGMENTS       9 /* SB + 2 (CP + SIT + NAT) + SSA + MAIN */
      19                 :            : 
      20                 :            : /* L: Logical segment # in volume, R: Relative segment # in main area */
      21                 :            : #define GET_L2R_SEGNO(free_i, segno)    ((segno) - (free_i)->start_segno)
      22                 :            : #define GET_R2L_SEGNO(free_i, segno)    ((segno) + (free_i)->start_segno)
      23                 :            : 
      24                 :            : #define IS_DATASEG(t)   ((t) <= CURSEG_COLD_DATA)
      25                 :            : #define IS_NODESEG(t)   ((t) >= CURSEG_HOT_NODE)
      26                 :            : 
      27                 :            : #define IS_HOT(t)       ((t) == CURSEG_HOT_NODE || (t) == CURSEG_HOT_DATA)
      28                 :            : #define IS_WARM(t)      ((t) == CURSEG_WARM_NODE || (t) == CURSEG_WARM_DATA)
      29                 :            : #define IS_COLD(t)      ((t) == CURSEG_COLD_NODE || (t) == CURSEG_COLD_DATA)
      30                 :            : 
      31                 :            : #define IS_CURSEG(sbi, seg)                                             \
      32                 :            :         (((seg) == CURSEG_I(sbi, CURSEG_HOT_DATA)->segno) || \
      33                 :            :          ((seg) == CURSEG_I(sbi, CURSEG_WARM_DATA)->segno) ||        \
      34                 :            :          ((seg) == CURSEG_I(sbi, CURSEG_COLD_DATA)->segno) ||        \
      35                 :            :          ((seg) == CURSEG_I(sbi, CURSEG_HOT_NODE)->segno) || \
      36                 :            :          ((seg) == CURSEG_I(sbi, CURSEG_WARM_NODE)->segno) ||        \
      37                 :            :          ((seg) == CURSEG_I(sbi, CURSEG_COLD_NODE)->segno))
      38                 :            : 
      39                 :            : #define IS_CURSEC(sbi, secno)                                           \
      40                 :            :         (((secno) == CURSEG_I(sbi, CURSEG_HOT_DATA)->segno /         \
      41                 :            :           (sbi)->segs_per_sec) ||    \
      42                 :            :          ((secno) == CURSEG_I(sbi, CURSEG_WARM_DATA)->segno /                \
      43                 :            :           (sbi)->segs_per_sec) ||    \
      44                 :            :          ((secno) == CURSEG_I(sbi, CURSEG_COLD_DATA)->segno /                \
      45                 :            :           (sbi)->segs_per_sec) ||    \
      46                 :            :          ((secno) == CURSEG_I(sbi, CURSEG_HOT_NODE)->segno /         \
      47                 :            :           (sbi)->segs_per_sec) ||    \
      48                 :            :          ((secno) == CURSEG_I(sbi, CURSEG_WARM_NODE)->segno /                \
      49                 :            :           (sbi)->segs_per_sec) ||    \
      50                 :            :          ((secno) == CURSEG_I(sbi, CURSEG_COLD_NODE)->segno /                \
      51                 :            :           (sbi)->segs_per_sec))      \
      52                 :            : 
      53                 :            : #define MAIN_BLKADDR(sbi)                                               \
      54                 :            :         (SM_I(sbi) ? SM_I(sbi)->main_blkaddr :                               \
      55                 :            :                 le32_to_cpu(F2FS_RAW_SUPER(sbi)->main_blkaddr))
      56                 :            : #define SEG0_BLKADDR(sbi)                                               \
      57                 :            :         (SM_I(sbi) ? SM_I(sbi)->seg0_blkaddr :                               \
      58                 :            :                 le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment0_blkaddr))
      59                 :            : 
      60                 :            : #define MAIN_SEGS(sbi)  (SM_I(sbi)->main_segments)
      61                 :            : #define MAIN_SECS(sbi)  ((sbi)->total_sections)
      62                 :            : 
      63                 :            : #define TOTAL_SEGS(sbi)                                                 \
      64                 :            :         (SM_I(sbi) ? SM_I(sbi)->segment_count :                              \
      65                 :            :                 le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment_count))
      66                 :            : #define TOTAL_BLKS(sbi) (TOTAL_SEGS(sbi) << (sbi)->log_blocks_per_seg)
      67                 :            : 
      68                 :            : #define MAX_BLKADDR(sbi)        (SEG0_BLKADDR(sbi) + TOTAL_BLKS(sbi))
      69                 :            : #define SEGMENT_SIZE(sbi)       (1ULL << ((sbi)->log_blocksize +       \
      70                 :            :                                         (sbi)->log_blocks_per_seg))
      71                 :            : 
      72                 :            : #define START_BLOCK(sbi, segno) (SEG0_BLKADDR(sbi) +                    \
      73                 :            :          (GET_R2L_SEGNO(FREE_I(sbi), segno) << (sbi)->log_blocks_per_seg))
      74                 :            : 
      75                 :            : #define NEXT_FREE_BLKADDR(sbi, curseg)                                  \
      76                 :            :         (START_BLOCK(sbi, (curseg)->segno) + (curseg)->next_blkoff)
      77                 :            : 
      78                 :            : #define GET_SEGOFF_FROM_SEG0(sbi, blk_addr)     ((blk_addr) - SEG0_BLKADDR(sbi))
      79                 :            : #define GET_SEGNO_FROM_SEG0(sbi, blk_addr)                              \
      80                 :            :         (GET_SEGOFF_FROM_SEG0(sbi, blk_addr) >> (sbi)->log_blocks_per_seg)
      81                 :            : #define GET_BLKOFF_FROM_SEG0(sbi, blk_addr)                             \
      82                 :            :         (GET_SEGOFF_FROM_SEG0(sbi, blk_addr) & ((sbi)->blocks_per_seg - 1))
      83                 :            : 
      84                 :            : #define GET_SEGNO(sbi, blk_addr)                                        \
      85                 :            :         ((!__is_valid_data_blkaddr(blk_addr)) ?                 \
      86                 :            :         NULL_SEGNO : GET_L2R_SEGNO(FREE_I(sbi),                 \
      87                 :            :                 GET_SEGNO_FROM_SEG0(sbi, blk_addr)))
      88                 :            : #define BLKS_PER_SEC(sbi)                                       \
      89                 :            :         ((sbi)->segs_per_sec * (sbi)->blocks_per_seg)
      90                 :            : #define GET_SEC_FROM_SEG(sbi, segno)                            \
      91                 :            :         ((segno) / (sbi)->segs_per_sec)
      92                 :            : #define GET_SEG_FROM_SEC(sbi, secno)                            \
      93                 :            :         ((secno) * (sbi)->segs_per_sec)
      94                 :            : #define GET_ZONE_FROM_SEC(sbi, secno)                           \
      95                 :            :         ((secno) / (sbi)->secs_per_zone)
      96                 :            : #define GET_ZONE_FROM_SEG(sbi, segno)                           \
      97                 :            :         GET_ZONE_FROM_SEC(sbi, GET_SEC_FROM_SEG(sbi, segno))
      98                 :            : 
      99                 :            : #define GET_SUM_BLOCK(sbi, segno)                               \
     100                 :            :         ((sbi)->sm_info->ssa_blkaddr + (segno))
     101                 :            : 
     102                 :            : #define GET_SUM_TYPE(footer) ((footer)->entry_type)
     103                 :            : #define SET_SUM_TYPE(footer, type) ((footer)->entry_type = (type))
     104                 :            : 
     105                 :            : #define SIT_ENTRY_OFFSET(sit_i, segno)                                  \
     106                 :            :         ((segno) % (sit_i)->sents_per_block)
     107                 :            : #define SIT_BLOCK_OFFSET(segno)                                 \
     108                 :            :         ((segno) / SIT_ENTRY_PER_BLOCK)
     109                 :            : #define START_SEGNO(segno)              \
     110                 :            :         (SIT_BLOCK_OFFSET(segno) * SIT_ENTRY_PER_BLOCK)
     111                 :            : #define SIT_BLK_CNT(sbi)                        \
     112                 :            :         DIV_ROUND_UP(MAIN_SEGS(sbi), SIT_ENTRY_PER_BLOCK)
     113                 :            : #define f2fs_bitmap_size(nr)                    \
     114                 :            :         (BITS_TO_LONGS(nr) * sizeof(unsigned long))
     115                 :            : 
     116                 :            : #define SECTOR_FROM_BLOCK(blk_addr)                                     \
     117                 :            :         (((sector_t)blk_addr) << F2FS_LOG_SECTORS_PER_BLOCK)
     118                 :            : #define SECTOR_TO_BLOCK(sectors)                                        \
     119                 :            :         ((sectors) >> F2FS_LOG_SECTORS_PER_BLOCK)
     120                 :            : 
     121                 :            : /*
     122                 :            :  * indicate a block allocation direction: RIGHT and LEFT.
     123                 :            :  * RIGHT means allocating new sections towards the end of volume.
     124                 :            :  * LEFT means the opposite direction.
     125                 :            :  */
     126                 :            : enum {
     127                 :            :         ALLOC_RIGHT = 0,
     128                 :            :         ALLOC_LEFT
     129                 :            : };
     130                 :            : 
     131                 :            : /*
     132                 :            :  * In the victim_sel_policy->alloc_mode, there are two block allocation modes.
     133                 :            :  * LFS writes data sequentially with cleaning operations.
     134                 :            :  * SSR (Slack Space Recycle) reuses obsolete space without cleaning operations.
     135                 :            :  */
     136                 :            : enum {
     137                 :            :         LFS = 0,
     138                 :            :         SSR
     139                 :            : };
     140                 :            : 
     141                 :            : /*
     142                 :            :  * In the victim_sel_policy->gc_mode, there are two gc, aka cleaning, modes.
     143                 :            :  * GC_CB is based on cost-benefit algorithm.
     144                 :            :  * GC_GREEDY is based on greedy algorithm.
     145                 :            :  */
     146                 :            : enum {
     147                 :            :         GC_CB = 0,
     148                 :            :         GC_GREEDY,
     149                 :            :         ALLOC_NEXT,
     150                 :            :         FLUSH_DEVICE,
     151                 :            :         MAX_GC_POLICY,
     152                 :            : };
     153                 :            : 
     154                 :            : /*
     155                 :            :  * BG_GC means the background cleaning job.
     156                 :            :  * FG_GC means the on-demand cleaning job.
     157                 :            :  * FORCE_FG_GC means on-demand cleaning job in background.
     158                 :            :  */
     159                 :            : enum {
     160                 :            :         BG_GC = 0,
     161                 :            :         FG_GC,
     162                 :            :         FORCE_FG_GC,
     163                 :            : };
     164                 :            : 
     165                 :            : /* for a function parameter to select a victim segment */
     166                 :            : struct victim_sel_policy {
     167                 :            :         int alloc_mode;                 /* LFS or SSR */
     168                 :            :         int gc_mode;                    /* GC_CB or GC_GREEDY */
     169                 :            :         unsigned long *dirty_segmap;    /* dirty segment bitmap */
     170                 :            :         unsigned int max_search;        /* maximum # of segments to search */
     171                 :            :         unsigned int offset;            /* last scanned bitmap offset */
     172                 :            :         unsigned int ofs_unit;          /* bitmap search unit */
     173                 :            :         unsigned int min_cost;          /* minimum cost */
     174                 :            :         unsigned int min_segno;         /* segment # having min. cost */
     175                 :            : };
     176                 :            : 
     177                 :            : struct seg_entry {
     178                 :            :         unsigned int type:6;            /* segment type like CURSEG_XXX_TYPE */
     179                 :            :         unsigned int valid_blocks:10;   /* # of valid blocks */
     180                 :            :         unsigned int ckpt_valid_blocks:10;      /* # of valid blocks last cp */
     181                 :            :         unsigned int padding:6;         /* padding */
     182                 :            :         unsigned char *cur_valid_map;   /* validity bitmap of blocks */
     183                 :            : #ifdef CONFIG_F2FS_CHECK_FS
     184                 :            :         unsigned char *cur_valid_map_mir;       /* mirror of current valid bitmap */
     185                 :            : #endif
     186                 :            :         /*
     187                 :            :          * # of valid blocks and the validity bitmap stored in the the last
     188                 :            :          * checkpoint pack. This information is used by the SSR mode.
     189                 :            :          */
     190                 :            :         unsigned char *ckpt_valid_map;  /* validity bitmap of blocks last cp */
     191                 :            :         unsigned char *discard_map;
     192                 :            :         unsigned long long mtime;       /* modification time of the segment */
     193                 :            : };
     194                 :            : 
     195                 :            : struct sec_entry {
     196                 :            :         unsigned int valid_blocks;      /* # of valid blocks in a section */
     197                 :            : };
     198                 :            : 
     199                 :            : struct segment_allocation {
     200                 :            :         void (*allocate_segment)(struct f2fs_sb_info *, int, bool);
     201                 :            : };
     202                 :            : 
     203                 :            : /*
     204                 :            :  * this value is set in page as a private data which indicate that
     205                 :            :  * the page is atomically written, and it is in inmem_pages list.
     206                 :            :  */
     207                 :            : #define ATOMIC_WRITTEN_PAGE             ((unsigned long)-1)
     208                 :            : #define DUMMY_WRITTEN_PAGE              ((unsigned long)-2)
     209                 :            : 
     210                 :            : #define IS_ATOMIC_WRITTEN_PAGE(page)                    \
     211                 :            :                 (page_private(page) == (unsigned long)ATOMIC_WRITTEN_PAGE)
     212                 :            : #define IS_DUMMY_WRITTEN_PAGE(page)                     \
     213                 :            :                 (page_private(page) == (unsigned long)DUMMY_WRITTEN_PAGE)
     214                 :            : 
     215                 :            : #define MAX_SKIP_GC_COUNT                       16
     216                 :            : 
     217                 :            : struct inmem_pages {
     218                 :            :         struct list_head list;
     219                 :            :         struct page *page;
     220                 :            :         block_t old_addr;               /* for revoking when fail to commit */
     221                 :            : };
     222                 :            : 
     223                 :            : struct sit_info {
     224                 :            :         const struct segment_allocation *s_ops;
     225                 :            : 
     226                 :            :         block_t sit_base_addr;          /* start block address of SIT area */
     227                 :            :         block_t sit_blocks;             /* # of blocks used by SIT area */
     228                 :            :         block_t written_valid_blocks;   /* # of valid blocks in main area */
     229                 :            :         char *bitmap;                   /* all bitmaps pointer */
     230                 :            :         char *sit_bitmap;               /* SIT bitmap pointer */
     231                 :            : #ifdef CONFIG_F2FS_CHECK_FS
     232                 :            :         char *sit_bitmap_mir;           /* SIT bitmap mirror */
     233                 :            : 
     234                 :            :         /* bitmap of segments to be ignored by GC in case of errors */
     235                 :            :         unsigned long *invalid_segmap;
     236                 :            : #endif
     237                 :            :         unsigned int bitmap_size;       /* SIT bitmap size */
     238                 :            : 
     239                 :            :         unsigned long *tmp_map;                 /* bitmap for temporal use */
     240                 :            :         unsigned long *dirty_sentries_bitmap;   /* bitmap for dirty sentries */
     241                 :            :         unsigned int dirty_sentries;            /* # of dirty sentries */
     242                 :            :         unsigned int sents_per_block;           /* # of SIT entries per block */
     243                 :            :         struct rw_semaphore sentry_lock;        /* to protect SIT cache */
     244                 :            :         struct seg_entry *sentries;             /* SIT segment-level cache */
     245                 :            :         struct sec_entry *sec_entries;          /* SIT section-level cache */
     246                 :            : 
     247                 :            :         /* for cost-benefit algorithm in cleaning procedure */
     248                 :            :         unsigned long long elapsed_time;        /* elapsed time after mount */
     249                 :            :         unsigned long long mounted_time;        /* mount time */
     250                 :            :         unsigned long long min_mtime;           /* min. modification time */
     251                 :            :         unsigned long long max_mtime;           /* max. modification time */
     252                 :            : 
     253                 :            :         unsigned int last_victim[MAX_GC_POLICY]; /* last victim segment # */
     254                 :            : };
     255                 :            : 
     256                 :            : struct free_segmap_info {
     257                 :            :         unsigned int start_segno;       /* start segment number logically */
     258                 :            :         unsigned int free_segments;     /* # of free segments */
     259                 :            :         unsigned int free_sections;     /* # of free sections */
     260                 :            :         spinlock_t segmap_lock;         /* free segmap lock */
     261                 :            :         unsigned long *free_segmap;     /* free segment bitmap */
     262                 :            :         unsigned long *free_secmap;     /* free section bitmap */
     263                 :            : };
     264                 :            : 
     265                 :            : /* Notice: The order of dirty type is same with CURSEG_XXX in f2fs.h */
     266                 :            : enum dirty_type {
     267                 :            :         DIRTY_HOT_DATA,         /* dirty segments assigned as hot data logs */
     268                 :            :         DIRTY_WARM_DATA,        /* dirty segments assigned as warm data logs */
     269                 :            :         DIRTY_COLD_DATA,        /* dirty segments assigned as cold data logs */
     270                 :            :         DIRTY_HOT_NODE,         /* dirty segments assigned as hot node logs */
     271                 :            :         DIRTY_WARM_NODE,        /* dirty segments assigned as warm node logs */
     272                 :            :         DIRTY_COLD_NODE,        /* dirty segments assigned as cold node logs */
     273                 :            :         DIRTY,                  /* to count # of dirty segments */
     274                 :            :         PRE,                    /* to count # of entirely obsolete segments */
     275                 :            :         NR_DIRTY_TYPE
     276                 :            : };
     277                 :            : 
     278                 :            : struct dirty_seglist_info {
     279                 :            :         const struct victim_selection *v_ops;   /* victim selction operation */
     280                 :            :         unsigned long *dirty_segmap[NR_DIRTY_TYPE];
     281                 :            :         struct mutex seglist_lock;              /* lock for segment bitmaps */
     282                 :            :         int nr_dirty[NR_DIRTY_TYPE];            /* # of dirty segments */
     283                 :            :         unsigned long *victim_secmap;           /* background GC victims */
     284                 :            : };
     285                 :            : 
     286                 :            : /* victim selection function for cleaning and SSR */
     287                 :            : struct victim_selection {
     288                 :            :         int (*get_victim)(struct f2fs_sb_info *, unsigned int *,
     289                 :            :                                                         int, int, char);
     290                 :            : };
     291                 :            : 
     292                 :            : /* for active log information */
     293                 :            : struct curseg_info {
     294                 :            :         struct mutex curseg_mutex;              /* lock for consistency */
     295                 :            :         struct f2fs_summary_block *sum_blk;     /* cached summary block */
     296                 :            :         struct rw_semaphore journal_rwsem;      /* protect journal area */
     297                 :            :         struct f2fs_journal *journal;           /* cached journal info */
     298                 :            :         unsigned char alloc_type;               /* current allocation type */
     299                 :            :         unsigned int segno;                     /* current segment number */
     300                 :            :         unsigned short next_blkoff;             /* next block offset to write */
     301                 :            :         unsigned int zone;                      /* current zone number */
     302                 :            :         unsigned int next_segno;                /* preallocated segment */
     303                 :            : };
     304                 :            : 
     305                 :            : struct sit_entry_set {
     306                 :            :         struct list_head set_list;      /* link with all sit sets */
     307                 :            :         unsigned int start_segno;       /* start segno of sits in set */
     308                 :            :         unsigned int entry_cnt;         /* the # of sit entries in set */
     309                 :            : };
     310                 :            : 
     311                 :            : /*
     312                 :            :  * inline functions
     313                 :            :  */
     314                 :            : static inline struct curseg_info *CURSEG_I(struct f2fs_sb_info *sbi, int type)
     315                 :            : {
     316                 :          0 :         return (struct curseg_info *)(SM_I(sbi)->curseg_array + type);
     317                 :            : }
     318                 :            : 
     319                 :            : static inline struct seg_entry *get_seg_entry(struct f2fs_sb_info *sbi,
     320                 :            :                                                 unsigned int segno)
     321                 :            : {
     322                 :            :         struct sit_info *sit_i = SIT_I(sbi);
     323                 :          0 :         return &sit_i->sentries[segno];
     324                 :            : }
     325                 :            : 
     326                 :            : static inline struct sec_entry *get_sec_entry(struct f2fs_sb_info *sbi,
     327                 :            :                                                 unsigned int segno)
     328                 :            : {
     329                 :            :         struct sit_info *sit_i = SIT_I(sbi);
     330                 :          0 :         return &sit_i->sec_entries[GET_SEC_FROM_SEG(sbi, segno)];
     331                 :            : }
     332                 :            : 
     333                 :          0 : static inline unsigned int get_valid_blocks(struct f2fs_sb_info *sbi,
     334                 :            :                                 unsigned int segno, bool use_section)
     335                 :            : {
     336                 :            :         /*
     337                 :            :          * In order to get # of valid blocks in a section instantly from many
     338                 :            :          * segments, f2fs manages two counting structures separately.
     339                 :            :          */
     340                 :          0 :         if (use_section && __is_large_section(sbi))
     341                 :          0 :                 return get_sec_entry(sbi, segno)->valid_blocks;
     342                 :            :         else
     343                 :          0 :                 return get_seg_entry(sbi, segno)->valid_blocks;
     344                 :            : }
     345                 :            : 
     346                 :            : static inline unsigned int get_ckpt_valid_blocks(struct f2fs_sb_info *sbi,
     347                 :            :                                 unsigned int segno)
     348                 :            : {
     349                 :          0 :         return get_seg_entry(sbi, segno)->ckpt_valid_blocks;
     350                 :            : }
     351                 :            : 
     352                 :          0 : static inline void seg_info_from_raw_sit(struct seg_entry *se,
     353                 :            :                                         struct f2fs_sit_entry *rs)
     354                 :            : {
     355                 :          0 :         se->valid_blocks = GET_SIT_VBLOCKS(rs);
     356                 :          0 :         se->ckpt_valid_blocks = GET_SIT_VBLOCKS(rs);
     357                 :          0 :         memcpy(se->cur_valid_map, rs->valid_map, SIT_VBLOCK_MAP_SIZE);
     358                 :          0 :         memcpy(se->ckpt_valid_map, rs->valid_map, SIT_VBLOCK_MAP_SIZE);
     359                 :            : #ifdef CONFIG_F2FS_CHECK_FS
     360                 :            :         memcpy(se->cur_valid_map_mir, rs->valid_map, SIT_VBLOCK_MAP_SIZE);
     361                 :            : #endif
     362                 :          0 :         se->type = GET_SIT_TYPE(rs);
     363                 :          0 :         se->mtime = le64_to_cpu(rs->mtime);
     364                 :          0 : }
     365                 :            : 
     366                 :          0 : static inline void __seg_info_to_raw_sit(struct seg_entry *se,
     367                 :            :                                         struct f2fs_sit_entry *rs)
     368                 :            : {
     369                 :          0 :         unsigned short raw_vblocks = (se->type << SIT_VBLOCKS_SHIFT) |
     370                 :          0 :                                         se->valid_blocks;
     371                 :          0 :         rs->vblocks = cpu_to_le16(raw_vblocks);
     372                 :          0 :         memcpy(rs->valid_map, se->cur_valid_map, SIT_VBLOCK_MAP_SIZE);
     373                 :          0 :         rs->mtime = cpu_to_le64(se->mtime);
     374                 :          0 : }
     375                 :            : 
     376                 :          0 : static inline void seg_info_to_sit_page(struct f2fs_sb_info *sbi,
     377                 :            :                                 struct page *page, unsigned int start)
     378                 :            : {
     379                 :            :         struct f2fs_sit_block *raw_sit;
     380                 :            :         struct seg_entry *se;
     381                 :            :         struct f2fs_sit_entry *rs;
     382                 :          0 :         unsigned int end = min(start + SIT_ENTRY_PER_BLOCK,
     383                 :            :                                         (unsigned long)MAIN_SEGS(sbi));
     384                 :            :         int i;
     385                 :            : 
     386                 :            :         raw_sit = (struct f2fs_sit_block *)page_address(page);
     387                 :          0 :         memset(raw_sit, 0, PAGE_SIZE);
     388                 :          0 :         for (i = 0; i < end - start; i++) {
     389                 :          0 :                 rs = &raw_sit->entries[i];
     390                 :          0 :                 se = get_seg_entry(sbi, start + i);
     391                 :          0 :                 __seg_info_to_raw_sit(se, rs);
     392                 :            :         }
     393                 :          0 : }
     394                 :            : 
     395                 :          0 : static inline void seg_info_to_raw_sit(struct seg_entry *se,
     396                 :            :                                         struct f2fs_sit_entry *rs)
     397                 :            : {
     398                 :          0 :         __seg_info_to_raw_sit(se, rs);
     399                 :            : 
     400                 :          0 :         memcpy(se->ckpt_valid_map, rs->valid_map, SIT_VBLOCK_MAP_SIZE);
     401                 :          0 :         se->ckpt_valid_blocks = se->valid_blocks;
     402                 :          0 : }
     403                 :            : 
     404                 :          0 : static inline unsigned int find_next_inuse(struct free_segmap_info *free_i,
     405                 :            :                 unsigned int max, unsigned int segno)
     406                 :            : {
     407                 :            :         unsigned int ret;
     408                 :            :         spin_lock(&free_i->segmap_lock);
     409                 :          0 :         ret = find_next_bit(free_i->free_segmap, max, segno);
     410                 :            :         spin_unlock(&free_i->segmap_lock);
     411                 :          0 :         return ret;
     412                 :            : }
     413                 :            : 
     414                 :          0 : static inline void __set_free(struct f2fs_sb_info *sbi, unsigned int segno)
     415                 :            : {
     416                 :            :         struct free_segmap_info *free_i = FREE_I(sbi);
     417                 :          0 :         unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
     418                 :          0 :         unsigned int start_segno = GET_SEG_FROM_SEC(sbi, secno);
     419                 :            :         unsigned int next;
     420                 :            : 
     421                 :            :         spin_lock(&free_i->segmap_lock);
     422                 :          0 :         clear_bit(segno, free_i->free_segmap);
     423                 :          0 :         free_i->free_segments++;
     424                 :            : 
     425                 :          0 :         next = find_next_bit(free_i->free_segmap,
     426                 :            :                         start_segno + sbi->segs_per_sec, start_segno);
     427                 :          0 :         if (next >= start_segno + sbi->segs_per_sec) {
     428                 :          0 :                 clear_bit(secno, free_i->free_secmap);
     429                 :          0 :                 free_i->free_sections++;
     430                 :            :         }
     431                 :            :         spin_unlock(&free_i->segmap_lock);
     432                 :          0 : }
     433                 :            : 
     434                 :          0 : static inline void __set_inuse(struct f2fs_sb_info *sbi,
     435                 :            :                 unsigned int segno)
     436                 :            : {
     437                 :            :         struct free_segmap_info *free_i = FREE_I(sbi);
     438                 :          0 :         unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
     439                 :            : 
     440                 :          0 :         set_bit(segno, free_i->free_segmap);
     441                 :          0 :         free_i->free_segments--;
     442                 :          0 :         if (!test_and_set_bit(secno, free_i->free_secmap))
     443                 :          0 :                 free_i->free_sections--;
     444                 :          0 : }
     445                 :            : 
     446                 :          0 : static inline void __set_test_and_free(struct f2fs_sb_info *sbi,
     447                 :            :                 unsigned int segno)
     448                 :            : {
     449                 :            :         struct free_segmap_info *free_i = FREE_I(sbi);
     450                 :          0 :         unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
     451                 :          0 :         unsigned int start_segno = GET_SEG_FROM_SEC(sbi, secno);
     452                 :            :         unsigned int next;
     453                 :            : 
     454                 :            :         spin_lock(&free_i->segmap_lock);
     455                 :          0 :         if (test_and_clear_bit(segno, free_i->free_segmap)) {
     456                 :          0 :                 free_i->free_segments++;
     457                 :            : 
     458                 :          0 :                 if (IS_CURSEC(sbi, secno))
     459                 :            :                         goto skip_free;
     460                 :          0 :                 next = find_next_bit(free_i->free_segmap,
     461                 :            :                                 start_segno + sbi->segs_per_sec, start_segno);
     462                 :          0 :                 if (next >= start_segno + sbi->segs_per_sec) {
     463                 :          0 :                         if (test_and_clear_bit(secno, free_i->free_secmap))
     464                 :          0 :                                 free_i->free_sections++;
     465                 :            :                 }
     466                 :            :         }
     467                 :            : skip_free:
     468                 :            :         spin_unlock(&free_i->segmap_lock);
     469                 :          0 : }
     470                 :            : 
     471                 :          0 : static inline void __set_test_and_inuse(struct f2fs_sb_info *sbi,
     472                 :            :                 unsigned int segno)
     473                 :            : {
     474                 :            :         struct free_segmap_info *free_i = FREE_I(sbi);
     475                 :          0 :         unsigned int secno = GET_SEC_FROM_SEG(sbi, segno);
     476                 :            : 
     477                 :            :         spin_lock(&free_i->segmap_lock);
     478                 :          0 :         if (!test_and_set_bit(segno, free_i->free_segmap)) {
     479                 :          0 :                 free_i->free_segments--;
     480                 :          0 :                 if (!test_and_set_bit(secno, free_i->free_secmap))
     481                 :          0 :                         free_i->free_sections--;
     482                 :            :         }
     483                 :            :         spin_unlock(&free_i->segmap_lock);
     484                 :          0 : }
     485                 :            : 
     486                 :            : static inline void get_sit_bitmap(struct f2fs_sb_info *sbi,
     487                 :            :                 void *dst_addr)
     488                 :            : {
     489                 :            :         struct sit_info *sit_i = SIT_I(sbi);
     490                 :            : 
     491                 :            : #ifdef CONFIG_F2FS_CHECK_FS
     492                 :            :         if (memcmp(sit_i->sit_bitmap, sit_i->sit_bitmap_mir,
     493                 :            :                                                 sit_i->bitmap_size))
     494                 :            :                 f2fs_bug_on(sbi, 1);
     495                 :            : #endif
     496                 :          0 :         memcpy(dst_addr, sit_i->sit_bitmap, sit_i->bitmap_size);
     497                 :            : }
     498                 :            : 
     499                 :            : static inline block_t written_block_count(struct f2fs_sb_info *sbi)
     500                 :            : {
     501                 :          0 :         return SIT_I(sbi)->written_valid_blocks;
     502                 :            : }
     503                 :            : 
     504                 :            : static inline unsigned int free_segments(struct f2fs_sb_info *sbi)
     505                 :            : {
     506                 :          0 :         return FREE_I(sbi)->free_segments;
     507                 :            : }
     508                 :            : 
     509                 :            : static inline int reserved_segments(struct f2fs_sb_info *sbi)
     510                 :            : {
     511                 :          0 :         return SM_I(sbi)->reserved_segments;
     512                 :            : }
     513                 :            : 
     514                 :            : static inline unsigned int free_sections(struct f2fs_sb_info *sbi)
     515                 :            : {
     516                 :          0 :         return FREE_I(sbi)->free_sections;
     517                 :            : }
     518                 :            : 
     519                 :            : static inline unsigned int prefree_segments(struct f2fs_sb_info *sbi)
     520                 :            : {
     521                 :          0 :         return DIRTY_I(sbi)->nr_dirty[PRE];
     522                 :            : }
     523                 :            : 
     524                 :            : static inline unsigned int dirty_segments(struct f2fs_sb_info *sbi)
     525                 :            : {
     526                 :          0 :         return DIRTY_I(sbi)->nr_dirty[DIRTY_HOT_DATA] +
     527                 :          0 :                 DIRTY_I(sbi)->nr_dirty[DIRTY_WARM_DATA] +
     528                 :          0 :                 DIRTY_I(sbi)->nr_dirty[DIRTY_COLD_DATA] +
     529                 :          0 :                 DIRTY_I(sbi)->nr_dirty[DIRTY_HOT_NODE] +
     530                 :          0 :                 DIRTY_I(sbi)->nr_dirty[DIRTY_WARM_NODE] +
     531                 :          0 :                 DIRTY_I(sbi)->nr_dirty[DIRTY_COLD_NODE];
     532                 :            : }
     533                 :            : 
     534                 :            : static inline int overprovision_segments(struct f2fs_sb_info *sbi)
     535                 :            : {
     536                 :          0 :         return SM_I(sbi)->ovp_segments;
     537                 :            : }
     538                 :            : 
     539                 :            : static inline int reserved_sections(struct f2fs_sb_info *sbi)
     540                 :            : {
     541                 :          0 :         return GET_SEC_FROM_SEG(sbi, (unsigned int)reserved_segments(sbi));
     542                 :            : }
     543                 :            : 
     544                 :          0 : static inline bool has_curseg_enough_space(struct f2fs_sb_info *sbi)
     545                 :            : {
     546                 :          0 :         unsigned int node_blocks = get_pages(sbi, F2FS_DIRTY_NODES) +
     547                 :            :                                         get_pages(sbi, F2FS_DIRTY_DENTS);
     548                 :          0 :         unsigned int dent_blocks = get_pages(sbi, F2FS_DIRTY_DENTS);
     549                 :            :         unsigned int segno, left_blocks;
     550                 :            :         int i;
     551                 :            : 
     552                 :            :         /* check current node segment */
     553                 :          0 :         for (i = CURSEG_HOT_NODE; i <= CURSEG_COLD_NODE; i++) {
     554                 :          0 :                 segno = CURSEG_I(sbi, i)->segno;
     555                 :          0 :                 left_blocks = sbi->blocks_per_seg -
     556                 :          0 :                         get_seg_entry(sbi, segno)->ckpt_valid_blocks;
     557                 :            : 
     558                 :          0 :                 if (node_blocks > left_blocks)
     559                 :            :                         return false;
     560                 :            :         }
     561                 :            : 
     562                 :            :         /* check current data segment */
     563                 :          0 :         segno = CURSEG_I(sbi, CURSEG_HOT_DATA)->segno;
     564                 :          0 :         left_blocks = sbi->blocks_per_seg -
     565                 :          0 :                         get_seg_entry(sbi, segno)->ckpt_valid_blocks;
     566                 :          0 :         if (dent_blocks > left_blocks)
     567                 :            :                 return false;
     568                 :          0 :         return true;
     569                 :            : }
     570                 :            : 
     571                 :          0 : static inline bool has_not_enough_free_secs(struct f2fs_sb_info *sbi,
     572                 :            :                                         int freed, int needed)
     573                 :            : {
     574                 :            :         int node_secs = get_blocktype_secs(sbi, F2FS_DIRTY_NODES);
     575                 :            :         int dent_secs = get_blocktype_secs(sbi, F2FS_DIRTY_DENTS);
     576                 :            :         int imeta_secs = get_blocktype_secs(sbi, F2FS_DIRTY_IMETA);
     577                 :            : 
     578                 :          0 :         if (unlikely(is_sbi_flag_set(sbi, SBI_POR_DOING)))
     579                 :            :                 return false;
     580                 :            : 
     581                 :          0 :         if (free_sections(sbi) + freed == reserved_sections(sbi) + needed &&
     582                 :          0 :                         has_curseg_enough_space(sbi))
     583                 :            :                 return false;
     584                 :          0 :         return (free_sections(sbi) + freed) <=
     585                 :          0 :                 (node_secs + 2 * dent_secs + imeta_secs +
     586                 :          0 :                 reserved_sections(sbi) + needed);
     587                 :            : }
     588                 :            : 
     589                 :          0 : static inline bool f2fs_is_checkpoint_ready(struct f2fs_sb_info *sbi)
     590                 :            : {
     591                 :          0 :         if (likely(!is_sbi_flag_set(sbi, SBI_CP_DISABLED)))
     592                 :            :                 return true;
     593                 :          0 :         if (likely(!has_not_enough_free_secs(sbi, 0, 0)))
     594                 :            :                 return true;
     595                 :          0 :         return false;
     596                 :            : }
     597                 :            : 
     598                 :            : static inline bool excess_prefree_segs(struct f2fs_sb_info *sbi)
     599                 :            : {
     600                 :          0 :         return prefree_segments(sbi) > SM_I(sbi)->rec_prefree_segments;
     601                 :            : }
     602                 :            : 
     603                 :          0 : static inline int utilization(struct f2fs_sb_info *sbi)
     604                 :            : {
     605                 :          0 :         return div_u64((u64)valid_user_blocks(sbi) * 100,
     606                 :            :                                         sbi->user_block_count);
     607                 :            : }
     608                 :            : 
     609                 :            : /*
     610                 :            :  * Sometimes f2fs may be better to drop out-of-place update policy.
     611                 :            :  * And, users can control the policy through sysfs entries.
     612                 :            :  * There are five policies with triggering conditions as follows.
     613                 :            :  * F2FS_IPU_FORCE - all the time,
     614                 :            :  * F2FS_IPU_SSR - if SSR mode is activated,
     615                 :            :  * F2FS_IPU_UTIL - if FS utilization is over threashold,
     616                 :            :  * F2FS_IPU_SSR_UTIL - if SSR mode is activated and FS utilization is over
     617                 :            :  *                     threashold,
     618                 :            :  * F2FS_IPU_FSYNC - activated in fsync path only for high performance flash
     619                 :            :  *                     storages. IPU will be triggered only if the # of dirty
     620                 :            :  *                     pages over min_fsync_blocks.
     621                 :            :  * F2FS_IPUT_DISABLE - disable IPU. (=default option)
     622                 :            :  */
     623                 :            : #define DEF_MIN_IPU_UTIL        70
     624                 :            : #define DEF_MIN_FSYNC_BLOCKS    8
     625                 :            : #define DEF_MIN_HOT_BLOCKS      16
     626                 :            : 
     627                 :            : #define SMALL_VOLUME_SEGMENTS   (16 * 512)      /* 16GB */
     628                 :            : 
     629                 :            : enum {
     630                 :            :         F2FS_IPU_FORCE,
     631                 :            :         F2FS_IPU_SSR,
     632                 :            :         F2FS_IPU_UTIL,
     633                 :            :         F2FS_IPU_SSR_UTIL,
     634                 :            :         F2FS_IPU_FSYNC,
     635                 :            :         F2FS_IPU_ASYNC,
     636                 :            : };
     637                 :            : 
     638                 :            : static inline unsigned int curseg_segno(struct f2fs_sb_info *sbi,
     639                 :            :                 int type)
     640                 :            : {
     641                 :            :         struct curseg_info *curseg = CURSEG_I(sbi, type);
     642                 :          0 :         return curseg->segno;
     643                 :            : }
     644                 :            : 
     645                 :            : static inline unsigned char curseg_alloc_type(struct f2fs_sb_info *sbi,
     646                 :            :                 int type)
     647                 :            : {
     648                 :            :         struct curseg_info *curseg = CURSEG_I(sbi, type);
     649                 :          0 :         return curseg->alloc_type;
     650                 :            : }
     651                 :            : 
     652                 :            : static inline unsigned short curseg_blkoff(struct f2fs_sb_info *sbi, int type)
     653                 :            : {
     654                 :            :         struct curseg_info *curseg = CURSEG_I(sbi, type);
     655                 :          0 :         return curseg->next_blkoff;
     656                 :            : }
     657                 :            : 
     658                 :          0 : static inline void check_seg_range(struct f2fs_sb_info *sbi, unsigned int segno)
     659                 :            : {
     660                 :          0 :         f2fs_bug_on(sbi, segno > TOTAL_SEGS(sbi) - 1);
     661                 :          0 : }
     662                 :            : 
     663                 :          0 : static inline void verify_fio_blkaddr(struct f2fs_io_info *fio)
     664                 :            : {
     665                 :          0 :         struct f2fs_sb_info *sbi = fio->sbi;
     666                 :            : 
     667                 :          0 :         if (__is_valid_data_blkaddr(fio->old_blkaddr))
     668                 :          0 :                 verify_blkaddr(sbi, fio->old_blkaddr, __is_meta_io(fio) ?
     669                 :            :                                         META_GENERIC : DATA_GENERIC);
     670                 :          0 :         verify_blkaddr(sbi, fio->new_blkaddr, __is_meta_io(fio) ?
     671                 :            :                                         META_GENERIC : DATA_GENERIC_ENHANCE);
     672                 :          0 : }
     673                 :            : 
     674                 :            : /*
     675                 :            :  * Summary block is always treated as an invalid block
     676                 :            :  */
     677                 :          0 : static inline int check_block_count(struct f2fs_sb_info *sbi,
     678                 :            :                 int segno, struct f2fs_sit_entry *raw_sit)
     679                 :            : {
     680                 :          0 :         bool is_valid  = test_bit_le(0, raw_sit->valid_map) ? true : false;
     681                 :            :         int valid_blocks = 0;
     682                 :            :         int cur_pos = 0, next_pos;
     683                 :            : 
     684                 :            :         /* check bitmap with valid block count */
     685                 :            :         do {
     686                 :          0 :                 if (is_valid) {
     687                 :          0 :                         next_pos = find_next_zero_bit_le(&raw_sit->valid_map,
     688                 :          0 :                                         sbi->blocks_per_seg,
     689                 :            :                                         cur_pos);
     690                 :          0 :                         valid_blocks += next_pos - cur_pos;
     691                 :            :                 } else
     692                 :          0 :                         next_pos = find_next_bit_le(&raw_sit->valid_map,
     693                 :          0 :                                         sbi->blocks_per_seg,
     694                 :            :                                         cur_pos);
     695                 :            :                 cur_pos = next_pos;
     696                 :          0 :                 is_valid = !is_valid;
     697                 :          0 :         } while (cur_pos < sbi->blocks_per_seg);
     698                 :            : 
     699                 :          0 :         if (unlikely(GET_SIT_VBLOCKS(raw_sit) != valid_blocks)) {
     700                 :          0 :                 f2fs_err(sbi, "Mismatch valid blocks %d vs. %d",
     701                 :            :                          GET_SIT_VBLOCKS(raw_sit), valid_blocks);
     702                 :            :                 set_sbi_flag(sbi, SBI_NEED_FSCK);
     703                 :          0 :                 return -EFSCORRUPTED;
     704                 :            :         }
     705                 :            : 
     706                 :            :         /* check segment usage, and check boundary of a given segment number */
     707                 :          0 :         if (unlikely(GET_SIT_VBLOCKS(raw_sit) > sbi->blocks_per_seg
     708                 :            :                                         || segno > TOTAL_SEGS(sbi) - 1)) {
     709                 :          0 :                 f2fs_err(sbi, "Wrong valid blocks %d or segno %u",
     710                 :            :                          GET_SIT_VBLOCKS(raw_sit), segno);
     711                 :            :                 set_sbi_flag(sbi, SBI_NEED_FSCK);
     712                 :          0 :                 return -EFSCORRUPTED;
     713                 :            :         }
     714                 :            :         return 0;
     715                 :            : }
     716                 :            : 
     717                 :          0 : static inline pgoff_t current_sit_addr(struct f2fs_sb_info *sbi,
     718                 :            :                                                 unsigned int start)
     719                 :            : {
     720                 :            :         struct sit_info *sit_i = SIT_I(sbi);
     721                 :          0 :         unsigned int offset = SIT_BLOCK_OFFSET(start);
     722                 :          0 :         block_t blk_addr = sit_i->sit_base_addr + offset;
     723                 :            : 
     724                 :          0 :         check_seg_range(sbi, start);
     725                 :            : 
     726                 :            : #ifdef CONFIG_F2FS_CHECK_FS
     727                 :            :         if (f2fs_test_bit(offset, sit_i->sit_bitmap) !=
     728                 :            :                         f2fs_test_bit(offset, sit_i->sit_bitmap_mir))
     729                 :            :                 f2fs_bug_on(sbi, 1);
     730                 :            : #endif
     731                 :            : 
     732                 :            :         /* calculate sit block address */
     733                 :          0 :         if (f2fs_test_bit(offset, sit_i->sit_bitmap))
     734                 :          0 :                 blk_addr += sit_i->sit_blocks;
     735                 :            : 
     736                 :          0 :         return blk_addr;
     737                 :            : }
     738                 :            : 
     739                 :            : static inline pgoff_t next_sit_addr(struct f2fs_sb_info *sbi,
     740                 :            :                                                 pgoff_t block_addr)
     741                 :            : {
     742                 :            :         struct sit_info *sit_i = SIT_I(sbi);
     743                 :          0 :         block_addr -= sit_i->sit_base_addr;
     744                 :          0 :         if (block_addr < sit_i->sit_blocks)
     745                 :          0 :                 block_addr += sit_i->sit_blocks;
     746                 :            :         else
     747                 :          0 :                 block_addr -= sit_i->sit_blocks;
     748                 :            : 
     749                 :          0 :         return block_addr + sit_i->sit_base_addr;
     750                 :            : }
     751                 :            : 
     752                 :            : static inline void set_to_next_sit(struct sit_info *sit_i, unsigned int start)
     753                 :            : {
     754                 :          0 :         unsigned int block_off = SIT_BLOCK_OFFSET(start);
     755                 :            : 
     756                 :          0 :         f2fs_change_bit(block_off, sit_i->sit_bitmap);
     757                 :            : #ifdef CONFIG_F2FS_CHECK_FS
     758                 :            :         f2fs_change_bit(block_off, sit_i->sit_bitmap_mir);
     759                 :            : #endif
     760                 :            : }
     761                 :            : 
     762                 :          0 : static inline unsigned long long get_mtime(struct f2fs_sb_info *sbi,
     763                 :            :                                                 bool base_time)
     764                 :            : {
     765                 :            :         struct sit_info *sit_i = SIT_I(sbi);
     766                 :          0 :         time64_t diff, now = ktime_get_real_seconds();
     767                 :            : 
     768                 :          0 :         if (now >= sit_i->mounted_time)
     769                 :          0 :                 return sit_i->elapsed_time + now - sit_i->mounted_time;
     770                 :            : 
     771                 :            :         /* system time is set to the past */
     772                 :          0 :         if (!base_time) {
     773                 :          0 :                 diff = sit_i->mounted_time - now;
     774                 :          0 :                 if (sit_i->elapsed_time >= diff)
     775                 :          0 :                         return sit_i->elapsed_time - diff;
     776                 :            :                 return 0;
     777                 :            :         }
     778                 :          0 :         return sit_i->elapsed_time;
     779                 :            : }
     780                 :            : 
     781                 :            : static inline void set_summary(struct f2fs_summary *sum, nid_t nid,
     782                 :            :                         unsigned int ofs_in_node, unsigned char version)
     783                 :            : {
     784                 :          0 :         sum->nid = cpu_to_le32(nid);
     785                 :          0 :         sum->ofs_in_node = cpu_to_le16(ofs_in_node);
     786                 :          0 :         sum->version = version;
     787                 :            : }
     788                 :            : 
     789                 :            : static inline block_t start_sum_block(struct f2fs_sb_info *sbi)
     790                 :            : {
     791                 :          0 :         return __start_cp_addr(sbi) +
     792                 :          0 :                 le32_to_cpu(F2FS_CKPT(sbi)->cp_pack_start_sum);
     793                 :            : }
     794                 :            : 
     795                 :            : static inline block_t sum_blk_addr(struct f2fs_sb_info *sbi, int base, int type)
     796                 :            : {
     797                 :          0 :         return __start_cp_addr(sbi) +
     798                 :          0 :                 le32_to_cpu(F2FS_CKPT(sbi)->cp_pack_total_block_count)
     799                 :          0 :                                 - (base + 1) + type;
     800                 :            : }
     801                 :            : 
     802                 :          0 : static inline bool sec_usage_check(struct f2fs_sb_info *sbi, unsigned int secno)
     803                 :            : {
     804                 :          0 :         if (IS_CURSEC(sbi, secno) || (sbi->cur_victim_sec == secno))
     805                 :            :                 return true;
     806                 :          0 :         return false;
     807                 :            : }
     808                 :            : 
     809                 :            : /*
     810                 :            :  * It is very important to gather dirty pages and write at once, so that we can
     811                 :            :  * submit a big bio without interfering other data writes.
     812                 :            :  * By default, 512 pages for directory data,
     813                 :            :  * 512 pages (2MB) * 8 for nodes, and
     814                 :            :  * 256 pages * 8 for meta are set.
     815                 :            :  */
     816                 :            : static inline int nr_pages_to_skip(struct f2fs_sb_info *sbi, int type)
     817                 :            : {
     818                 :          0 :         if (sbi->sb->s_bdi->wb.dirty_exceeded)
     819                 :            :                 return 0;
     820                 :            : 
     821                 :            :         if (type == DATA)
     822                 :          0 :                 return sbi->blocks_per_seg;
     823                 :            :         else if (type == NODE)
     824                 :          0 :                 return 8 * sbi->blocks_per_seg;
     825                 :            :         else if (type == META)
     826                 :            :                 return 8 * BIO_MAX_PAGES;
     827                 :            :         else
     828                 :            :                 return 0;
     829                 :            : }
     830                 :            : 
     831                 :            : /*
     832                 :            :  * When writing pages, it'd better align nr_to_write for segment size.
     833                 :            :  */
     834                 :            : static inline long nr_pages_to_write(struct f2fs_sb_info *sbi, int type,
     835                 :            :                                         struct writeback_control *wbc)
     836                 :            : {
     837                 :            :         long nr_to_write, desired;
     838                 :            : 
     839                 :          0 :         if (wbc->sync_mode != WB_SYNC_NONE)
     840                 :            :                 return 0;
     841                 :            : 
     842                 :          0 :         nr_to_write = wbc->nr_to_write;
     843                 :            :         desired = BIO_MAX_PAGES;
     844                 :            :         if (type == NODE)
     845                 :            :                 desired <<= 1;
     846                 :            : 
     847                 :          0 :         wbc->nr_to_write = desired;
     848                 :          0 :         return desired - nr_to_write;
     849                 :            : }
     850                 :            : 
     851                 :          0 : static inline void wake_up_discard_thread(struct f2fs_sb_info *sbi, bool force)
     852                 :            : {
     853                 :          0 :         struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info;
     854                 :            :         bool wakeup = false;
     855                 :            :         int i;
     856                 :            : 
     857                 :          0 :         if (force)
     858                 :            :                 goto wake_up;
     859                 :            : 
     860                 :          0 :         mutex_lock(&dcc->cmd_lock);
     861                 :          0 :         for (i = MAX_PLIST_NUM - 1; i >= 0; i--) {
     862                 :          0 :                 if (i + 1 < dcc->discard_granularity)
     863                 :            :                         break;
     864                 :          0 :                 if (!list_empty(&dcc->pend_list[i])) {
     865                 :            :                         wakeup = true;
     866                 :            :                         break;
     867                 :            :                 }
     868                 :            :         }
     869                 :          0 :         mutex_unlock(&dcc->cmd_lock);
     870                 :          0 :         if (!wakeup || !is_idle(sbi, DISCARD_TIME))
     871                 :          0 :                 return;
     872                 :            : wake_up:
     873                 :          0 :         dcc->discard_wake = 1;
     874                 :          0 :         wake_up_interruptible_all(&dcc->discard_wait_queue);
     875                 :            : }
    

Generated by: LCOV version 1.14