add option to control amount of fsync()ing
This commit is contained in:
parent
49223b2df2
commit
35851f133b
2
NEWS
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
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
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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
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]
|
||||
..
|
||||
|
|
|
@ -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()."
|
||||
|
|
|
@ -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…
Reference in New Issue
Block a user