]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-fs: fs-posix - Add accurate-mtime parameter
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Thu, 26 Apr 2018 16:38:55 +0000 (19:38 +0300)
committerTimo Sirainen <timo.sirainen@dovecot.fi>
Mon, 30 Apr 2018 13:06:32 +0000 (16:06 +0300)
This is mainly useful for testing to find out whether one file was created
after another.

src/lib-fs/fs-posix.c

index 3c9550e9320a8750b04bbd144419e12104e6d206..33bde79c58a45c5feb13a648f10429db68cab857 100644 (file)
@@ -37,6 +37,7 @@ struct posix_fs {
        bool mode_auto;
        bool have_dirs;
        bool disable_fsync;
+       bool accurate_mtime;
 };
 
 struct posix_fs_file {
@@ -110,6 +111,8 @@ fs_posix_init(struct fs *_fs, const char *args, const struct fs_settings *set)
                        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 @@ static int fs_posix_write_finish(struct posix_fs_file *file)
                        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) {