changeset 22942:b91af97dd666

lib-fs: fs-posix - Add accurate-mtime parameter This is mainly useful for testing to find out whether one file was created after another.
author Timo Sirainen <timo.sirainen@dovecot.fi>
date Thu, 26 Apr 2018 19:38:55 +0300
parents 731b91108e05
children b00d51dbc55d
files src/lib-fs/fs-posix.c
diffstat 1 files changed, 18 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-fs/fs-posix.c	Thu Apr 26 18:23:54 2018 +0300
+++ b/src/lib-fs/fs-posix.c	Thu Apr 26 19:38:55 2018 +0300
@@ -37,6 +37,7 @@
 	bool mode_auto;
 	bool have_dirs;
 	bool disable_fsync;
+	bool accurate_mtime;
 };
 
 struct posix_fs_file {
@@ -110,6 +111,8 @@
 			fs->have_dirs = TRUE;
 		} else if (strcmp(arg, "no-fsync") == 0) {
 			fs->disable_fsync = TRUE;
+		} else if (strcmp(arg, "accurate-mtime") == 0) {
+			fs->accurate_mtime = TRUE;
 		} else if (strncmp(arg, "mode=", 5) == 0) {
 			unsigned int mode;
 			if (str_to_uint_oct(arg+5, &mode) < 0) {
@@ -476,6 +479,21 @@
 			return -1;
 		}
 	}
+	if (fs->accurate_mtime) {
+		/* Linux updates the mtime timestamp only on timer interrupts.
+		   This isn't anywhere close to being microsecond precision.
+		   If requested, use utimes() to explicitly set a more accurate
+		   mtime. */
+		struct timeval tv[2];
+		if (gettimeofday(&tv[0], NULL) < 0)
+			i_fatal("gettimeofday() failed: %m");
+		tv[1] = tv[0];
+		if ((utimes(file->temp_path, tv)) < 0) {
+			fs_set_error(file->file.fs, "utimes(%s) failed: %m",
+				     file->temp_path);
+			return -1;
+		}
+	}
 
 	fs_posix_write_rename_if_needed(file);
 	switch (file->open_mode) {