From 2b23657db008e266e0a547bfdecb3c28dce4e56a Mon Sep 17 00:00:00 2001 From: John Goerzen Date: Sat, 2 Aug 2008 14:55:08 -0500 Subject: [PATCH] Added ability to disable fsync() Passed config to LocalStatus and Maildir folders so they can look up the fsync status --- offlineimap.conf | 10 ++++++++++ offlineimap/folder/LocalStatus.py | 20 ++++++++++++-------- offlineimap/folder/Maildir.py | 7 +++++-- offlineimap/repository/LocalStatus.py | 6 ++++-- offlineimap/repository/Maildir.py | 6 ++++-- 5 files changed, 35 insertions(+), 14 deletions(-) diff --git a/offlineimap.conf b/offlineimap.conf index 996fe7a..de1a9d9 100644 --- a/offlineimap.conf +++ b/offlineimap.conf @@ -98,6 +98,16 @@ ignore-readonly = no # # socktimeout = 60 +# By default, OfflineIMAP will use fsync() to force data out to disk at +# opportune times to ensure consistency. This can, however, reduce +# performance. Users where /home is on SSD (Flash) may also wish to reduce +# write cycles. Therefore, you can disable OfflineIMAP's use of fsync(). +# Doing so will come at the expense of greater risk of message duplication +# in the event of a system crash or power loss. Default is fsync = true. +# Set fsync = false ot disable fsync. +# +# fsync = true + ################################################## # Mailbox name recorder ################################################## diff --git a/offlineimap/folder/LocalStatus.py b/offlineimap/folder/LocalStatus.py index 4bb83ee..c07c2b5 100644 --- a/offlineimap/folder/LocalStatus.py +++ b/offlineimap/folder/LocalStatus.py @@ -22,10 +22,12 @@ import os, threading magicline = "OFFLINEIMAP LocalStatus CACHE DATA - DO NOT MODIFY - FORMAT 1" class LocalStatusFolder(BaseFolder): - def __init__(self, root, name, repository, accountname): + def __init__(self, root, name, repository, accountname, config): self.name = name self.root = root self.sep = '.' + self.config = config + self.dofsync = config.getdefaultboolean("general", "fsync") self.filename = os.path.join(root, name) self.filename = repository.getfolderfilename(name) self.messagelist = None @@ -96,16 +98,18 @@ class LocalStatusFolder(BaseFolder): flags = ''.join(flags) file.write("%s:%s\n" % (msg['uid'], flags)) file.flush() - os.fsync(file.fileno()) + if self.dofsync: + os.fsync(file.fileno()) file.close() os.rename(self.filename + ".tmp", self.filename) - try: - fd = os.open(os.path.dirname(self.filename), os.O_RDONLY) - os.fsync(fd) - os.close(fd) - except: - pass + if self.dofsync: + try: + fd = os.open(os.path.dirname(self.filename), os.O_RDONLY) + os.fsync(fd) + os.close(fd) + except: + pass finally: self.savelock.release() diff --git a/offlineimap/folder/Maildir.py b/offlineimap/folder/Maildir.py index 56a63e4..9b1b9ca 100644 --- a/offlineimap/folder/Maildir.py +++ b/offlineimap/folder/Maildir.py @@ -45,8 +45,10 @@ def gettimeseq(): timelock.release() class MaildirFolder(BaseFolder): - def __init__(self, root, name, sep, repository, accountname): + def __init__(self, root, name, sep, repository, accountname, config): self.name = name + self.config = config + self.dofsync = config.getdefaultboolean("general", "fsync") self.root = root self.sep = sep self.messagelist = None @@ -183,7 +185,8 @@ class MaildirFolder(BaseFolder): # Make sure the data hits the disk file.flush() - os.fsync(file.fileno()) + if self.dofsync: + os.fsync(file.fileno()) file.close() if rtime != None: diff --git a/offlineimap/repository/LocalStatus.py b/offlineimap/repository/LocalStatus.py index 8b7ac51..92e392d 100644 --- a/offlineimap/repository/LocalStatus.py +++ b/offlineimap/repository/LocalStatus.py @@ -54,12 +54,14 @@ class LocalStatusRepository(BaseRepository): retval = [] for folder in os.listdir(self.directory): retval.append(folder.LocalStatus.LocalStatusFolder(self.directory, - folder, self, self.accountname)) + folder, self, self.accountname, + self.config)) return retval def getfolder(self, foldername): return folder.LocalStatus.LocalStatusFolder(self.directory, foldername, - self, self.accountname) + self, self.accountname, + self.config) diff --git a/offlineimap/repository/Maildir.py b/offlineimap/repository/Maildir.py index 291f35a..53edd63 100644 --- a/offlineimap/repository/Maildir.py +++ b/offlineimap/repository/Maildir.py @@ -113,7 +113,8 @@ class MaildirRepository(BaseRepository): if self.config.has_option('Repository ' + self.name, 'restoreatime') and self.config.getboolean('Repository ' + self.name, 'restoreatime'): self._append_folder_atimes(foldername) return folder.Maildir.MaildirFolder(self.root, foldername, - self.getsep(), self, self.accountname) + self.getsep(), self, + self.accountname, self.config) def _getfolders_scandir(self, root, extension = None): self.debug("_GETFOLDERS_SCANDIR STARTING. root = %s, extension = %s" \ @@ -159,7 +160,8 @@ class MaildirRepository(BaseRepository): if self.config.has_option('Repository ' + self.name, 'restoreatime') and self.config.getboolean('Repository ' + self.name, 'restoreatime'): self._append_folder_atimes(foldername) retval.append(folder.Maildir.MaildirFolder(self.root, foldername, - self.getsep(), self, self.accountname)) + self.getsep(), self, self.accountname, + self.config)) if self.getsep() == '/' and dirname != '.': # Check sub-directories for folders. retval.extend(self._getfolders_scandir(root, foldername))