f2fs: fix potential overflow when adjusting GC cycle
Subsystems (2)
Chao Yu
maintainerPATCH 1/1 f2fs: fix potential overflow when adjusting GC cycle
From: Chao Yu <[email protected]>
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 Chao Yu <[email protected]>
--- fs/f2fs/gc.c | 2 +- fs/f2fs/gc.h | 23 +++++++++++++++-------- include/trace/events/f2fs.h | 6 +++--- 3 files changed, 19 insertions(+), 12 deletions(-)
fs/f2fs/gc.c +1 -1
@@ -28,7 +28,7 @@ static int gc_thread_func(void *data)struct f2fs_sb_info *sbi = data;struct f2fs_gc_kthread *gc_th = sbi->gc_thread;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;
fs/f2fs/gc.h +15 -8
@@ -65,25 +65,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, -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)return ; - *wait += gc_th->min_sleep_time; -if (*wait > gc_th->max_sleep_time) - *wait = gc_th->max_sleep_time; +if ((long long )*wait + (long long )min_time > (long long )max_time) + *wait = max_time; +else + *wait += min_time; }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) *wait = gc_th->max_sleep_time; - *wait -= gc_th->min_sleep_time; -if (*wait <= gc_th->min_sleep_time) - *wait = gc_th->min_sleep_time; +if ((long long )*wait - (long long )min_time < (long long )min_time) + *wait = min_time; +else + *wait -= min_time; }static inline bool has_enough_invalid_blocks (struct f2fs_sb_info *sbi)
include/trace/events/f2fs.h +3 -3
@@ -543,14 +543,14 @@ TRACE_EVENT(f2fs_map_blocks, 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), TP_ARGS(sb, wait_ms, prefree, free), TP_STRUCT__entry( __field(dev_t, dev) - __field(long, wait_ms) + __field(unsigned int, wait_ms) __field(unsigned int, prefree) __field(unsigned int, free) ),
@@ -562,7 +562,7 @@ TRACE_EVENT(f2fs_background_gc, __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), __entry->wait_ms, __entry->prefree,
Signature · 1 line
2.14.0