]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
ext4: fix lazy initialization next schedule time computation in more granular unit
authorShaoying Xu <shaoyi@amazon.com>
Thu, 2 Sep 2021 16:44:12 +0000 (16:44 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 26 Nov 2021 10:36:18 +0000 (11:36 +0100)
commit 39fec6889d15a658c3a3ebb06fd69d3584ddffd3 upstream.

Ext4 file system has default lazy inode table initialization setup once
it is mounted. However, it has issue on computing the next schedule time
that makes the timeout same amount in jiffies but different real time in
secs if with various HZ values. Therefore, fix by measuring the current
time in a more granular unit nanoseconds and make the next schedule time
independent of the HZ value.

Fixes: bfff68738f1c ("ext4: add support for lazy inode table initialization")
Signed-off-by: Shaoying Xu <shaoyi@amazon.com>
Cc: stable@vger.kernel.org
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Link: https://lore.kernel.org/r/20210902164412.9994-2-shaoyi@amazon.com
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/ext4/super.c

index 9ae3b6dd72fe8fd1c8316873e86f995a78ef7fc9..fab2092856a27f71280c82de7b1b9f8afcf0ac9d 100644 (file)
@@ -3026,8 +3026,8 @@ static int ext4_run_li_request(struct ext4_li_request *elr)
        struct ext4_group_desc *gdp = NULL;
        ext4_group_t group, ngroups;
        struct super_block *sb;
-       unsigned long timeout = 0;
        int ret = 0;
+       u64 start_time;
 
        sb = elr->lr_super;
        ngroups = EXT4_SB(sb)->s_groups_count;
@@ -3047,13 +3047,12 @@ static int ext4_run_li_request(struct ext4_li_request *elr)
                ret = 1;
 
        if (!ret) {
-               timeout = jiffies;
+               start_time = ktime_get_real_ns();
                ret = ext4_init_inode_table(sb, group,
                                            elr->lr_timeout ? 0 : 1);
                if (elr->lr_timeout == 0) {
-                       timeout = (jiffies - timeout) *
-                                 elr->lr_sbi->s_li_wait_mult;
-                       elr->lr_timeout = timeout;
+                       elr->lr_timeout = nsecs_to_jiffies((ktime_get_real_ns() - start_time) *
+                                 elr->lr_sbi->s_li_wait_mult);
                }
                elr->lr_next_sched = jiffies + elr->lr_timeout;
                elr->lr_next_group = group + 1;