dovecot: FreeBSD: Flush directory attribute caches by rmdir()ing...

dovecot at dovecot.org dovecot at dovecot.org
Fri Nov 16 05:11:45 EET 2007


details:   http://hg.dovecot.org/dovecot/rev/8573124a89b3
changeset: 6816:8573124a89b3
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Nov 16 05:11:42 2007 +0200
description:
FreeBSD: Flush directory attribute caches by rmdir()ing it.

diffstat:

1 file changed, 35 insertions(+), 2 deletions(-)
src/lib/nfs-workarounds.c |   37 +++++++++++++++++++++++++++++++++++--

diffs (70 lines):

diff -r c991d1b132d8 -r 8573124a89b3 src/lib/nfs-workarounds.c
--- a/src/lib/nfs-workarounds.c	Fri Nov 16 04:45:53 2007 +0200
+++ b/src/lib/nfs-workarounds.c	Fri Nov 16 05:11:42 2007 +0200
@@ -37,6 +37,8 @@
 #ifdef __linux__
 #  define READ_CACHE_FLUSH_FCNTL
 #endif
+
+static void nfs_flush_chown_uid(const char *path);
 
 static int
 nfs_safe_do(const char *path, int (*callback)(const char *path, void *context),
@@ -185,6 +187,29 @@ static bool nfs_flush_fchown_uid(const c
 	return TRUE;
 }
 
+static void nfs_flush_dir(const char *path)
+{
+#ifdef __FreeBSD__
+	/* Unfortunately rmdir() seems to be the only way to flush a
+	   directory's attribute cache. */
+	if (rmdir(path) == 0) {
+		if (mkdir(path, 0600) == 0) {
+			i_warning("nfs_flush_dir: rmdir(%s) unexpectedly "
+				  "removed the dir. recreated.", path);
+		} else {
+			i_error("nfs_flush_dir: rmdir(%s) unexpectedly "
+				"removed the dir. mkdir() failed: %m", path);
+		}
+	} else if (errno == ESTALE || errno == ENOENT || errno == ENOTEMPTY) {
+		/* expected failures */
+	} else {
+		i_error("nfs_flush_dir: rmdir(%s) failed: %m", path);
+	}
+#else
+	nfs_flush_chown_uid(path);
+#endif
+}
+
 static void nfs_flush_chown_uid(const char *path)
 {
 	struct stat st;
@@ -206,6 +231,14 @@ static void nfs_flush_chown_uid(const ch
 		   change it anyway */
 		st.st_uid = geteuid();
 	}
+#ifdef __FreeBSD__
+	if (S_ISDIR(st.st_mode)) {
+		nfs_flush_dir(path);
+		return;
+	}
+#endif
+
+
 	if (chown(path, st.st_uid, (gid_t)-1) < 0) {
 		if (errno == ESTALE || errno == EACCES ||
 		    errno == EPERM || errno == ENOENT) {
@@ -254,10 +287,10 @@ void nfs_flush_attr_cache(const char *pa
 	if (flush_dir) {
 		p = strrchr(path, '/');
 		if (p == NULL)
-			nfs_flush_chown_uid(".");
+			nfs_flush_dir(".");
 		else {
 			t_push();
-			nfs_flush_chown_uid(t_strdup_until(path, p));
+			nfs_flush_dir(t_strdup_until(path, p));
 			t_pop();
 		}
 	}


More information about the dovecot-cvs mailing list