Mercurial > dovecot > original-hg > dovecot-1.2
changeset 4225:abdef9d86a94 HEAD
Added nfs_safe_stat() to transparently work around ESTALE with stat().
author | Timo Sirainen <timo.sirainen@movial.fi> |
---|---|
date | Tue, 25 Apr 2006 16:40:18 +0300 |
parents | 8736c4deb253 |
children | 83322a523c91 |
files | src/lib-index/mail-index.c src/lib-index/mail-transaction-log.c src/lib-storage/index/maildir/maildir-uidlist.c src/lib/nfs-workarounds.c src/lib/nfs-workarounds.h |
diffstat | 5 files changed, 52 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-index/mail-index.c Mon Apr 24 16:18:45 2006 +0300 +++ b/src/lib-index/mail-index.c Tue Apr 25 16:40:18 2006 +0300 @@ -1664,7 +1664,7 @@ } return mail_index_set_syscall_error(index, "fstat()"); } - if (stat(index->filepath, &st2) < 0) { + if (nfs_safe_stat(index->filepath, &st2) < 0) { mail_index_set_syscall_error(index, "stat()"); if (errno != ENOENT) return -1;
--- a/src/lib-index/mail-transaction-log.c Mon Apr 24 16:18:45 2006 +0300 +++ b/src/lib-index/mail-transaction-log.c Tue Apr 25 16:40:18 2006 +0300 @@ -920,7 +920,7 @@ path = t_strconcat(log->index->filepath, MAIL_TRANSACTION_LOG_SUFFIX, NULL); - if (stat(path, &st) < 0) { + if (nfs_safe_stat(path, &st) < 0) { mail_index_file_set_syscall_error(log->index, path, "stat()"); return -1; }
--- a/src/lib-storage/index/maildir/maildir-uidlist.c Mon Apr 24 16:18:45 2006 +0300 +++ b/src/lib-storage/index/maildir/maildir-uidlist.c Tue Apr 25 16:40:18 2006 +0300 @@ -375,7 +375,7 @@ int ret; if (uidlist->last_mtime != 0) { - if (stat(uidlist->fname, &st) < 0) { + if (nfs_safe_stat(uidlist->fname, &st) < 0) { if (errno != ENOENT) { mail_storage_set_critical(storage, "stat(%s) failed: %m", uidlist->fname);
--- a/src/lib/nfs-workarounds.c Mon Apr 24 16:18:45 2006 +0300 +++ b/src/lib/nfs-workarounds.c Tue Apr 25 16:40:18 2006 +0300 @@ -7,19 +7,19 @@ #include <unistd.h> #include <sys/stat.h> -int nfs_safe_open(const char *path, int flags) +static int +nfs_safe_do(const char *path, int (*callback)(const char *path, void *context), + void *context) { const char *dir = NULL; struct stat st; unsigned int i; - int fd; - - i_assert((flags & O_CREAT) == 0); + int ret; t_push(); for (i = 1;; i++) { - fd = open(path, flags); - if (fd != -1 || errno != ESTALE || i == NFS_ESTALE_RETRY_COUNT) + ret = callback(path, context); + if (ret == 0 || errno != ESTALE || i == NFS_ESTALE_RETRY_COUNT) break; /* ESTALE: Some operating systems may fail with this if they @@ -44,5 +44,43 @@ /* directory still exists, try reopening */ } t_pop(); - return fd; + return ret; +} + +struct nfs_safe_open_context { + int flags; + int fd; +}; + +static int nfs_safe_open_callback(const char *path, void *context) +{ + struct nfs_safe_open_context *ctx = context; + + ctx->fd = open(path, ctx->flags); + return ctx->fd == -1 ? -1 : 0; } + +int nfs_safe_open(const char *path, int flags) +{ + struct nfs_safe_open_context ctx; + + i_assert((flags & O_CREAT) == 0); + + ctx.flags = flags; + if (nfs_safe_do(path, nfs_safe_open_callback, &ctx) < 0) + return -1; + + return ctx.fd; +} + +static int nfs_safe_stat_callback(const char *path, void *context) +{ + struct stat *buf = context; + + return stat(path, buf); +} + +int nfs_safe_stat(const char *path, struct stat *buf) +{ + return nfs_safe_do(path, nfs_safe_stat_callback, buf); +}
--- a/src/lib/nfs-workarounds.h Mon Apr 24 16:18:45 2006 +0300 +++ b/src/lib/nfs-workarounds.h Tue Apr 25 16:40:18 2006 +0300 @@ -1,11 +1,15 @@ #ifndef __NFS_WORKAROUNDS_H #define __NFS_WORKAROUNDS_H +struct stat; + /* When syscall fails with ESTALE error, how many times to try reopening the file and retrying the operation. */ #define NFS_ESTALE_RETRY_COUNT 10 /* open() with some NFS workarounds */ int nfs_safe_open(const char *path, int flags); +/* stat() with some NFS workarounds */ +int nfs_safe_stat(const char *path, struct stat *buf); #endif