diff options
author | Chao Yu <yuchao0@huawei.com> | 2020-08-07 10:02:31 +0800 |
---|---|---|
committer | Jaegeuk Kim <jaegeuk@kernel.org> | 2020-08-17 23:52:38 -0700 |
commit | 2579fe8099a8852e0793afdcc1131f1b30bebab4 (patch) | |
tree | 754e0f51c6196be04cdf30fff814dba340c15f90 | |
parent | 5c92399f8fc157740165845a43aa178037c97b2e (diff) | |
download | f2fs-tools-2579fe8099a8852e0793afdcc1131f1b30bebab4.tar.gz |
fsck.f2fs: correct return value
As Norbert Lange reported:
"
$ fsck.f2fs -a /dev/mmcblk0p5; echo $?
Info: Fix the reported corruption.
Info: Mounted device!
Info: Check FS only on RO mounted device
Error: Failed to open the device!
255
"
Michael Laß reminds:
"
I think the return value is exactly the problem here. See fsck(8) (
https://linux.die.net/man/8/fsck) which specifies the return values.
Systemd looks at these and decides how to proceed:
https://github.com/systemd/systemd/blob/a859abf062cef1511e4879c4ee39c6036ebeaec8/src/fsck/fsck.c#L407
That means, if fsck.f2fs returns 255, then
the FSCK_SYSTEM_SHOULD_REBOOT bit is set and systemd will reboot.
"
So the problem here is fsck.f2fs didn't return correct value to userspace
apps, result in later unexpected behavior of rebooting, let's fix this.
Reported-by: Norbert Lange <nolange79@gmail.com>
Reported-by: Michael Laß <bevan@bi-co.net>
Signed-off-by: Chao Yu <yuchao0@huawei.com>
[Jaegeuk Kim: fix FSCK_ERROR_CORRECTED]
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
-rw-r--r-- | fsck/fsck.c | 2 | ||||
-rw-r--r-- | fsck/fsck.h | 11 | ||||
-rw-r--r-- | fsck/main.c | 39 |
3 files changed, 40 insertions, 12 deletions
diff --git a/fsck/fsck.c b/fsck/fsck.c index e110f3d..0f627eb 100644 --- a/fsck/fsck.c +++ b/fsck/fsck.c @@ -3165,6 +3165,8 @@ int fsck_verify(struct f2fs_sb_info *sbi) is_set_ckpt_flags(cp, CP_QUOTA_NEED_FSCK_FLAG)) { write_checkpoints(sbi); } + /* to return FSCK_ERROR_CORRECTED */ + ret = 0; } return ret; } diff --git a/fsck/fsck.h b/fsck/fsck.h index bc6a435..d8bab97 100644 --- a/fsck/fsck.h +++ b/fsck/fsck.h @@ -13,6 +13,17 @@ #include "f2fs.h" +enum { + FSCK_SUCCESS = 0, + FSCK_ERROR_CORRECTED = 1 << 0, + FSCK_SYSTEM_SHOULD_REBOOT = 1 << 1, + FSCK_ERRORS_LEFT_UNCORRECTED = 1 << 2, + FSCK_OPERATIONAL_ERROR = 1 << 3, + FSCK_USAGE_OR_SYNTAX_ERROR = 1 << 4, + FSCK_USER_CANCELLED = 1 << 5, + FSCK_SHARED_LIB_ERROR = 1 << 7, +}; + struct quota_ctx; #define FSCK_UNMATCHED_EXTENT 0x00000001 diff --git a/fsck/main.c b/fsck/main.c index 9a1596f..32559f1 100644 --- a/fsck/main.c +++ b/fsck/main.c @@ -630,7 +630,7 @@ void f2fs_parse_options(int argc, char *argv[]) error_out(prog); } -static void do_fsck(struct f2fs_sb_info *sbi) +static int do_fsck(struct f2fs_sb_info *sbi) { struct f2fs_checkpoint *ckpt = F2FS_CKPT(sbi); u32 flag = le32_to_cpu(ckpt->ckpt_flags); @@ -655,7 +655,7 @@ static void do_fsck(struct f2fs_sb_info *sbi) } else { MSG(0, "[FSCK] F2FS metadata [Ok..]"); fsck_free(sbi); - return; + return FSCK_SUCCESS; } if (!c.ro) @@ -687,7 +687,7 @@ static void do_fsck(struct f2fs_sb_info *sbi) ret = quota_init_context(sbi); if (ret) { ASSERT_MSG("quota_init_context failure: %d", ret); - return; + return FSCK_OPERATIONAL_ERROR; } } fsck_chk_orphan_node(sbi); @@ -695,8 +695,14 @@ static void do_fsck(struct f2fs_sb_info *sbi) F2FS_FT_DIR, TYPE_INODE, &blk_cnt, NULL); fsck_chk_quota_files(sbi); - fsck_verify(sbi); + ret = fsck_verify(sbi); fsck_free(sbi); + + if (!c.bug_on) + return FSCK_SUCCESS; + if (!ret) + return FSCK_ERROR_CORRECTED; + return FSCK_ERRORS_LEFT_UNCORRECTED; } static void do_dump(struct f2fs_sb_info *sbi) @@ -823,7 +829,7 @@ static u64 get_boottime_ns() int main(int argc, char **argv) { struct f2fs_sb_info *sbi; - int ret = 0; + int ret = 0, ret2; u64 start = get_boottime_ns(); f2fs_init_configuration(); @@ -833,11 +839,15 @@ int main(int argc, char **argv) if (c.func != DUMP && f2fs_devs_are_umounted() < 0) { if (errno == EBUSY) { ret = -1; + if (c.func == FSCK) + ret = FSCK_OPERATIONAL_ERROR; goto quick_err; } if (!c.ro || c.func == DEFRAG) { MSG(0, "\tError: Not available on mounted device!\n"); ret = -1; + if (c.func == FSCK) + ret = FSCK_OPERATIONAL_ERROR; goto quick_err; } @@ -854,6 +864,8 @@ int main(int argc, char **argv) /* Get device */ if (f2fs_get_device_info() < 0) { ret = -1; + if (c.func == FSCK) + ret = FSCK_OPERATIONAL_ERROR; goto quick_err; } @@ -873,7 +885,7 @@ fsck_again: switch (c.func) { case FSCK: - do_fsck(sbi); + ret = do_fsck(sbi); break; #ifdef WITH_DUMP case DUMP: @@ -921,8 +933,8 @@ fsck_again: char ans[255] = {0}; retry: printf("Do you want to fix this partition? [Y/N] "); - ret = scanf("%s", ans); - ASSERT(ret >= 0); + ret2 = scanf("%s", ans); + ASSERT(ret2 >= 0); if (!strcasecmp(ans, "y")) c.fix_on = 1; else if (!strcasecmp(ans, "n")) @@ -934,12 +946,15 @@ retry: goto fsck_again; } } - ret = f2fs_finalize_device(); - if (ret < 0) - return ret; + ret2 = f2fs_finalize_device(); + if (ret2) { + if (c.func == FSCK) + return FSCK_OPERATIONAL_ERROR; + return ret2; + } printf("\nDone: %lf secs\n", (get_boottime_ns() - start) / 1000000000.0); - return 0; + return ret; out_err: if (sbi->ckpt) |