# fflush() and escalate errors correctly. Index: imap/sync_server.c =================================================================== RCS file: /cvs/src/cyrus/imap/sync_server.c,v retrieving revision 1.8 diff -u -d -r1.8 sync_server.c --- imap/sync_server.c 30 Aug 2007 17:51:44 -0000 1.8 +++ imap/sync_server.c 3 Sep 2007 08:36:05 -0000 @@ -1891,8 +1891,13 @@ goto parse_err; } - if (message_list->cache_buffer_size > 0) - sync_message_list_cache_flush(message_list); + if (message_list->cache_buffer_size > 0) { + r = sync_message_list_cache_flush(message_list); + if (r) { + err = "Failed to flush messages to disk"; + goto parse_err; + } + } /* YYY Problem: sync_server needs source of Message-UUID for new uploaded messages. Schema 2? */ @@ -1981,10 +1986,10 @@ } /* Make sure cache data flushed to disk before we commit */ - sync_message_fsync(message_list); - sync_message_list_cache_flush(message_list); - - r=sync_upload_commit(mailbox, last_appenddate, upload_list, message_list); + r = sync_message_fsync(message_list); + if (!r) sync_message_list_cache_flush(message_list); + if (!r) r = sync_upload_commit(mailbox, last_appenddate, + upload_list, message_list); if (r) { prot_printf(sync_out, "NO Failed to commit message upload to %s: %s\r\n", Index: imap/sync_support.c =================================================================== RCS file: /cvs/src/cyrus/imap/sync_support.c,v retrieving revision 1.9 diff -u -d -r1.9 sync_support.c --- imap/sync_support.c 16 Jul 2007 18:01:25 -0000 1.9 +++ imap/sync_support.c 3 Sep 2007 08:36:05 -0000 @@ -959,9 +959,10 @@ return(result); } -void sync_message_fsync(struct sync_message_list *l) +int sync_message_fsync(struct sync_message_list *l) { int i; + int r = 0; if (l->file_count == 0) return; @@ -969,11 +970,15 @@ /* fsync() files in reverse order: ReiserFS FAQ indicates that this * gives best potential for optimisation */ for (i = (l->file_count-1) ; i >= 0 ; i--) { - fsync(fileno(l->file[i])); - fclose(l->file[i]); + if ((fflush(l->file[i]) != 0) || + (fsync(fileno(l->file[i])) < 0) || + (fclose(l->file[i]) != 0)) + r = IMAP_IOERROR; /* Aggregate to single error */ l->file[i] = NULL; } l->file_count = 0; + + return(r); } FILE *sync_message_open(struct sync_message_list *l, @@ -981,8 +986,12 @@ { FILE *file; - if (l->file_count == l->file_max) - sync_message_fsync(l); + if (l->file_count == l->file_max) { + if (sync_message_fsync(l) != 0) { + syslog(LOG_ERR, "sync_message_open(): Unable to flush files"); + return(NULL); + } + } /* unlink just in case a previous crash left a file * hard linked into someone else's mailbox! */ @@ -1286,8 +1295,10 @@ /* If switching from PARSED to SIMPLE, need to flush cache. This is * redundant as it duplicates code in cmd_upload() (which is the * logical place for the code to go), but better safe than sorry. */ - if (list->cache_buffer_size > 0) - sync_message_list_cache_flush(list); + if (list->cache_buffer_size > 0) { + if ((r = sync_message_list_cache_flush(list))) + return(r); + } if ((r = sync_getliteral_size(input, output, &message->msg_size))) return(r); Index: imap/sync_support.h =================================================================== RCS file: /cvs/src/cyrus/imap/sync_support.h,v retrieving revision 1.3 diff -u -d -r1.3 sync_support.h --- imap/sync_support.h 18 May 2007 13:24:40 -0000 1.3 +++ imap/sync_support.h 3 Sep 2007 08:36:05 -0000 @@ -310,7 +310,7 @@ struct sync_message *sync_message_find(struct sync_message_list *l, struct message_uuid *uuid); -void sync_message_fsync(struct sync_message_list *l); +int sync_message_fsync(struct sync_message_list *l); FILE *sync_message_open(struct sync_message_list *l, struct sync_message *message);