commit dfa1f8f2f48318fc2b8956ef4463a8ec43679325
Author: Oswald Buddenhagen <o...@kde.org>
Date:   Sat Sep 15 15:15:22 2012 +0200

    add option to control amount of fsync()ing

 NEWS              |    2 ++
 TODO              |    2 ++
 src/config.c      |   11 +++++++++++
 src/drv_maildir.c |    4 ++--
 src/isync.h       |    6 ++++++
 src/mbsync.1      |   22 +++++++++++++++++++++-
 src/run-tests.pl  |    4 +++-
 src/sync.c        |    5 +++--
 8 files changed, 50 insertions(+), 6 deletions(-)

diff --git a/NEWS b/NEWS
index aa478c9..ff72886 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,8 @@ UIDPLUS extension (e.g., M$ Exchange).
 
 More automatic handling of SSL certificates.
 
+Data safety in case of system crashes is improved.
+
 [1.0.0]
 
 Essentially a rewrite. Synchronization state storage concept, configuration
diff --git a/TODO b/TODO
index 8eed42d..c12931c 100644
--- a/TODO
+++ b/TODO
@@ -1,5 +1,7 @@
 find out why mutt's message size calc is confused.
 
+f{,data}sync() usage could be optimized by batching the calls.
+
 add some marker about message being already [remotely] trashed.
 real transactions would be certainly not particularly useful ...
 
diff --git a/src/config.c b/src/config.c
index a998514..9e4f766 100644
--- a/src/config.c
+++ b/src/config.c
@@ -39,6 +39,7 @@ channel_conf_t *channels;
 group_conf_t *groups;
 int global_ops[2];
 char *global_sync_state;
+int FSyncLevel = FSYNC_NORMAL;
 
 #define ARG_OPTIONAL 0
 #define ARG_REQUIRED 1
@@ -448,6 +449,16 @@ load_config( const char *where, int pseudo )
                        }
                        break;
                }
