dovecot: Fixed nfs_flush_file_handle_cache() for Solaris when tr...

dovecot at dovecot.org dovecot at dovecot.org
Sat Jan 12 11:47:15 EET 2008


details:   http://hg.dovecot.org/dovecot/rev/5dda06c19eb1
changeset: 7156:5dda06c19eb1
user:      Timo Sirainen <tss at iki.fi>
date:      Sat Jan 12 11:47:12 2008 +0200
description:
Fixed nfs_flush_file_handle_cache() for Solaris when trying to flush the
current directory's cache. Now we temporarily change to parent directory so
rmdir() doesn't return EINVAL.

diffstat:

1 file changed, 40 insertions(+), 3 deletions(-)
src/lib/nfs-workarounds.c |   43 ++++++++++++++++++++++++++++++++++++++++---

diffs (68 lines):

diff -r dd64c0e649aa -r 5dda06c19eb1 src/lib/nfs-workarounds.c
--- a/src/lib/nfs-workarounds.c	Sat Jan 12 11:35:47 2008 +0200
+++ b/src/lib/nfs-workarounds.c	Sat Jan 12 11:47:12 2008 +0200
@@ -275,7 +275,8 @@ bool nfs_flush_attr_cache_fd_locked(cons
 #endif
 }
 
-static bool nfs_flush_file_handle_cache_dir(const char *path)
+static bool
+nfs_flush_file_handle_cache_dir(const char *path, bool try_parent ATTR_UNUSED)
 {
 #ifdef __linux__
 	/* chown()ing parent is the safest way to handle this */
@@ -297,6 +298,42 @@ static bool nfs_flush_file_handle_cache_
 		/* expected failures */
 	} else if (errno == ENOENT) {
 		return FALSE;
+	} else if (errno == EINVAL && try_parent) {
+		/* Solaris gives this if we're trying to rmdir() the current
+		   directory. Work around this by temporarily changing the
+		   current directory to the parent directory. */
+		char cur_path[PATH_MAX], *p;
+		int cur_dir_fd;
+		bool ret;
+
+		cur_dir_fd = open(".", O_RDONLY);
+		if (cur_dir_fd == -1) {
+			i_error("open(.) failed for: %m");
+			return TRUE;
+		}
+
+		if (getcwd(cur_path, sizeof(cur_path)) == NULL) {
+			i_error("nfs_flush_file_handle_cache_dir: "
+				"getcwd() failed");
+			(void)close(cur_dir_fd);
+			return TRUE;
+		}
+		p = strrchr(cur_path, '/');
+		if (p != NULL)
+			*p = '\0';
+		else {
+			p[0] = '/';
+			p[1] = '\0';
+		}
+		if (chdir(cur_path) < 0) {
+			i_error("nfs_flush_file_handle_cache_dir: "
+				"chdir() failed");
+		}
+		ret = nfs_flush_file_handle_cache_dir(path, FALSE);
+		if (fchdir(cur_dir_fd) < 0)
+			i_error("fchdir() failed: %m");
+		(void)close(cur_dir_fd);
+		return ret;
 	} else {
 		i_error("nfs_flush_file_handle_cache_dir: "
 			"rmdir(%s) failed: %m", path);
@@ -311,9 +348,9 @@ static void nfs_flush_file_handle_cache_
 
 	p = strrchr(path, '/');
 	if (p == NULL)
-		nfs_flush_file_handle_cache_dir(".");
+		nfs_flush_file_handle_cache_dir(".", TRUE);
 	else T_FRAME(
-		nfs_flush_file_handle_cache_dir(t_strdup_until(path, p));
+		nfs_flush_file_handle_cache_dir(t_strdup_until(path, p), TRUE);
 	);
 }
 


More information about the dovecot-cvs mailing list