mirror of https://gitee.com/openkylin/linux.git
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: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
parent
9a20d391cd
commit
b8c502b81e
|
@ -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;
|
||||
|
||||
|
|
23
fs/f2fs/gc.h
23
fs/f2fs/gc.h
|
@ -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,
|
||||
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)
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue