f2fs-tools: add periodic check in kernel version check

In previous, we did a full scan right after kernel version is changed
and it triggered many unnecessary full scan whenever a newly built
kernel is downloaded. Plus, we are lack of a periodic health check of
on-disk filesystem images. So, I added a monthly periodic check after
a new vesion is updated.

Signed-off-by: Daeho Jeong <daehojeong@google.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
Daeho Jeong 2021-07-16 14:57:03 -07:00 committed by Jaegeuk Kim
parent 1bc76585d5
commit 9ee091e819
3 changed files with 44 additions and 16 deletions

View File

@ -13,6 +13,7 @@
#include "xattr.h"
#include <locale.h>
#include <stdbool.h>
#include <time.h>
#ifdef HAVE_LINUX_POSIX_ACL_H
#include <linux/posix_acl.h>
#endif
@ -424,7 +425,7 @@ printout:
DISP_u32(sb, meta_ino);
DISP_u32(sb, cp_payload);
DISP_u32(sb, crc);
DISP("%-.256s", sb, version);
DISP("%-.252s", sb, version);
printf("\n");
}
@ -939,6 +940,8 @@ int sanity_check_raw_super(struct f2fs_super_block *sb, enum SB_ADDR sb_addr)
return 0;
}
#define CHECK_PERIOD (3600 * 24 * 30) // one month by default
int validate_super_block(struct f2fs_sb_info *sbi, enum SB_ADDR sb_addr)
{
char buf[F2FS_BLKSIZE];
@ -956,31 +959,54 @@ int validate_super_block(struct f2fs_sb_info *sbi, enum SB_ADDR sb_addr)
if (!sanity_check_raw_super(sbi->raw_super, sb_addr)) {
/* get kernel version */
if (c.kd >= 0) {
dev_read_version(c.version, 0, VERSION_LEN);
dev_read_version(c.version, 0, VERSION_NAME_LEN);
get_kernel_version(c.version);
} else {
get_kernel_uname_version(c.version);
}
/* build sb version */
memcpy(c.sb_version, sbi->raw_super->version, VERSION_LEN);
memcpy(c.sb_version, sbi->raw_super->version, VERSION_NAME_LEN);
get_kernel_version(c.sb_version);
memcpy(c.init_version, sbi->raw_super->init_version, VERSION_LEN);
memcpy(c.init_version, sbi->raw_super->init_version,
VERSION_NAME_LEN);
get_kernel_version(c.init_version);
MSG(0, "Info: MKFS version\n \"%s\"\n", c.init_version);
MSG(0, "Info: FSCK version\n from \"%s\"\n to \"%s\"\n",
c.sb_version, c.version);
if (!c.no_kernel_check &&
memcmp(c.sb_version, c.version, VERSION_LEN)) {
c.auto_fix = 0;
c.fix_on = 1;
}
if (c.fix_on) {
memcpy(sbi->raw_super->version,
c.version, VERSION_LEN);
if (!c.no_kernel_check) {
struct timespec t;
u32 prev_time, cur_time, time_diff;
__le32 *ver_ts_ptr = (__le32 *)(sbi->raw_super->version
+ VERSION_NAME_LEN);
t.tv_sec = t.tv_nsec = 0;
clock_gettime(CLOCK_REALTIME, &t);
cur_time = (u32)t.tv_sec;
prev_time = le32_to_cpu(*ver_ts_ptr);
MSG(0, "Info: version timestamp cur: %u, prev: %u\n",
cur_time, prev_time);
if (!memcmp(c.sb_version, c.version,
VERSION_NAME_LEN)) {
/* valid prev_time */
if (prev_time != 0 && cur_time > prev_time) {
time_diff = cur_time - prev_time;
if (time_diff < CHECK_PERIOD)
goto out;
c.auto_fix = 0;
c.fix_on = 1;
}
} else {
memcpy(sbi->raw_super->version,
c.version, VERSION_NAME_LEN);
}
*ver_ts_ptr = cpu_to_le32(cur_time);
update_superblock(sbi->raw_super, SB_MASK(sb_addr));
}
out:
print_sb_state(sbi->raw_super);
return 0;
}

View File

@ -350,7 +350,9 @@ static inline uint64_t bswap_64(uint64_t val)
#define DEFAULT_BLOCKS_PER_SEGMENT 512
#define DEFAULT_SEGMENTS_PER_SECTION 1
#define VERSION_LEN 256
#define VERSION_LEN 256
#define VERSION_TIMESTAMP_LEN 4
#define VERSION_NAME_LEN (VERSION_LEN - VERSION_TIMESTAMP_LEN)
#define LPF "lost+found"

View File

@ -828,7 +828,7 @@ int f2fs_devs_are_umounted(void)
void get_kernel_version(__u8 *version)
{
int i;
for (i = 0; i < VERSION_LEN; i++) {
for (i = 0; i < VERSION_NAME_LEN; i++) {
if (version[i] == '\n')
break;
}
@ -846,10 +846,10 @@ void get_kernel_uname_version(__u8 *version)
#if defined(WITH_KERNEL_VERSION)
snprintf((char *)version,
VERSION_LEN, "%s %s", buf.release, buf.version);
VERSION_NAME_LEN, "%s %s", buf.release, buf.version);
#else
snprintf((char *)version,
VERSION_LEN, "%s", buf.release);
VERSION_NAME_LEN, "%s", buf.release);
#endif
#else
memset(version, 0, VERSION_LEN);