On Thu, Mar 25, 2010 at 05:25:53PM +0200, Timo Sirainen wrote: > Are you using ext4 on the Linux NFS server?
Yes: /dev/sda1 on / type ext4 (rw,errors=remount-ro) > Nano/microsecond resolution timestamps fix the worst caching problems. I can't see whether that's true through stat mtime though. I've tried adding some extra debugging but it seems a variety of situations are occurring: Mar 25 15:49:36 freebsd-dev dovecot: IMAP(br...@dev.example.com): Our dotlock file /mail/0/6/37/30/brian%dev.example.com/dovecot-uidlist.lock was deleted (kept it 1 secs) file_dotlock_delete: unlink gave ENOENT Mar 25 15:49:40 freebsd-dev dovecot: IMAP(br...@dev.example.com): Our dotlock file /mail/0/6/37/30/brian%dev.example.com/dovecot-uidlist.lock was overridden (kept it 0 secs) file_dotlock_delete: inode changed Mar 25 15:49:54 freebsd-dev dovecot: IMAP(br...@dev.example.com): dotlock /mail/0/6/37/30/brian%dev.example.com/dovecot-uidlist.lock was immediately recreated under us Mar 25 15:49:56 freebsd-dev dovecot: IMAP(br...@dev.example.com): dotlock /mail/0/6/37/30/brian%dev.example.com/dovecot-uidlist.lock was immediately recreated under us Mar 25 15:50:18 freebsd-dev dovecot: IMAP(br...@dev.example.com): Our dotlock file /mail/0/6/37/30/brian%dev.example.com/dovecot-uidlist.lock was overridden (kept it 0 secs) file_dotlock_delete: inode changed Mar 25 15:50:22 freebsd-dev dovecot: IMAP(br...@dev.example.com): dotlock /mail/0/6/37/30/brian%dev.example.com/dovecot-uidlist.lock was immediately recreated under us Mar 25 15:50:27 freebsd-dev dovecot: IMAP(br...@dev.example.com): dotlock /mail/0/6/37/30/brian%dev.example.com/dovecot-uidlist.lock was immediately recreated under us Out of interest, why is dot locking used instead of fcntl here? Regards, Brian.
--- src/lib/file-dotlock.c.orig 2010-03-25 15:40:12.000000000 +0000 +++ src/lib/file-dotlock.c 2010-03-25 15:48:17.000000000 +0000 @@ -671,7 +671,8 @@ return ret; } -static void dotlock_replaced_warning(struct dotlock *dotlock, bool deleted) +static void dotlock_replaced_warning(struct dotlock *dotlock, bool deleted, + const char *debug) { const char *lock_path; time_t now = time(NULL); @@ -679,15 +680,17 @@ lock_path = file_dotlock_get_lock_path(dotlock); if (dotlock->mtime == dotlock->lock_time) { i_warning("Our dotlock file %s was %s " - "(locked %d secs ago, touched %d secs ago)", + "(locked %d secs ago, touched %d secs ago) %s", lock_path, deleted ? "deleted" : "overridden", (int)(now - dotlock->lock_time), - (int)(now - dotlock->mtime)); + (int)(now - dotlock->mtime), + debug ? debug : ""); } else { i_warning("Our dotlock file %s was %s " - "(kept it %d secs)", lock_path, + "(kept it %d secs) %s", lock_path, deleted ? "deleted" : "overridden", - (int)(now - dotlock->lock_time)); + (int)(now - dotlock->lock_time), + debug ? debug : ""); } } @@ -703,7 +706,9 @@ lock_path = file_dotlock_get_lock_path(dotlock); if (nfs_safe_lstat(lock_path, &st) < 0) { if (errno == ENOENT) { - dotlock_replaced_warning(dotlock, TRUE); + dotlock_replaced_warning(dotlock, TRUE, + "file_dotlock_delete: " + "nfs_safe_lstat gave ENOENT"); file_dotlock_free(&dotlock); return 0; } @@ -715,7 +720,8 @@ if (dotlock->ino != st.st_ino || !CMP_DEV_T(dotlock->dev, st.st_dev)) { - dotlock_replaced_warning(dotlock, FALSE); + dotlock_replaced_warning(dotlock, FALSE, + "file_dotlock_delete: inode changed"); errno = EEXIST; file_dotlock_free(&dotlock); return 0; @@ -731,7 +737,8 @@ if (unlink(lock_path) < 0) { if (errno == ENOENT) { - dotlock_replaced_warning(dotlock, TRUE); + dotlock_replaced_warning(dotlock, TRUE, + "file_dotlock_delete: unlink gave ENOENT"); file_dotlock_free(&dotlock); return 0; } @@ -835,7 +842,8 @@ lock_path = file_dotlock_get_lock_path(dotlock); if ((flags & DOTLOCK_REPLACE_FLAG_VERIFY_OWNER) != 0 && !file_dotlock_is_locked(dotlock)) { - dotlock_replaced_warning(dotlock, FALSE); + dotlock_replaced_warning(dotlock, FALSE, + "file_dotlock_replace: FLAG_VERIFY_OWNER failed"); errno = EEXIST; file_dotlock_free(&dotlock); return 0; @@ -844,7 +852,8 @@ if (rename(lock_path, dotlock->path) < 0) { i_error("rename(%s, %s) failed: %m", lock_path, dotlock->path); if (errno == ENOENT) - dotlock_replaced_warning(dotlock, TRUE); + dotlock_replaced_warning(dotlock, TRUE, + "file_dotlock_replace: rename gave ENOENT"); file_dotlock_free(&dotlock); return -1; }