Commit 4bc34777 authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim
Browse files

f2fs: add timeout in f2fs_enable_checkpoint()



During f2fs_enable_checkpoint() in remount(), if we flush a large
amount of dirty pages into slow device, it may take long time which
will block write IO, let's add a timeout machanism during dirty
pages flush to avoid long time block in f2fs_enable_checkpoint().

Signed-off-by: default avatarChao Yu <chao@kernel.org>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 8fc6056d
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -267,6 +267,7 @@ enum {
#define DEF_CP_INTERVAL			60	/* 60 secs */
#define DEF_IDLE_INTERVAL		5	/* 5 secs */
#define DEF_DISABLE_INTERVAL		5	/* 5 secs */
#define DEF_ENABLE_INTERVAL		16	/* 16 secs */
#define DEF_DISABLE_QUICK_INTERVAL	1	/* 1 secs */
#define DEF_UMOUNT_DISCARD_TIMEOUT	5	/* 5 secs */

@@ -1397,6 +1398,7 @@ enum {
	DISCARD_TIME,
	GC_TIME,
	DISABLE_TIME,
	ENABLE_TIME,
	UMOUNT_DISCARD_TIMEOUT,
	MAX_TIME,
};
+15 −6
Original line number Diff line number Diff line
@@ -2594,16 +2594,24 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi)

static void f2fs_enable_checkpoint(struct f2fs_sb_info *sbi)
{
	int retry = DEFAULT_RETRY_IO_COUNT;
	unsigned int nr_pages = get_pages(sbi, F2FS_DIRTY_DATA) / 16;

	f2fs_update_time(sbi, ENABLE_TIME);

	/* we should flush all the data to keep data consistency */
	do {
		sync_inodes_sb(sbi->sb);
	while (get_pages(sbi, F2FS_DIRTY_DATA)) {
		writeback_inodes_sb_nr(sbi->sb, nr_pages, WB_REASON_SYNC);
		f2fs_io_schedule_timeout(DEFAULT_IO_TIMEOUT);
	} while (get_pages(sbi, F2FS_DIRTY_DATA) && retry--);

	if (unlikely(retry < 0))
		f2fs_warn(sbi, "checkpoint=enable has some unwritten data.");
		if (f2fs_time_over(sbi, ENABLE_TIME))
			break;
	}

	sync_inodes_sb(sbi->sb);

	if (unlikely(get_pages(sbi, F2FS_DIRTY_DATA)))
		f2fs_warn(sbi, "checkpoint=enable has some unwritten data: %lld",
					get_pages(sbi, F2FS_DIRTY_DATA));

	f2fs_down_write(&sbi->gc_lock);
	f2fs_dirty_to_prefree(sbi);
@@ -4200,6 +4208,7 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
	sbi->interval_time[DISCARD_TIME] = DEF_IDLE_INTERVAL;
	sbi->interval_time[GC_TIME] = DEF_IDLE_INTERVAL;
	sbi->interval_time[DISABLE_TIME] = DEF_DISABLE_INTERVAL;
	sbi->interval_time[ENABLE_TIME] = DEF_ENABLE_INTERVAL;
	sbi->interval_time[UMOUNT_DISCARD_TIMEOUT] =
				DEF_UMOUNT_DISCARD_TIMEOUT;
	clear_sbi_flag(sbi, SBI_NEED_FSCK);