From: Adam Borowski Date: Wed, 21 Dec 2016 22:10:02 +0000 (+0100) Subject: manually touch 'atime' when reading a mbox file X-Git-Tag: neomutt-20170113~13 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=816095bfdb72caafd8845e8fb28cbc8c6afc114f;p=neomutt manually touch 'atime' when reading a mbox file 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 --- diff --git a/configure.ac b/configure.ac index 398cbd27a..37c856db1 100644 --- a/configure.ac +++ b/configure.ac @@ -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 37f426d8e..f6000feaf 100644 --- 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); diff --git a/muttlib.c b/muttlib.c index f482ed311..6ef660a4f 100644 --- 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]; diff --git a/protos.h b/protos.h index 72eb5e6e7..9ee839338 100644 --- 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, diff --git a/version.c b/version.c index 933c6a3bb..2f93a61c1 100644 --- 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