dovecot: Added nfs_safe_link().
dovecot at dovecot.org
dovecot at dovecot.org
Thu Nov 15 16:28:11 EET 2007
details: http://hg.dovecot.org/dovecot/rev/9bc620b934f4
changeset: 6811:9bc620b934f4
user: Timo Sirainen <tss at iki.fi>
date: Thu Nov 15 16:27:41 2007 +0200
description:
Added nfs_safe_link().
diffstat:
2 files changed, 32 insertions(+)
src/lib/nfs-workarounds.c | 29 +++++++++++++++++++++++++++++
src/lib/nfs-workarounds.h | 3 +++
diffs (52 lines):
diff -r a4c87d5d881c -r 9bc620b934f4 src/lib/nfs-workarounds.c
--- a/src/lib/nfs-workarounds.c Thu Nov 15 15:01:27 2007 +0200
+++ b/src/lib/nfs-workarounds.c Thu Nov 15 16:27:41 2007 +0200
@@ -129,6 +129,35 @@ int nfs_safe_lstat(const char *path, str
return nfs_safe_do(path, nfs_safe_lstat_callback, buf);
}
+int nfs_safe_link(const char *oldpath, const char *newpath)
+{
+ struct stat st;
+
+#ifdef DEBUG
+ if (stat(oldpath, &st) == 0 && st.st_nlink != 1) {
+ i_panic("nfs_safe_link(): %s link count = %d",
+ oldpath, (int)st.st_nlink);
+ }
+#endif
+ if (link(oldpath, newpath) == 0) {
+#ifndef __FreeBSD__
+ return 0;
+#endif
+ /* FreeBSD at least up to v6.2 converts EEXIST errors to
+ success. */
+ } else if (errno != EEXIST)
+ return -1;
+
+ /* We don't know if it succeeded or failed. stat() to make sure. */
+ if (stat(oldpath, &st) < 0)
+ return -1;
+ if (st.st_nlink < 2) {
+ errno = EEXIST;
+ return -1;
+ }
+ return 0;
+}
+
static bool nfs_flush_fchown_uid(const char *path, int fd)
{
struct stat st;
diff -r a4c87d5d881c -r 9bc620b934f4 src/lib/nfs-workarounds.h
--- a/src/lib/nfs-workarounds.h Thu Nov 15 15:01:27 2007 +0200
+++ b/src/lib/nfs-workarounds.h Thu Nov 15 16:27:41 2007 +0200
@@ -14,6 +14,9 @@ int nfs_safe_open(const char *path, int
Doesn't flush attribute cache. */
int nfs_safe_stat(const char *path, struct stat *buf);
int nfs_safe_lstat(const char *path, struct stat *buf);
+/* Same as link(), but handle UDP retries by stat()ing to see if the success
+ reply just got lost. Assumes that oldpath's link count is initially 1. */
+int nfs_safe_link(const char *oldpath, const char *newpath);
/* Flush attribute cache for given path. If flush_dir is TRUE, also the
directory's cache is flushed. */
More information about the dovecot-cvs
mailing list