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