Subject: Re: bug#13149: 24.3.50; Emacs thinks file was changed outside Emacs, but it was not

From: Dmitry Gutov <[email-masked]>
Date: Tue, 15 Jan 2013 12:54:03 +0400

On 15.01.2013 10:45, Paul Eggert wrote:
> On 01/14/2013 02:20 PM, Dmitry Gutov wrote:
>
>> stat_mtime=1358201692.000000000
>> stat_mtime=1358201692.912737000
>
> That looks like a file system bug, I'm afraid.
> Does the following work around the bug, if you
> set the variable sloppy-file-time-stamps?

Not entirely.

When the value is t, it works ok right after I open the file, and also 
if I wait a second or more between save buffer commands.

If I repeat modify -> save cycle quickly enough, the problem is still 
visible.

> === modified file 'src/ChangeLog'
> --- src/ChangeLog	2013-01-14 17:46:14 +0000
> +++ src/ChangeLog	2013-01-15 05:38:42 +0000
> @@ -1,3 +1,10 @@
> +2013-01-15  Paul Eggert  <[email-masked]>
> +
> +	Add workaround for file system time stamp bug (Bug#13149).
> +	Reported by Dmitry Gutov for Ubuntu vboxsf mounting MS Windows 7.
> +	* fileio.c (syms_of_fileio) <sloppy-file-time-stamps>: New variable.
> +	(Fverify_visited_file_modtime): Use it.
> +
>   2013-01-14  Paul Eggert  <[email-masked]>
>
>   	Avoid needless casts with XSAVE_POINTER.
>
> === modified file 'src/fileio.c'
> --- src/fileio.c	2013-01-14 17:46:14 +0000
> +++ src/fileio.c	2013-01-15 05:38:42 +0000
> @@ -5358,7 +5358,17 @@
>     mtime = (stat (SSDATA (filename), &st) == 0
>   	   ? get_stat_mtime (&st)
>   	   : time_error_value (errno));
> -  if (EMACS_TIME_EQ (mtime, b->modtime)
> +
> +  /* On a few buggy file systems, the fractional part of the time stamp,
> +     or perhaps even the low order bit of the seconds part, can
> +     spontaneously change even though the file has not changed.  If
> +     SLOPPY_FILE_TIME_STAMPS, work around these bugs at the cost of
> +     possibly missing some changes.  */
> +  if ((EMACS_TIME_EQ (mtime, b->modtime)
> +       || (sloppy_file_time_stamps
> +	   && EMACS_TIME_VALID_P (mtime)
> +	   && EMACS_TIME_VALID_P (b->modtime)
> +	   && EMACS_SECS (mtime) >> 1 == EMACS_SECS (b->modtime) >> 1))
>         && (b->modtime_size < 0
>   	  || st.st_size == b->modtime_size))
>       return Qt;
> @@ -6036,6 +6046,13 @@
>     write_region_inhibit_fsync = 0;
>   #endif
>
> +  DEFVAR_BOOL ("sloppy-file-time-stamps", sloppy_file_time_stamps,
> +	       doc: /* Non-nil means file time stamps are sloppy.
> +When non-nil, ignore low-order part of time stamp when inferring whether
> +a file may have changed.  Although this suppresses bogus diagnostics
> +on buggy file systems, it can also lose changes to files.  */);
> +  sloppy_file_time_stamps = 0;
> +
>     DEFVAR_BOOL ("delete-by-moving-to-trash", delete_by_moving_to_trash,
>                  doc: /* Specifies whether to use the system's trash can.
>   When non-nil, certain file deletion commands use the function
>
>