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:
		| @@ -1,5 +1,5 @@ | ||||
| # Local status cache virtual folder | ||||
| # Copyright (C) 2002 - 2003 John Goerzen | ||||
| # Copyright (C) 2002 - 2007 John Goerzen | ||||
| # <jgoerzen@complete.org> | ||||
| # | ||||
| #    This program is free software; you can redistribute it and/or modify | ||||
| @@ -90,8 +90,18 @@ class LocalStatusFolder(BaseFolder): | ||||
|                 flags.sort() | ||||
|                 flags = ''.join(flags) | ||||
|                 file.write("%s:%s\n" % (msg['uid'], flags)) | ||||
|             file.flush() | ||||
|             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 | ||||
|  | ||||
|         finally: | ||||
|             self.savelock.release() | ||||
|  | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| # Maildir folder support | ||||
| # Copyright (C) 2002 - 2006 John Goerzen | ||||
| # Copyright (C) 2002 - 2007 John Goerzen | ||||
| # <jgoerzen@complete.org> | ||||
| # | ||||
| #    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) | ||||
|         file = open(os.path.join(tmpdir, tmpmessagename), "wt") | ||||
|         file.write(content) | ||||
|  | ||||
|         # Make sure the data hits the disk | ||||
|         file.flush() | ||||
|         os.fsync(file.fileno()) | ||||
|  | ||||
|         file.close() | ||||
|         if rtime != None: | ||||
|             os.utime(os.path.join(tmpdir,tmpmessagename), (rtime,rtime)) | ||||
| @@ -177,6 +182,15 @@ class MaildirFolder(BaseFolder): | ||||
|         os.link(os.path.join(tmpdir, tmpmessagename), | ||||
|                 os.path.join(newdir, messagename)) | ||||
|         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': [], | ||||
|                                  'filename': os.path.join(newdir, messagename)} | ||||
|         self.savemessageflags(uid, flags) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 John Goerzen
					John Goerzen