=== modified file 'src/ChangeLog' --- src/ChangeLog 2013-01-15 21:38:58 +0000 +++ src/ChangeLog 2013-01-16 05:01:01 +0000 @@ -1,3 +1,18 @@ +2013-01-16 Paul Eggert + + Work around bug in vboxsf file system (Bug#13149). + The bug was observed on Ubuntu operating inside a virtual machine, + editing files mounted via vboxsf from the MS Windows 7 host. + The workaround introduces a race condition on non-buggy hosts, + but it's an unlikely race and anyway there's a nearly identical + nearby race that can't be fixed. + * fileio.c (valid_timestamp_file_system, timestamp_file_system): + New static vars. + (Fwrite_region): Test for file system time stamp bug. + (init_fileio): New function. + * lisp.h (init_fileio): Declare it. + * emacs.c (main): Call it. + 2013-01-15 Paul Eggert * alloc.c (free_save_value): Now static. === modified file 'src/emacs.c' --- src/emacs.c 2013-01-13 20:03:01 +0000 +++ src/emacs.c 2013-01-16 05:01:01 +0000 @@ -1317,6 +1317,7 @@ } init_callproc (); /* Must follow init_cmdargs but not init_sys_modes. */ + init_fileio (); init_lread (); #ifdef WINDOWSNT /* Check to see if Emacs has been installed correctly. */ === modified file 'src/fileio.c' --- src/fileio.c 2013-01-15 10:14:31 +0000 +++ src/fileio.c 2013-01-16 05:04:51 +0000 @@ -103,6 +103,11 @@ /* Set by auto_save_1 if an error occurred during the last auto-save. */ static bool auto_save_error_occurred; +/* If VALID_TIMESTAMP_FILE_SYSTEM, then TIMESTAMP_FILE_SYSTEM is the device + number of a file system where time stamps were observed to to work. */ +static bool valid_timestamp_file_system; +static dev_t timestamp_file_system; + /* The symbol bound to coding-system-for-read when insert-file-contents is called for recovering a file. This is not an actual coding system name, but just an indicator to tell @@ -5020,6 +5025,42 @@ /* Discard the unwind protect for close_file_unwind. */ specpdl_ptr = specpdl + count1; + /* Some file systems have a bug where st_mtime is updated merely + because a file was closed. Update MODTIME to the newer st_mtime + if this file system appears to have the bug. Working around this + bug introduces a race condition: to avoid most instances of the + race condition on non-buggy file systems, skip this check if the + most recently encountered non-buggy file system was the current + file system. + + A race condition can occur if some other process modifies the + file between the fstat above and the stat below, but the race is + unlikely and a similar race between the last write and the fstat + above cannot possibly be closed anyway. */ + + if (visiting && EMACS_TIME_VALID_P (modtime) + && ! (valid_timestamp_file_system && st.st_dev == timestamp_file_system)) + { + struct stat stat_st; + if (stat (fn, &stat_st) != 0) + ok = 0, save_errno = errno; + else if (stat_st.st_dev == st.st_dev && stat_st.st_ino == st.st_ino) + { + EMACS_TIME stat_modtime = get_stat_mtime (&stat_st); + if (EMACS_TIME_EQ (modtime, stat_modtime) + && st.st_size == stat_st.st_size) + { + timestamp_file_system = st.st_dev; + valid_timestamp_file_system = 1; + } + else + { + st.st_size = stat_st.st_size; + modtime = stat_modtime; + } + } + } + /* Call write-region-post-annotation-function. */ while (CONSP (Vwrite_region_annotation_buffers)) { @@ -5814,8 +5855,13 @@ args[6] = predicate; RETURN_UNGCPRO (Ffuncall (7, args)); } + +void +init_fileio (void) +{ + valid_timestamp_file_system = 0; +} - void syms_of_fileio (void) { === modified file 'src/lisp.h' --- src/lisp.h 2013-01-15 21:38:58 +0000 +++ src/lisp.h 2013-01-16 05:01:01 +0000 @@ -3256,6 +3256,7 @@ extern bool internal_delete_file (Lisp_Object); extern bool file_directory_p (const char *); extern bool file_accessible_directory_p (const char *); +extern void init_fileio (void); extern void syms_of_fileio (void); extern Lisp_Object make_temp_name (Lisp_Object, bool); extern Lisp_Object Qdelete_file;