[dovecot-cvs] dovecot/src/lib-storage/index/maildir maildir-sync.c, 1.97, 1.98
tss at dovecot.org
tss at dovecot.org
Sat Mar 24 02:49:25 EET 2007
Update of /var/lib/cvs/dovecot/src/lib-storage/index/maildir
In directory talvi:/tmp/cvs-serv31674
Modified Files:
maildir-sync.c
Log Message:
comment/duplicate link handling fixes.
Index: maildir-sync.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib-storage/index/maildir/maildir-sync.c,v
retrieving revision 1.97
retrieving revision 1.98
diff -u -d -r1.97 -r1.98
--- maildir-sync.c 23 Mar 2007 17:20:24 -0000 1.97
+++ maildir-sync.c 24 Mar 2007 00:49:23 -0000 1.98
@@ -204,8 +204,8 @@
to see if we need to touch the uidlist lock. */
#define MAILDIR_SLOW_CHECK_COUNT 10000
-/* This is mostly to avoid infinite looping when filesystem breaks itself by
- making rename() not unlink the source file (ext3, Linux 2.6.20) */
+/* This is mostly to avoid infinite looping when rename() destination already
+ exists as the hard link of the file itself. */
#define MAILDIR_SCAN_DIR_MAX_COUNT 5
struct maildir_sync_context {
@@ -692,8 +692,7 @@
struct maildir_mailbox *mbox = ctx->mbox;
const char *existing_fname, *existing_path;
const char *new_fname, *old_path, *new_path;
- struct stat ex_st, old_st, ex2_st, old2_st;
- bool delete_old;
+ struct stat ex_st, old_st;
int ret = 0;
existing_fname =
@@ -715,60 +714,17 @@
}
if (ex_st.st_ino == old_st.st_ino &&
CMP_DEV_T(ex_st.st_dev, old_st.st_dev)) {
- /* files are the same. this means either a race condition
+ /* Files are the same. this means either a race condition
between stat() calls, or that the files were link()ed.
- if the files really were link()ed, we want to get rid of
- them. however we can't just go directly rename() them
- because if this was a race between stat()s, we could reverse
- a flag change done by another process. so, stat again
- and hope that there wasn't another race condition changing
- the flag back.. */
- if (!(stat(existing_path, &ex2_st) == 0 &&
- stat(old_path, &old2_st) == 0 &&
-#ifdef HAVE_STAT_TV_NSEC
- ex_st.st_ctim.tv_nsec == ex2_st.st_ctim.tv_nsec &&
- old_st.st_ctim.tv_nsec == old2_st.st_ctim.tv_nsec &&
-#endif
- ex_st.st_ctime == ex2_st.st_ctime &&
- old_st.st_ctime == old2_st.st_ctime)) {
- /* changed again */
- t_pop();
- return 0;
- }
-
- /* don't unlink(), if this is a race condition after
- all we really don't want to delete the message
- accidentally.
+ There's really no easy way to handle this. If the files
+ really are duplicate links, rename()ing one on top of
+ another won't work. Then again if we unlink() one of them
+ and this was actually a race condition, we just deleted
+ a mail.
- the ctime checks are only meant to help with stat() race
- conditions. the inode is shared between links, so there's
- no way to know which filename was created later. */
- if (old_st.st_ctime != ex_st.st_ctime)
- delete_old = old_st.st_ctime < ex_st.st_ctime;
- else {
-#ifdef HAVE_STAT_TV_NSEC
- delete_old = old_st.st_ctim.tv_nsec <
- ex_st.st_ctim.tv_nsec;
-#else
- delete_old = TRUE;
-#endif
- }
- if (delete_old)
- new_path = existing_path;
- else {
- new_path = old_path;
- old_path = existing_path;
- }
- ret = rename(old_path, new_path);
- if (ret == 0) {
- i_warning("Fixed a duplicate link: %s -> %s",
- old_path, new_path);
- } else if (ret < 0 && errno != ENOENT) {
- mail_storage_set_critical(STORAGE(mbox->storage),
- "rename(%s, %s) failed: %m",
- old_path, new_path);
- }
+ So for now, just do nothing. Lets hope there aren't any
+ duplicate links in the maildir. */
t_pop();
return 0;
}
More information about the dovecot-cvs
mailing list