Improve filesystem flushing semantics
fsync the Maildir file, its final directory when writing a new message. fsync the localstatus file and its final directory when writing the local status cache. This should reduce duplication in the event of hardware trouble. fixes #8 see thread at http://lists.complete.org/offlineimap@complete.org/2007/03/threads.html.gz
This commit is contained in:
parent
4b564bd568
commit
4f54887265
@ -1,5 +1,5 @@
|
|||||||
# Local status cache virtual folder
|
# Local status cache virtual folder
|
||||||
# Copyright (C) 2002 - 2003 John Goerzen
|
# Copyright (C) 2002 - 2007 John Goerzen
|
||||||
# <jgoerzen@complete.org>
|
# <jgoerzen@complete.org>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
@ -90,8 +90,18 @@ class LocalStatusFolder(BaseFolder):
|
|||||||
flags.sort()
|
flags.sort()
|
||||||
flags = ''.join(flags)
|
flags = ''.join(flags)
|
||||||
file.write("%s:%s\n" % (msg['uid'], flags))
|
file.write("%s:%s\n" % (msg['uid'], flags))
|
||||||
|
file.flush()
|
||||||
|
os.fsync(file.fileno())
|
||||||
file.close()
|
file.close()
|
||||||
os.rename(self.filename + ".tmp", self.filename)
|
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
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
self.savelock.release()
|
self.savelock.release()
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Maildir folder support
|
# Maildir folder support
|
||||||
# Copyright (C) 2002 - 2006 John Goerzen
|
# Copyright (C) 2002 - 2007 John Goerzen
|
||||||
# <jgoerzen@complete.org>
|
# <jgoerzen@complete.org>
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# This program is free software; you can redistribute it and/or modify
|
||||||
@ -169,6 +169,11 @@ class MaildirFolder(BaseFolder):
|
|||||||
ui.debug('maildir', 'savemessage: using temporary name %s' % tmpmessagename)
|
ui.debug('maildir', 'savemessage: using temporary name %s' % tmpmessagename)
|
||||||
file = open(os.path.join(tmpdir, tmpmessagename), "wt")
|
file = open(os.path.join(tmpdir, tmpmessagename), "wt")
|
||||||
file.write(content)
|
file.write(content)
|
||||||
|
|
||||||
|
# Make sure the data hits the disk
|
||||||
|
file.flush()
|
||||||
|
os.fsync(file.fileno())
|
||||||
|
|
||||||
file.close()
|
file.close()
|
||||||
if rtime != None:
|
if rtime != None:
|
||||||
os.utime(os.path.join(tmpdir,tmpmessagename), (rtime,rtime))
|
os.utime(os.path.join(tmpdir,tmpmessagename), (rtime,rtime))
|
||||||
@ -177,6 +182,15 @@ class MaildirFolder(BaseFolder):
|
|||||||
os.link(os.path.join(tmpdir, tmpmessagename),
|
os.link(os.path.join(tmpdir, tmpmessagename),
|
||||||
os.path.join(newdir, messagename))
|
os.path.join(newdir, messagename))
|
||||||
os.unlink(os.path.join(tmpdir, tmpmessagename))
|
os.unlink(os.path.join(tmpdir, tmpmessagename))
|
||||||
|
|
||||||
|
try:
|
||||||
|
# fsync the directory (safer semantics in Linux)
|
||||||
|
fd = os.open(newdir, os.O_RDONLY)
|
||||||
|
os.fsync(fd)
|
||||||
|
os.close(fd)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
self.messagelist[uid] = {'uid': uid, 'flags': [],
|
self.messagelist[uid] = {'uid': uid, 'flags': [],
|
||||||
'filename': os.path.join(newdir, messagename)}
|
'filename': os.path.join(newdir, messagename)}
|
||||||
self.savemessageflags(uid, flags)
|
self.savemessageflags(uid, flags)
|
||||||
|
Loading…
Reference in New Issue
Block a user