changeset 8476:9bcc2dd5f17f HEAD

Linux/Solaris NFS: if there are no locks, try flushing data cache by flushing attr cache.
author Timo Sirainen <tss@iki.fi>
date Fri, 21 Nov 2008 22:57:50 +0200
parents b64fb26e3b6f
children c033b3e2d9b6
files src/lib/nfs-workarounds.c
diffstat 1 files changed, 13 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/nfs-workarounds.c	Fri Nov 21 22:40:48 2008 +0200
+++ b/src/lib/nfs-workarounds.c	Fri Nov 21 22:57:50 2008 +0200
@@ -214,11 +214,15 @@
 #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 @@
 	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_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