From: Timo Sirainen Date: Fri, 21 Nov 2008 20:57:50 +0000 (+0200) Subject: Linux/Solaris NFS: if there are no locks, try flushing data cache by flushing attr... X-Git-Tag: 1.2.alpha4~13 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=025c13e0dd644aa025fa02ca287581b579810042;p=thirdparty%2Fdovecot%2Fcore.git Linux/Solaris NFS: if there are no locks, try flushing data cache by flushing attr cache. --HG-- branch : HEAD --- diff --git a/src/lib/nfs-workarounds.c b/src/lib/nfs-workarounds.c index 75cf7646a1..93fc048bb5 100644 --- a/src/lib/nfs-workarounds.c +++ b/src/lib/nfs-workarounds.c @@ -214,11 +214,15 @@ static bool nfs_flush_fchown_uid(const char *path, int fd) #endif #ifdef READ_CACHE_FLUSH_FCNTL -static void nfs_flush_fcntl(const char *path, int fd) +static bool nfs_flush_fcntl(const char *path, int fd) { + static bool locks_disabled = FALSE; struct flock fl; int ret; + if (locks_disabled) + return FALSE; + /* If the file was already locked, we'll just get the same lock again. It should succeed just fine. If was was unlocked, we'll have to get a lock and then unlock it. Linux 2.6 flushes read cache @@ -233,12 +237,17 @@ static void nfs_flush_fcntl(const char *path, int fd) alarm(0); if (unlikely(ret < 0)) { + if (errno == ENOLCK) { + locks_disabled = TRUE; + return FALSE; + } i_error("nfs_flush_fcntl: fcntl(%s, F_RDLCK) failed: %m", path); - return; + return FALSE; } fl.l_type = F_UNLCK; (void)fcntl(fd, F_SETLKW, &fl); + return TRUE; } #endif @@ -376,7 +385,8 @@ void nfs_flush_read_cache_locked(const char *path ATTR_UNUSED, void nfs_flush_read_cache_unlocked(const char *path, int fd) { #ifdef READ_CACHE_FLUSH_FCNTL - nfs_flush_fcntl(path, fd); + if (!nfs_flush_fcntl(path, fd)) + nfs_flush_attr_cache_fd_locked(path, fd); #else nfs_flush_read_cache_locked(path, fd); #endif