/* Maximum difference between current time and create file's ctime before
logging a warning. Should be less than a second in normal operation. */
#define MAX_TIME_DIFF 30
+/* NFS may return a cached mtime in stat(). A later non-cached stat() may
+ return a slightly different mtime. Allow the difference to be this much
+ and still consider it to be the same mtime. */
+#define FILE_DOTLOCK_MAX_STAT_MTIME_DIFF 1
struct dotlock {
struct dotlock_settings settings;
}
}
+static bool file_dotlock_has_mtime_changed(time_t t1, time_t t2)
+{
+ time_t diff;
+
+ if (t1 == t2)
+ return FALSE;
+
+ /* with NFS t1 may have been looked up from local cache.
+ allow it to be a little bit different. */
+ diff = t1 > t2 ? t1-t2 : t2-t1;
+ return diff <= FILE_DOTLOCK_MAX_STAT_MTIME_DIFF;
+}
+
int file_dotlock_delete(struct dotlock **dotlock_p)
{
struct dotlock *dotlock;
return 0;
}
- if (dotlock->mtime != st.st_mtime && dotlock->fd == -1) {
+ if (file_dotlock_has_mtime_changed(dotlock->mtime, st.st_mtime) &&
+ dotlock->fd == -1) {
i_warning("Our dotlock file %s was modified (%s vs %s), "
"assuming it wasn't overridden (kept it %d secs)",
lock_path,