Browse Source

add option to control amount of fsync()ing

wip/maildir-uid-dupes-test
Oswald Buddenhagen 12 years ago
parent
commit
35851f133b
  1. 2
      NEWS
  2. 2
      TODO
  3. 11
      src/config.c
  4. 4
      src/drv_maildir.c
  5. 6
      src/isync.h
  6. 22
      src/mbsync.1
  7. 4
      src/run-tests.pl
  8. 5
      src/sync.c

2
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

2
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 ...

11
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",

4
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

6
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 );

22
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]
..

4
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()."

5
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;

Loading…
Cancel
Save