2021-07-16 21:59:23

by Daeho Jeong

[permalink] [raw]
Subject: [PATCH] f2fs-tools: add periodic check in kernel version check

From: Daeho Jeong <[email protected]>

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 <[email protected]>
---
fsck/mount.c | 50 +++++++++++++++++++++++++++++++++++------------
include/f2fs_fs.h | 4 +++-
lib/libf2fs.c | 6 +++---
3 files changed, 44 insertions(+), 16 deletions(-)

diff --git a/fsck/mount.c b/fsck/mount.c
index 1f2d7e0..7c4c681 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -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;
}
diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h
index 45f7257..3000d9d 100644
--- a/include/f2fs_fs.h
+++ b/include/f2fs_fs.h
@@ -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"

diff --git a/lib/libf2fs.c b/lib/libf2fs.c
index 876c1dc..c6ab329 100644
--- a/lib/libf2fs.c
+++ b/lib/libf2fs.c
@@ -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);
--
2.32.0.402.g57bb445576-goog


2021-07-17 11:09:02

by Chao Yu

[permalink] [raw]
Subject: Re: [f2fs-dev] [PATCH] f2fs-tools: add periodic check in kernel version check

On 2021/7/17 5:57, Daeho Jeong wrote:
> From: Daeho Jeong <[email protected]>
>
> 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 <[email protected]>

Reviewed-by: Chao Yu <[email protected]>

Thanks,