Mercurial > dovecot > original-hg > dovecot-1.2
changeset 6811:9bc620b934f4 HEAD
Added nfs_safe_link().
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 15 Nov 2007 16:27:41 +0200 |
parents | a4c87d5d881c |
children | ebe88bc73154 |
files | src/lib/nfs-workarounds.c src/lib/nfs-workarounds.h |
diffstat | 2 files changed, 32 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- 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 @@ 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;
--- 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 @@ 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. */