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

f2fs: fix potential overflow when adjusting GC cycle

While comparing signed and unsigned variables, compiler will converts the
signed value to unsigned one, due to this reason, {in,de}crease_sleep_time
may return overflowed result.
Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 9a20d391
...@@ -28,7 +28,7 @@ static int gc_thread_func(void *data) ...@@ -28,7 +28,7 @@ static int gc_thread_func(void *data)
struct f2fs_sb_info *sbi = data; struct f2fs_sb_info *sbi = data;
struct f2fs_gc_kthread *gc_th = sbi->gc_thread; struct f2fs_gc_kthread *gc_th = sbi->gc_thread;
wait_queue_head_t *wq = &sbi->gc_thread->gc_wait_queue_head; wait_queue_head_t *wq = &sbi->gc_thread->gc_wait_queue_head;
long wait_ms; unsigned int wait_ms;
wait_ms = gc_th->min_sleep_time; wait_ms = gc_th->min_sleep_time;
......
...@@ -69,25 +69,32 @@ static inline block_t limit_free_user_blocks(struct f2fs_sb_info *sbi) ...@@ -69,25 +69,32 @@ static inline block_t limit_free_user_blocks(struct f2fs_sb_info *sbi)
} }
static inline void increase_sleep_time(struct f2fs_gc_kthread *gc_th, static inline void increase_sleep_time(struct f2fs_gc_kthread *gc_th,
long *wait) unsigned int *wait)
{ {
unsigned int min_time = gc_th->min_sleep_time;
unsigned int max_time = gc_th->max_sleep_time;
if (*wait == gc_th->no_gc_sleep_time) if (*wait == gc_th->no_gc_sleep_time)
return; return;
*wait += gc_th->min_sleep_time; if ((long long)*wait + (long long)min_time > (long long)max_time)
if (*wait > gc_th->max_sleep_time) *wait = max_time;
*wait = gc_th->max_sleep_time; else
*wait += min_time;
} }
static inline void decrease_sleep_time(struct f2fs_gc_kthread *gc_th, static inline void decrease_sleep_time(struct f2fs_gc_kthread *gc_th,
long *wait) unsigned int *wait)
{ {
unsigned int min_time = gc_th->min_sleep_time;
if (*wait == gc_th->no_gc_sleep_time) if (*wait == gc_th->no_gc_sleep_time)
*wait = gc_th->max_sleep_time; *wait = gc_th->max_sleep_time;
*wait -= gc_th->min_sleep_time; if ((long long)*wait - (long long)min_time < (long long)min_time)
if (*wait <= gc_th->min_sleep_time) *wait = min_time;
*wait = gc_th->min_sleep_time; else
*wait -= min_time;
} }
static inline bool has_enough_invalid_blocks(struct f2fs_sb_info *sbi) static inline bool has_enough_invalid_blocks(struct f2fs_sb_info *sbi)
......
...@@ -543,14 +543,14 @@ TRACE_EVENT(f2fs_map_blocks, ...@@ -543,14 +543,14 @@ TRACE_EVENT(f2fs_map_blocks,
TRACE_EVENT(f2fs_background_gc, TRACE_EVENT(f2fs_background_gc,
TP_PROTO(struct super_block *sb, long wait_ms, TP_PROTO(struct super_block *sb, unsigned int wait_ms,
unsigned int prefree, unsigned int free), unsigned int prefree, unsigned int free),
TP_ARGS(sb, wait_ms, prefree, free), TP_ARGS(sb, wait_ms, prefree, free),
TP_STRUCT__entry( TP_STRUCT__entry(
__field(dev_t, dev) __field(dev_t, dev)
__field(long, wait_ms) __field(unsigned int, wait_ms)
__field(unsigned int, prefree) __field(unsigned int, prefree)
__field(unsigned int, free) __field(unsigned int, free)
), ),
...@@ -562,7 +562,7 @@ TRACE_EVENT(f2fs_background_gc, ...@@ -562,7 +562,7 @@ TRACE_EVENT(f2fs_background_gc,
__entry->free = free; __entry->free = free;
), ),
TP_printk("dev = (%d,%d), wait_ms = %ld, prefree = %u, free = %u", TP_printk("dev = (%d,%d), wait_ms = %u, prefree = %u, free = %u",
show_dev(__entry->dev), show_dev(__entry->dev),
__entry->wait_ms, __entry->wait_ms,
__entry->prefree, __entry->prefree,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment