Mercurial > dovecot > original-hg > dovecot-1.2
diff src/lib/nfs-workarounds.c @ 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 | cd3d26cf124a |
children | 885ed4d5c51d |
line wrap: on
line diff
--- 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); +}