Skip to content

Commit a9cfee0

Browse files
chaseyuJaegeuk Kim
authored andcommitted
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: Chao Yu <chao@kernel.org> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
1 parent ca7efd7 commit a9cfee0

File tree

9 files changed

+65
-17
lines changed

9 files changed

+65
-17
lines changed

fs/f2fs/checkpoint.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,16 @@
2626
static struct kmem_cache *ino_entry_slab;
2727
struct kmem_cache *f2fs_inode_entry_slab;
2828

29-
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io)
29+
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io,
30+
unsigned char reason)
3031
{
3132
f2fs_build_fault_attr(sbi, 0, 0);
3233
set_ckpt_flags(sbi, CP_ERROR_FLAG);
33-
if (!end_io)
34+
if (!end_io) {
3435
f2fs_flush_merged_writes(sbi);
36+
37+
f2fs_handle_stop(sbi, reason);
38+
}
3539
}
3640

3741
/*
@@ -122,7 +126,7 @@ struct page *f2fs_get_meta_page_retry(struct f2fs_sb_info *sbi, pgoff_t index)
122126
if (PTR_ERR(page) == -EIO &&
123127
++count <= DEFAULT_RETRY_IO_COUNT)
124128
goto retry;
125-
f2fs_stop_checkpoint(sbi, false);
129+
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_META_PAGE);
126130
}
127131
return page;
128132
}

fs/f2fs/data.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,8 @@ static void f2fs_write_end_io(struct bio *bio)
333333
mempool_free(page, sbi->write_io_dummy);
334334

335335
if (unlikely(bio->bi_status))
336-
f2fs_stop_checkpoint(sbi, true);
336+
f2fs_stop_checkpoint(sbi, true,
337+
STOP_CP_REASON_WRITE_FAIL);
337338
continue;
338339
}
339340

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

355357
f2fs_bug_on(sbi, page->mapping == NODE_MAPPING(sbi) &&

fs/f2fs/f2fs.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3556,6 +3556,7 @@ int f2fs_enable_quota_files(struct f2fs_sb_info *sbi, bool rdonly);
35563556
int f2fs_quota_sync(struct super_block *sb, int type);
35573557
loff_t max_file_blocks(struct inode *inode);
35583558
void f2fs_quota_off_umount(struct super_block *sb);
3559+
void f2fs_handle_stop(struct f2fs_sb_info *sbi, unsigned char reason);
35593560
int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover);
35603561
int f2fs_sync_fs(struct super_block *sb, int sync);
35613562
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)
37153716
/*
37163717
* checkpoint.c
37173718
*/
3718-
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io);
3719+
void f2fs_stop_checkpoint(struct f2fs_sb_info *sbi, bool end_io,
3720+
unsigned char reason);
37193721
void f2fs_flush_ckpt_thread(struct f2fs_sb_info *sbi);
37203722
struct page *f2fs_grab_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);
37213723
struct page *f2fs_get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index);

fs/f2fs/file.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2145,7 +2145,8 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
21452145
if (ret) {
21462146
if (ret == -EROFS) {
21472147
ret = 0;
2148-
f2fs_stop_checkpoint(sbi, false);
2148+
f2fs_stop_checkpoint(sbi, false,
2149+
STOP_CP_REASON_SHUTDOWN);
21492150
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
21502151
trace_f2fs_shutdown(sbi, in, ret);
21512152
}
@@ -2158,7 +2159,7 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
21582159
ret = freeze_bdev(sb->s_bdev);
21592160
if (ret)
21602161
goto out;
2161-
f2fs_stop_checkpoint(sbi, false);
2162+
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
21622163
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
21632164
thaw_bdev(sb->s_bdev);
21642165
break;
@@ -2167,16 +2168,16 @@ static int f2fs_ioc_shutdown(struct file *filp, unsigned long arg)
21672168
ret = f2fs_sync_fs(sb, 1);
21682169
if (ret)
21692170
goto out;
2170-
f2fs_stop_checkpoint(sbi, false);
2171+
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
21712172
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
21722173
break;
21732174
case F2FS_GOING_DOWN_NOSYNC:
2174-
f2fs_stop_checkpoint(sbi, false);
2175+
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
21752176
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
21762177
break;
21772178
case F2FS_GOING_DOWN_METAFLUSH:
21782179
f2fs_sync_meta_pages(sbi, META, LONG_MAX, FS_META_IO);
2179-
f2fs_stop_checkpoint(sbi, false);
2180+
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_SHUTDOWN);
21802181
set_sbi_flag(sbi, SBI_IS_SHUTDOWN);
21812182
break;
21822183
case F2FS_GOING_DOWN_NEED_FSCK:

