From 4a83daacc42f3a561fa30ba6124046898649d183 Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Sun, 22 Nov 2020 15:06:29 +0300 Subject: [PATCH] Ticket #4147: VFS timestamps: use g_get_real_time(). In the function vfs_expire(), curr_time and exp_time are declared guint64. curr_time is initialised with a timestamp and exp_time with this timestamp minus vfs_timeout seconds. Later there is if (stamping->time <= exp_time). Prior to commit a94dd7d2ded0dd3ce3f6cd2c56612327d065b5ac curr_time was initialised with a value larger than vfs_timeout seconds, so everything was fine. This commit changed the initialisation to a timer starting when mc is started. So for the first vfs_timeout seconds, the result of the subtraction is negative, but it is a guint64, so we just get a VERY large unsigned value and the if (stamping->time <= exp_time) is always true. So mc thinks the vfs hasn't been used recently and goes into an infinite loop. If one opens a .rpm file with mc and goes into the CONTENTS.cpio and then tries to go into the .tar.gz there (this is the usual structure of a .rpm) after waiting vfs_timeout seconds, everything is fine. However, before vfs_timeout seconds, mc hangs. Solution: use g_get_real_time() instead of mc_timer_elapsed(). Thanks nvwarr at hotmail.com for finding out the reason for this bug. Signed-off-by: Andrew Borodin --- lib/vfs/direntry.c | 5 ++--- lib/vfs/gc.c | 11 +++++------ lib/vfs/xdirentry.h | 2 +- src/vfs/fish/fish.c | 3 +-- src/vfs/ftpfs/ftpfs.c | 11 +++++------ 5 files changed, 14 insertions(+), 18 deletions(-) diff --git a/lib/vfs/direntry.c b/lib/vfs/direntry.c index 949fe04c5..d2211ea5b 100644 --- a/lib/vfs/direntry.c +++ b/lib/vfs/direntry.c @@ -70,7 +70,6 @@ #include "lib/tty/tty.h" /* enable/disable interrupt key */ #include "lib/util.h" /* custom_canonicalize_pathname() */ -#include "lib/timer.h" #if 0 #include "lib/widget.h" /* message() */ #endif @@ -863,7 +862,7 @@ vfs_s_free (vfsid id) static gboolean vfs_s_dir_uptodate (struct vfs_class *me, struct vfs_s_inode *ino) { - guint64 tim; + gint64 tim; if (me->flush) { @@ -871,7 +870,7 @@ vfs_s_dir_uptodate (struct vfs_class *me, struct vfs_s_inode *ino) return 0; } - tim = mc_timer_elapsed (mc_global.timer); + tim = g_get_real_time (); return (tim < ino->timestamp); } diff --git a/lib/vfs/gc.c b/lib/vfs/gc.c index 5090aaacb..d0bad1f91 100644 --- a/lib/vfs/gc.c +++ b/lib/vfs/gc.c @@ -44,7 +44,6 @@ #include "lib/global.h" #include "lib/event.h" #include "lib/util.h" /* MC_PTR_FREE */ -#include "lib/timer.h" #include "vfs.h" #include "utilvfs.h" @@ -98,7 +97,7 @@ struct vfs_stamping { struct vfs_class *v; vfsid id; - guint64 time; + gint64 time; }; /*** file scope variables ************************************************************************/ @@ -130,7 +129,7 @@ vfs_addstamp (struct vfs_class *v, vfsid id) stamp = g_new (struct vfs_stamping, 1); stamp->v = v; stamp->id = id; - stamp->time = mc_timer_elapsed (mc_global.timer); + stamp->time = g_get_real_time (); stamps = g_slist_append (stamps, stamp); } @@ -153,7 +152,7 @@ vfs_stamp (struct vfs_class *v, vfsid id) stamp = g_slist_find_custom (stamps, &what, vfs_stamp_compare); if (stamp != NULL && stamp->data != NULL) { - VFS_STAMPING (stamp->data)->time = mc_timer_elapsed (mc_global.timer); + VFS_STAMPING (stamp->data)->time = g_get_real_time (); ret = TRUE; } @@ -239,7 +238,7 @@ void vfs_expire (gboolean now) { static gboolean locked = FALSE; - guint64 curr_time, exp_time; + gint64 curr_time, exp_time; GSList *stamp; /* Avoid recursive invocation, e.g. when one of the free functions @@ -248,7 +247,7 @@ vfs_expire (gboolean now) return; locked = TRUE; - curr_time = mc_timer_elapsed (mc_global.timer); + curr_time = g_get_real_time (); exp_time = curr_time - vfs_timeout * G_USEC_PER_SEC; if (now) diff --git a/lib/vfs/xdirentry.h b/lib/vfs/xdirentry.h index 7b6410e74..56ce843a3 100644 --- a/lib/vfs/xdirentry.h +++ b/lib/vfs/xdirentry.h @@ -91,7 +91,7 @@ struct vfs_s_inode struct stat st; /* Parameters of this inode */ char *linkname; /* Symlink's contents */ char *localname; /* Filename of local file, if we have one */ - guint64 timestamp; /* Subclass specific */ + gint64 timestamp; /* Subclass specific */ off_t data_offset; /* Subclass specific */ }; diff --git a/src/vfs/fish/fish.c b/src/vfs/fish/fish.c index 5cd279f95..8f8f59543 100644 --- a/src/vfs/fish/fish.c +++ b/src/vfs/fish/fish.c @@ -65,7 +65,6 @@ #include "lib/fileloc.h" #include "lib/util.h" /* my_exit() */ #include "lib/mcconfig.h" -#include "lib/timer.h" #include "src/execute.h" /* pre_exec, post_exec */ @@ -766,7 +765,7 @@ fish_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, char *remote_path) vfs_print_message (_("fish: Reading directory %s..."), remote_path); - dir->timestamp = mc_timer_elapsed (mc_global.timer) + fish_directory_timeout * G_USEC_PER_SEC; + dir->timestamp = g_get_real_time () + fish_directory_timeout * G_USEC_PER_SEC; quoted_path = strutils_shell_escape (remote_path); (void) fish_command_v (me, super, NONE, FISH_SUPER (super)->scr_ls, "FISH_FILENAME=%s;\n", diff --git a/src/vfs/ftpfs/ftpfs.c b/src/vfs/ftpfs/ftpfs.c index 8a841ac1a..4c02ba409 100644 --- a/src/vfs/ftpfs/ftpfs.c +++ b/src/vfs/ftpfs/ftpfs.c @@ -98,7 +98,6 @@ What to do with this? #include "lib/util.h" #include "lib/strutil.h" /* str_move() */ #include "lib/mcconfig.h" -#include "lib/timer.h" #include "lib/tty/tty.h" /* enable/disable interrupt key */ #include "lib/widget.h" /* message() */ @@ -1491,17 +1490,17 @@ ftpfs_linear_abort (struct vfs_class *me, vfs_file_handler_t * fh) if (select (dsock + 1, &mask, NULL, NULL, NULL) > 0) { - guint64 start_tim; + gint64 start_tim; char buf[BUF_8K]; - start_tim = mc_timer_elapsed (mc_global.timer); + start_tim = g_get_real_time (); /* flush the remaining data */ while (read (dsock, buf, sizeof (buf)) > 0) { - guint64 tim; + gint64 tim; - tim = mc_timer_elapsed (mc_global.timer); + tim = g_get_real_time (); if (tim > start_tim + ABORT_TIMEOUT) { @@ -1748,7 +1747,7 @@ ftpfs_dir_load (struct vfs_class *me, struct vfs_s_inode *dir, char *remote_path return (-1); } - dir->timestamp = mc_timer_elapsed (mc_global.timer) + ftpfs_directory_timeout * G_USEC_PER_SEC; + dir->timestamp = g_get_real_time () + ftpfs_directory_timeout * G_USEC_PER_SEC; if (ftp_super->strict == RFC_STRICT) sock = ftpfs_open_data_connection (me, super, "LIST", 0, TYPE_ASCII, 0);