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