linux/fs/f2fs/gc.h
<<
>>
Prefs
   1/*
   2 * fs/f2fs/gc.h
   3 *
   4 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
   5 *             http://www.samsung.com/
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 */
  11#define GC_THREAD_MIN_WB_PAGES          1       /*
  12                                                 * a threshold to determine
  13                                                 * whether IO subsystem is idle
  14                                                 * or not
  15                                                 */
  16#define DEF_GC_THREAD_URGENT_SLEEP_TIME 500     /* 500 ms */
  17#define DEF_GC_THREAD_MIN_SLEEP_TIME    30000   /* milliseconds */
  18#define DEF_GC_THREAD_MAX_SLEEP_TIME    60000
  19#define DEF_GC_THREAD_NOGC_SLEEP_TIME   300000  /* wait 5 min */
  20#define LIMIT_INVALID_BLOCK     40 /* percentage over total user space */
  21#define LIMIT_FREE_BLOCK        40 /* percentage over invalid + free space */
  22
  23#define DEF_GC_FAILED_PINNED_FILES      2048
  24
  25/* Search max. number of dirty segments to select a victim segment */
  26#define DEF_MAX_VICTIM_SEARCH 4096 /* covers 8GB */
  27
  28struct f2fs_gc_kthread {
  29        struct task_struct *f2fs_gc_task;
  30        wait_queue_head_t gc_wait_queue_head;
  31
  32        /* for gc sleep time */
  33        unsigned int urgent_sleep_time;
  34        unsigned int min_sleep_time;
  35        unsigned int max_sleep_time;
  36        unsigned int no_gc_sleep_time;
  37
  38        /* for changing gc mode */
  39        unsigned int gc_wake;
  40};
  41
  42struct gc_inode_list {
  43        struct list_head ilist;
  44        struct radix_tree_root iroot;
  45};
  46
  47/*
  48 * inline functions
  49 */
  50static inline block_t free_user_blocks(struct f2fs_sb_info *sbi)
  51{
  52        if (free_segments(sbi) < overprovision_segments(sbi))
  53                return 0;
  54        else
  55                return (free_segments(sbi) - overprovision_segments(sbi))
  56                        << sbi->log_blocks_per_seg;
  57}
  58
  59static inline block_t limit_invalid_user_blocks(struct f2fs_sb_info *sbi)
  60{
  61        return (long)(sbi->user_block_count * LIMIT_INVALID_BLOCK) / 100;
  62}
  63
  64static inline block_t limit_free_user_blocks(struct f2fs_sb_info *sbi)
  65{
  66        block_t reclaimable_user_blocks = sbi->user_block_count -
  67                written_block_count(sbi);
  68        return (long)(reclaimable_user_blocks * LIMIT_FREE_BLOCK) / 100;
  69}
  70
  71static inline void increase_sleep_time(struct f2fs_gc_kthread *gc_th,
  72                                                        unsigned int *wait)
  73{
  74        unsigned int min_time = gc_th->min_sleep_time;
  75        unsigned int max_time = gc_th->max_sleep_time;
  76
  77        if (*wait == gc_th->no_gc_sleep_time)
  78                return;
  79
  80        if ((long long)*wait + (long long)min_time > (long long)max_time)
  81                *wait = max_time;
  82        else
  83                *wait += min_time;
  84}
  85
  86static inline void decrease_sleep_time(struct f2fs_gc_kthread *gc_th,
  87                                                        unsigned int *wait)
  88{
  89        unsigned int min_time = gc_th->min_sleep_time;
  90
  91        if (*wait == gc_th->no_gc_sleep_time)
  92                *wait = gc_th->max_sleep_time;
  93
  94        if ((long long)*wait - (long long)min_time < (long long)min_time)
  95                *wait = min_time;
  96        else
  97                *wait -= min_time;
  98}
  99
 100static inline bool has_enough_invalid_blocks(struct f2fs_sb_info *sbi)
 101{
 102        block_t invalid_user_blocks = sbi->user_block_count -
 103                                        written_block_count(sbi);
 104        /*
 105         * Background GC is triggered with the following conditions.
 106         * 1. There are a number of invalid blocks.
 107         * 2. There is not enough free space.
 108         */
 109        if (invalid_user_blocks > limit_invalid_user_blocks(sbi) &&
 110                        free_user_blocks(sbi) < limit_free_user_blocks(sbi))
 111                return true;
 112        return false;
 113}
 114