fs/f2fs/gc.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ static int gc_thread_func(void *data)
7474

7575
if (time_to_inject(sbi, FAULT_CHECKPOINT)) {
7676
f2fs_show_injection_info(sbi, FAULT_CHECKPOINT);
77-
f2fs_stop_checkpoint(sbi, false);
77+
f2fs_stop_checkpoint(sbi, false,
78+
STOP_CP_REASON_FAULT_INJECT);
7879
}
7980

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

fs/f2fs/inode.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,8 @@ void f2fs_update_inode_page(struct inode *inode)
713713
cond_resched();
714714
goto retry;
715715
} else if (err != -ENOENT) {
716-
f2fs_stop_checkpoint(sbi, false);
716+
f2fs_stop_checkpoint(sbi, false,
717+
STOP_CP_REASON_UPDATE_INODE);
717718
}
718719
return;
719720
}

fs/f2fs/segment.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi, bool need)
376376
{
377377
if (time_to_inject(sbi, FAULT_CHECKPOINT)) {
378378
f2fs_show_injection_info(sbi, FAULT_CHECKPOINT);
379-
f2fs_stop_checkpoint(sbi, false);
379+
f2fs_stop_checkpoint(sbi, false, STOP_CP_REASON_FAULT_INJECT);
380380
}
381381

382382
/* balance_fs_bg is able to be pending */
@@ -694,7 +694,8 @@ int f2fs_flush_device_cache(struct f2fs_sb_info *sbi)
694694
} while (ret && --count);
695695

696696
if (ret) {
697-
f2fs_stop_checkpoint(sbi, false);
697+
f2fs_stop_checkpoint(sbi, false,
698+
STOP_CP_REASON_FLUSH_FAIL);
698699
break;
699700
}
700701

fs/f2fs/super.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3846,6 +3846,26 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover)
38463846
return err;
38473847
}
38483848

3849+
void f2fs_handle_stop(struct f2fs_sb_info *sbi, unsigned char reason)
3850+
{
3851+
struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
3852+
int err;
3853+
3854+
f2fs_bug_on(sbi, reason >= MAX_STOP_REASON);
3855+
3856+
f2fs_down_write(&sbi->sb_lock);
3857+
3858+
if (raw_super->s_stop_reason[reason] < ((1 << BITS_PER_BYTE) - 1))
3859+
raw_super->s_stop_reason[reason]++;
3860+
3861+
err = f2fs_commit_super(sbi, false);
3862+
if (err)
3863+
f2fs_err(sbi, "f2fs_commit_super fails to record reason:%u err:%d",
3864+
reason, err);
3865+
3866+
f2fs_up_write(&sbi->sb_lock);
3867+
}
3868+
38493869
static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
38503870
{
38513871
struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);

include/linux/f2fs_fs.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,20 @@ struct f2fs_device {
7373
__le32 total_segments;
7474
} __packed;
7575

76+
/* reason of stop_checkpoint */
77+
enum stop_cp_reason {
78+
STOP_CP_REASON_SHUTDOWN,
79+
STOP_CP_REASON_FAULT_INJECT,
80+
STOP_CP_REASON_META_PAGE,
81+
STOP_CP_REASON_WRITE_FAIL,
82+
STOP_CP_REASON_CORRUPTED_SUMMARY,
83+
STOP_CP_REASON_UPDATE_INODE,
84+
STOP_CP_REASON_FLUSH_FAIL,
85+
STOP_CP_REASON_MAX,
86+
};
87+
88+
#define MAX_STOP_REASON 32
89+
7690
struct f2fs_super_block {
7791
__le32 magic; /* Magic Number */
7892
__le16 major_ver; /* Major Version */
@@ -116,7 +130,8 @@ struct f2fs_super_block {
116130
__u8 hot_ext_count; /* # of hot file extension */
117131
__le16 s_encoding; /* Filename charset encoding */
118132
__le16 s_encoding_flags; /* Filename charset encoding flags */
119-
__u8 reserved[306]; /* valid reserved region */
133+
__u8 s_stop_reason[MAX_STOP_REASON]; /* stop checkpoint reason */
134+
__u8 reserved[274]; /* valid reserved region */
120135
__le32 crc; /* checksum of superblock */
121136
} __packed;
122137

0 commit comments

Comments
 (0)