dovecot: Preserve mbox files' atime when saving/syncing.

dovecot at dovecot.org dovecot at dovecot.org
Thu Jun 14 15:01:12 EEST 2007


details:   http://hg.dovecot.org/dovecot/rev/7a57631e2d6c
changeset: 5741:7a57631e2d6c
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Jun 14 15:01:09 2007 +0300
description:
Preserve mbox files' atime when saving/syncing.

diffstat:

3 files changed, 37 insertions(+), 5 deletions(-)
src/lib-storage/index/mbox/mbox-save.c         |   24 ++++++++++++++++++++----
src/lib-storage/index/mbox/mbox-sync-private.h |    2 +-
src/lib-storage/index/mbox/mbox-sync.c         |   16 ++++++++++++++++

diffs (114 lines):

diff -r 05d06a1c0f0c -r 7a57631e2d6c src/lib-storage/index/mbox/mbox-save.c
--- a/src/lib-storage/index/mbox/mbox-save.c	Thu Jun 14 14:53:47 2007 +0300
+++ b/src/lib-storage/index/mbox/mbox-save.c	Thu Jun 14 15:01:09 2007 +0300
@@ -27,6 +27,7 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <netdb.h>
+#include <utime.h>
 
 #define MBOX_DELIVERY_ID_RAND_BYTES (64/8)
 
@@ -37,6 +38,7 @@ struct mbox_save_context {
 	struct mail_index_transaction *trans;
 	struct mail *mail;
 	uoff_t append_offset, mail_offset;
+	time_t orig_atime;
 
 	string_t *headers;
 	size_t space_end_idx;
@@ -78,6 +80,8 @@ static int mbox_seek_to_end(struct mbox_
 	fd = ctx->mbox->mbox_fd;
 	if (fstat(fd, &st) < 0)
                 return mbox_set_syscall_error(ctx->mbox, "fstat()");
+
+	ctx->orig_atime = st.st_atime;
 
 	*offset = (uoff_t)st.st_size;
 	if (st.st_size == 0)
@@ -644,6 +648,11 @@ int mbox_transaction_save_commit(struct 
 
 	i_assert(ctx->finished);
 
+	if (fstat(ctx->mbox->mbox_fd, &st) < 0) {
+		mbox_set_syscall_error(ctx->mbox, "fstat()");
+		ret = -1;
+	}
+
 	if (ctx->synced) {
 		*t->ictx.first_saved_uid = ctx->first_saved_uid;
 
@@ -651,10 +660,7 @@ int mbox_transaction_save_commit(struct 
 			offsetof(struct mail_index_header, next_uid),
 			&ctx->next_uid, sizeof(ctx->next_uid), FALSE);
 
-		if (fstat(ctx->mbox->mbox_fd, &st) < 0) {
-			mbox_set_syscall_error(ctx->mbox, "fstat()");
-			ret = -1;
-		} else if (!ctx->mbox->mbox_sync_dirty) {
+		if (!ctx->mbox->mbox_sync_dirty && ret == 0) {
 			uint32_t sync_stamp = st.st_mtime;
 			uint64_t sync_size = st.st_size;
 
@@ -669,6 +675,16 @@ int mbox_transaction_save_commit(struct 
 		*t->ictx.last_saved_uid = ctx->next_uid - 1;
 	}
 
+	if (ret == 0 && ctx->orig_atime != st.st_atime) {
+		/* try to set atime back to its original value */
+		struct utimbuf buf;
+
+		buf.modtime = st.st_mtime;
+		buf.actime = ctx->orig_atime;
+		if (utime(ctx->mbox->path, &buf) < 0)
+			mbox_set_syscall_error(ctx->mbox, "utime()");
+	}
+
 	if (!ctx->synced && ctx->mbox->mbox_fd != -1 &&
 	    !ctx->mbox->mbox_writeonly && !ctx->mbox->ibox.fsync_disable) {
 		if (fdatasync(ctx->mbox->mbox_fd) < 0) {
diff -r 05d06a1c0f0c -r 7a57631e2d6c src/lib-storage/index/mbox/mbox-sync-private.h
--- a/src/lib-storage/index/mbox/mbox-sync-private.h	Thu Jun 14 14:53:47 2007 +0300
+++ b/src/lib-storage/index/mbox/mbox-sync-private.h	Thu Jun 14 15:01:09 2007 +0300
@@ -105,7 +105,7 @@ struct mbox_sync_context {
 	struct istream *input, *file_input;
 	int write_fd;
 
-	time_t orig_mtime;
+	time_t orig_mtime, orig_atime;
 	uoff_t orig_size;
 	struct stat last_stat;
 
diff -r 05d06a1c0f0c -r 7a57631e2d6c src/lib-storage/index/mbox/mbox-sync.c
--- a/src/lib-storage/index/mbox/mbox-sync.c	Thu Jun 14 14:53:47 2007 +0300
+++ b/src/lib-storage/index/mbox/mbox-sync.c	Thu Jun 14 15:01:09 2007 +0300
@@ -1579,6 +1579,7 @@ static int mbox_sync_do(struct mbox_sync
 	}
 	sync_ctx->last_stat = *st;
 	sync_ctx->orig_size = st->st_size;
+	sync_ctx->orig_atime = st->st_atime;
 	sync_ctx->orig_mtime = st->st_mtime;
 
 	if ((flags & MBOX_SYNC_FORCE_SYNC) != 0) {
@@ -1864,6 +1865,21 @@ __again:
                 ret = mbox_rewrite_base_uid_last(&sync_ctx);
 	}
 
+	if (ret == 0 && mbox->mbox_fd != -1 && mbox->ibox.keep_recent) {
+		/* try to set atime back to its original value */
+		struct utimbuf buf;
+		struct stat st;
+
+		if (fstat(mbox->mbox_fd, &st) < 0)
+			mbox_set_syscall_error(mbox, "fstat()");
+		else {
+			buf.modtime = st.st_mtime;
+			buf.actime = sync_ctx.orig_atime;
+			if (utime(mbox->path, &buf) < 0)
+				mbox_set_syscall_error(mbox, "utime()");
+		}
+	}
+
 	i_assert(lock_id != 0);
 
 	if (mbox->mbox_lock_type != F_RDLCK) {


More information about the dovecot-cvs mailing list