changeset 6816:8573124a89b3 HEAD

FreeBSD: Flush directory attribute caches by rmdir()ing it.
author Timo Sirainen <tss@iki.fi>
date Fri, 16 Nov 2007 05:11:42 +0200
parents c991d1b132d8
children 766250fcedd8
files src/lib/nfs-workarounds.c
diffstat 1 files changed, 35 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- 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
@@ -38,6 +38,8 @@
 #  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),
 	    void *context)
@@ -185,6 +187,29 @@
 	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 @@
 		   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 @@
 	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();
 		}
 	}