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

f2fs: support recording stop_checkpoint reason into super_block



This patch supports to record stop_checkpoint error into
f2fs_super_block.s_stop_reason[].

Signed-off-by: default avatarChao Yu <chao@kernel.org>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent ca7efd71
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -26,12 +26,16 @@
static struct kmem_cache *ino_entry_slab;
struct kmem_cache *f2fs_inode_entry_slab;

void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io)
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io,
						unsigned char reason)
{
	f2fs_build_fault_attr(sbi, 0, 0);
	set_ckpt_flags(sbi, CP_ERROR_FLAG);
	if (!end_io)
	if (!end_io) {
		f2fs_flush_merged_writes(sbi);

		f2fs_handle_stop(sbi, reason);
	}
}

/*
@@ -122,7 +126,7 @@ struct page *f2fs_get_meta_page_retry(struct f2fs_sb_info *sbi, pgoff_t index)
		if (PTR_ERR(page) == -EIO &&
				++count <= DEFAULT_RETRY_IO_COUNT)
			goto retry;
		f2fs_stop_checkpoint(sbi, false);
		f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_META_PAGE);
	}
	return page;
}
+4 −2
Original line number Diff line number Diff line
@@ -333,7 +333,8 @@ static void f2fs_write_end_io(struct bio *bio)
			mempool_free(page, sbi->write_io_dummy);

			if (unlikely(bio->bi_status))
				f2fs_stop_checkpoint(sbi, true);
				f2fs_stop_checkpoint(sbi, true,
						STOP_CP_REASON_WRITE_FAIL);
			continue;
		}

@@ -349,7 +350,8 @@ static void f2fs_write_end_io(struct bio *bio)
		if (unlikely(bio->bi_status)) {
			mapping_set_error(page->mapping, -EIO);
			if (type == F2FS_WB_CP_DATA)
				f2fs_stop_checkpoint(sbi, true);
				f2fs_stop_checkpoint(sbi, true,
						STOP_CP_REASON_WRITE_FAIL);
		}

		f2fs_bug_on(sbi, page->mapping == NODE_MAPPING(sbi) &&
+3 −1
Original line number Diff line number Diff line
@@ -3556,6 +3556,7 @@ int f2fs_enable_quota_files(struct f2fs_sb_info *sbi, bool rdonly);
int f2fs_quota_sync(struct super_block *sb, int type);
loff_t max_file_blocks(struct inode *inode);
void f2fs_quota_off_umount(struct super_block *sb);
void f2fs_handle_stop(struct f2fs_sb_info *sbi, unsigned char reason);
int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover);
int f2fs_sync_fs(struct super_block *sb, int sync);
int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi);
@@ -3715,7 +3716,8 @@ static inline bool f2fs_need_rand_seg(struct f2fs_sb_info *sbi)
/*
 * checkpoint.c
 */
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io);
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io,
							unsigned char reason);
void f2fs_flush_ckpt_thread(struct f2fs_sb_info *sbi);
struct page *f2fs_grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
struct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
+6 −5
Original line number Diff line number Diff line
@@ -2145,7 +2145,8 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
		if (ret) {
			if (ret == -EROFS) {
				ret = 0;
				f2fs_stop_checkpoint(sbi, false);
				f2fs_stop_checkpoint(sbi, false,
						STOP_CP_REASON_SHUTDOWN);
				set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
				trace_f2fs_shutdown(sbi, in, ret);
			}
@@ -2158,7 +2159,7 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
		ret = freeze_bdev(sb->s_bdev);
		if (ret)
			goto out;
		f2fs_stop_checkpoint(sbi, false);
		f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
		set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
		thaw_bdev(sb->s_bdev);
		break;
@@ -2167,16 +2168,16 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
		ret = f2fs_sync_fs(sb, 1);
		if (ret)
			goto out;
		f2fs_stop_checkpoint(sbi, false);
		f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
		set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
		break;
	case F2FS_GOING_DOWN_NOSYNC:
		f2fs_stop_checkpoint(sbi, false);
		f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
		set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
		break;
	case F2FS_GOING_DOWN_METAFLUSH:
		f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_META_IO);
		f2fs_stop_checkpoint(sbi, false);
		f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
		set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
		break;
	case F2FS_GOING_DOWN_NEED_FSCK:
+4 −2
Original line number Diff line number Diff line
@@ -74,7 +74,8 @@ static int gc_thread_func(void *data)

		if (time_to_inject(sbi, FAULT_CHECKPOINT)) {
			f2fs_show_injection_info(sbi, FAULT_CHECKPOINT);
			f2fs_stop_checkpoint(sbi, false);
			f2fs_stop_checkpoint(sbi, false,
					STOP_CP_REASON_FAULT_INJECT);
		}

		if (!sb_start_write_trylock(sbi->sb)) {
@@ -1712,7 +1713,8 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
			f2fs_err(sbi, "Inconsistent segment (%u) type [%d, %d] in SSA and SIT",
				 segno, type, GET_SUM_TYPE((&sum->footer)));
			set_sbi_flag(sbi, SBI_NEED_FSCK);
			f2fs_stop_checkpoint(sbi, false);
			f2fs_stop_checkpoint(sbi, false,
				STOP_CP_REASON_CORRUPTED_SUMMARY);
			goto skip;
		}

Loading