+               else if (!strcasecmp( "FSync", cfile.cmd ))
+               {
+                       arg = cfile.val;
+                       if (!strcasecmp( "None", arg ))
+                               FSyncLevel = FSYNC_NONE;
+                       else if (!strcasecmp( "Normal", arg ))
+                               FSyncLevel = FSYNC_NORMAL;
+                       else if (!strcasecmp( "Thorough", arg ))
+                               FSyncLevel = FSYNC_THOROUGH;
+               }
                else if (!getopt_helper( &cfile, &gcops, global_ops, 
&global_sync_state ))
                {
                        error( "%s:%d: unknown section keyword '%s'\n",
diff --git a/src/drv_maildir.c b/src/drv_maildir.c
index 921f97f..4807e75 100644
--- a/src/drv_maildir.c
+++ b/src/drv_maildir.c
@@ -432,7 +432,7 @@ maildir_store_uid( maildir_store_t *ctx )
 
        n = sprintf( buf, "%d\n%d\n", ctx->gen.uidvalidity, ctx->nuid );
        lseek( ctx->uvfd, 0, SEEK_SET );
-       if (write( ctx->uvfd, buf, n ) != n || ftruncate( ctx->uvfd, n ) || 
fdatasync( ctx->uvfd )) {
+       if (write( ctx->uvfd, buf, n ) != n || ftruncate( ctx->uvfd, n ) || 
(FSyncLevel >= FSYNC_NORMAL && fdatasync( ctx->uvfd ))) {
                error( "Maildir error: cannot write UIDVALIDITY.\n" );
                return DRV_BOX_BAD;
        }
@@ -1204,7 +1204,7 @@ maildir_store_msg( store_t *gctx, msg_data_t *data, int 
to_trash,
        }
        ret = write( fd, data->data, data->len );
        free( data->data );
-       if (ret != data->len || (ret = fsync( fd ))) {
+       if (ret != data->len || ((FSyncLevel >= FSYNC_NORMAL) && (ret = fsync( 
fd )))) {
                if (ret < 0)
                        sys_error( "Maildir error: cannot write %s", buf );
                else
diff --git a/src/isync.h b/src/isync.h
index 3ea5fd0..ef6759e 100644
--- a/src/isync.h
+++ b/src/isync.h
@@ -481,6 +481,12 @@ extern group_conf_t *groups;
 extern int global_ops[2];
 extern char *global_sync_state;
 
+#define FSYNC_NONE     0
+#define FSYNC_NORMAL   1
+#define FSYNC_THOROUGH 2
+
+extern int FSyncLevel;
+
 int parse_bool( conffile_t *cfile );
 int parse_int( conffile_t *cfile );
 int parse_size( conffile_t *cfile );
diff --git a/src/mbsync.1 b/src/mbsync.1
index ced52ed..d452e31 100644
--- a/src/mbsync.1
+++ b/src/mbsync.1
@@ -20,7 +20,7 @@
 \" As a special exception, mbsync may be linked with the OpenSSL library,
 \" despite that library's more restrictive license.
 ..
-.TH mbsync 1 "2012 Aug 25"
+.TH mbsync 1 "2012 Sep 15"
 ..
 .SH NAME
 mbsync - synchronize IMAP4 and Maildir mailboxes
@@ -477,6 +477,26 @@ line, except that there newlines can be used as mailbox 
name separators as well.
 Add the specified channels to the group. This option can be specified multiple
 times within a Group.
 ..
+.SS Global Options
+.TP
+\fBFSync\fR {\fINone\fR|\fINormal\fR|\fIThorough\fR}
+.br
+Select the amount of forced flushing \fBmbsync\fR performs, which determines
+the level of data safety after system crashes and power outages:
+.br
+\fBNone\fR - no flushing at all. This is reasonably safe for file systems
+which are mounted with data=ordered mode.
+.br
+\fBNormal\fR - message and critical metadata writes are flushed. No data
+should be lost due to crashes, though it is still possible that messages
+are duplicated after crashes. This is the default, and is a wise choice for
+file systems mounted with data=writeback, in particular modern systems like
+ext4, btrfs and xfs. The performance impact on older file systems may be
+disproportionate.
+.br
+\fBThorough\fR - this avoids message duplication after crashes as well,
+at some additional performance cost.
+..
 .SH SSL CERTIFICATES
 [to be done]
 ..
diff --git a/src/run-tests.pl b/src/run-tests.pl
index 9924f33..25eae65 100755
--- a/src/run-tests.pl
+++ b/src/run-tests.pl
@@ -256,7 +256,9 @@ sub writecfg($$$)
        open(FILE, ">", ".mbsyncrc") or
                die "Cannot open .mbsyncrc.\n";
        print FILE
-"MaildirStore master
+"FSync None
+
+MaildirStore master
 Path ./
 Inbox ./master
 ".shift()."
diff --git a/src/sync.c b/src/sync.c
index 3a1f386..17e0e06 100644
--- a/src/sync.c
+++ b/src/sync.c
@@ -42,7 +42,7 @@ const char *str_ms[] = { "master", "slave" }, *str_hl[] = { 
"push", "pull" };
 void
 Fclose( FILE *f, int safe )
 {
-       if ((safe && (fflush( f ) || fdatasync( fileno( f ) ))) || fclose( f ) 
== EOF) {
+       if ((safe && (fflush( f ) || (FSyncLevel >= FSYNC_NORMAL && fdatasync( 
fileno( f ) )))) || fclose( f ) == EOF) {
                sys_error( "Error: cannot close file. Disk full?" );
                exit( 1 );
        }
@@ -1202,7 +1202,8 @@ box_loaded( int sts, void *aux )
                                                cv->srec = srec;
                                                cv->msg = tmsg;
                                                Fprintf( svars->jfp, "# %d %d 
%." stringify(TUIDL) "s\n", srec->uid[M], srec->uid[S], srec->tuid );
-                                               fdatasync( fileno( svars->jfp ) 
);
+                                               if (FSyncLevel >= 
FSYNC_THOROUGH)
+                                                       fdatasync( fileno( 
svars->jfp ) );
                                                debug( "  -> %sing message, 
TUID %." stringify(TUIDL) "s\n", str_hl[t], srec->tuid );
                                                if (copy_msg( cv ))
                                                        return;

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://ad.doubleclick.net/clk;258768047;13503038;j?
http://info.appdynamics.com/FreeJavaPerformanceDownload.html
_______________________________________________
isync-devel mailing list
isync-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to