Mercurial > dovecot > original-hg > dovecot-1.2
changeset 7156:5dda06c19eb1 HEAD
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.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Sat, 12 Jan 2008 11:47:12 +0200 |
parents | dd64c0e649aa |
children | 0c1d5a814368 |
files | src/lib/nfs-workarounds.c |
diffstat | 1 files changed, 40 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- 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 @@ #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 @@ /* 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 @@ 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); ); }