Skip to content
Permalink
Browse files

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
  • Loading branch information
kilobyte authored and flatcap committed Dec 31, 2016
1 parent 2c84a05 commit 816095bfdb72caafd8845e8fb28cbc8c6afc114f
Showing with 22 additions and 0 deletions.
  1. +3 −0 configure.ac
  2. +3 −0 mbox.c
  3. +10 −0 muttlib.c
  4. +1 −0 protos.h
  5. +5 −0 version.c
@@ -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])

3 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);
@@ -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];
@@ -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,
@@ -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

0 comments on commit 816095b

Please sign in to comment.
You can’t perform that action at this time.