]> granicus.if.org Git - neomutt/commitdiff
manually touch 'atime' when reading a mbox file
authorAdam Borowski <kilobyte@angband.pl>
Wed, 21 Dec 2016 22:10:02 +0000 (23:10 +0100)
committerRichard Russon <rich@flatcap.org>
Sat, 31 Dec 2016 17:16:00 +0000 (17:16 +0000)
futimens is a new thing, coming from POSIX-2008, yet all modern Unices added
it almost immediately.  If it isn't implemented, silently ignoring that is
no worse than current state.

While performance issues related to atime updates have been greatly reduced
by relatime and lazytime, it is an abomination for other reasons: CoW
filesystems (btrfs, zfs, ...), CoWed VM images, deduplicating thin
provisioning, etc lose significant space for every snapshot.  It also causes
wear on flash-based storage prevalent on SoCs, and so on.  Thus, it is
prudent to mount everything with noatime.

There is only one real use for atime these days: new mail notification on
mbox files.  With only a limited number of readers (mutt is one), let's
do atime updates manually.

This can be done unconditionally: while redundant without noatime, there's
no performance loss as the inode will be dirty already in such case.

Closes: #272
configure.ac
mbox.c
muttlib.c
protos.h
version.c

index 398cbd27a230fbc836e2b51ff8123eb3cfc919b5..37c856db106e022ef21ad8acad3b5fdac92bbe12 100644 (file)
@@ -564,6 +564,9 @@ AC_CHECK_FUNCS(ftruncate, , [AC_CHECK_LIB(x, chsize)])
 dnl SCO has strftime() in libintl
 AC_CHECK_FUNCS(strftime, , [AC_CHECK_LIB(intl, strftime)])
 
+dnl Set the atime of files
+AC_CHECK_FUNCS(futimens)
+
 dnl AIX may not have fchdir()
 AC_CHECK_FUNCS(fchdir, , [mutt_cv_fchdir=no])
 
diff --git a/mbox.c b/mbox.c
index 37f426d8e55b7c36a5eae72624d24f10e6278e09..f6000feafb9fece59350f23a95ec6ac505bbab4e 100644 (file)
--- a/mbox.c
+++ b/mbox.c
@@ -436,6 +436,7 @@ static int mbox_open_mailbox (CONTEXT *ctx)
     rc = mmdf_parse_mailbox (ctx);
   else
     rc = -1;
+  mutt_touch_atime (fileno (ctx->fp));
 
   mbox_unlock_mailbox (ctx);
   mutt_unblock_signals ();
@@ -1255,6 +1256,8 @@ int mutt_reopen_mailbox (CONTEXT *ctx, int *index_hint)
     return (-1);
   }
 
+  mutt_touch_atime (fileno (ctx->fp));
+
   /* now try to recover the old flags */
 
   index_hint_set = (index_hint == NULL);
index f482ed31168cc3b13cd19bcfc4633914567cda65..6ef660a4f8b608880043be80d4e957ce7a7a9590 100644 (file)
--- a/muttlib.c
+++ b/muttlib.c
@@ -2008,6 +2008,16 @@ void mutt_set_mtime (const char* from, const char* to)
   }
 }
 
+/* set atime to current time, just as read() would do on !noatime.
+ * Silently ignored if unsupported. */
+void mutt_touch_atime (int f)
+{
+#ifdef HAVE_FUTIMENS
+  struct timespec times[2]={{0,UTIME_NOW},{0,UTIME_OMIT}};
+  futimens(f, times);
+#endif
+}
+
 const char *mutt_make_version (void)
 {
   static char vstring[STRING];
index 72eb5e6e764ce3808786df4e13fcefb44fc454fd..9ee8393386a21b5526a7d292035ed8a5ace6b6d5 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -133,6 +133,7 @@ time_t mutt_local_tz (time_t);
 time_t mutt_mktime (struct tm *, int);
 time_t mutt_parse_date (const char *, HEADER *);
 int is_from (const char *, char *, size_t, time_t *);
+void mutt_touch_atime (int);
 
 const char *mutt_attach_fmt (
        char *dest,
index 933c6a3bbc6319a62ce2a1c3158c874555d07c62..2f93a61c1d3e947b757e7f393d25da884db0dbda 100644 (file)
--- a/version.c
+++ b/version.c
@@ -171,6 +171,11 @@ static struct compile_options comp_opts[] =
 #else
   { "HAVE_CURS_SET", 0 },
 #endif
+#ifdef HAVE_FUTIMENS
+  { "HAVE_FUTIMENS", 1 },
+#else
+  { "HAVE_FUTIMENS", 0 },
+#endif
 #ifdef HAVE_GETADDRINFO
   { "HAVE_GETADDRINFO", 1 },
 #else