From 4b3633cde1bb9a9a692eade129e4a45dbf82d8ec Mon Sep 17 00:00:00 2001 From: Shehjar Tikoo Date: Fri, 17 Jul 2009 08:48:10 +0000 Subject: libglusterfsclient: Invalidate not update iattr cache on writev Signed-off-by: Anand V. Avati BUG: 149 (libglusterfsclient interacts incorrectly with write-behind on writev) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=149 --- .../src/libglusterfsclient-internals.h | 2 + libglusterfsclient/src/libglusterfsclient.c | 48 +++++++++++++++++++++- 2 files changed, 48 insertions(+), 2 deletions(-) (limited to 'libglusterfsclient') diff --git a/libglusterfsclient/src/libglusterfsclient-internals.h b/libglusterfsclient/src/libglusterfsclient-internals.h index 951843ef421..3a5962a2294 100755 --- a/libglusterfsclient/src/libglusterfsclient-internals.h +++ b/libglusterfsclient/src/libglusterfsclient-internals.h @@ -280,6 +280,8 @@ struct vmp_entry { #define LIBGF_VALIDATE_LOOKUP 0x1 #define LIBGF_VALIDATE_STAT 0x2 +#define LIBGF_INVALIDATE_LOOKUP 0x1 +#define LIBGF_INVALIDATE_STAT 0x2 int libgf_is_iattr_cache_valid (libglusterfs_client_ctx_t *ctx, inode_t *inode, struct stat *sbuf, int flags); diff --git a/libglusterfsclient/src/libglusterfsclient.c b/libglusterfsclient/src/libglusterfsclient.c index 1cb66ab280e..6ff6f243f21 100755 --- a/libglusterfsclient/src/libglusterfsclient.c +++ b/libglusterfsclient/src/libglusterfsclient.c @@ -502,6 +502,34 @@ out: return op_ret; } + +int +libgf_invalidate_iattr_cache (inode_t *inode, int flags) +{ + libglusterfs_client_inode_ctx_t *ictx = NULL; + + if (!inode) + return -1; + + ictx = libgf_get_inode_ctx (inode); + if (!ictx) + return -1; + + pthread_mutex_lock (&ictx->lock); + { + if (flags & LIBGF_INVALIDATE_LOOKUP) + ictx->previous_lookup_time = 0; + + if (flags & LIBGF_INVALIDATE_STAT) + ictx->previous_stat_time = 0; + + } + pthread_mutex_unlock (&ictx->lock); + + return 0; +} + + int libgf_is_iattr_cache_valid (libglusterfs_client_ctx_t *ctx, inode_t *inode, struct stat *sbuf, int flags) @@ -527,7 +555,19 @@ libgf_is_iattr_cache_valid (libglusterfs_client_ctx_t *ctx, inode_t *inode, timeout = ctx->stat_timeout; } - /* Cache infinely */ + /* Even if the timeout is set to -1 to cache + * infinitely, fops like write must invalidate the + * stat cache because writev_cbk cannot update + * the cache using the stat returned to it. This is + * because write-behind can return a stat bufs filled + * with zeroes. + */ + if (prev == 0) { + cache_valid = 0; + goto iattr_unlock_out; + } + + /* Cache infinitely */ if (timeout == (time_t)-1) { cache_valid = 1; goto iattr_unlock_out; @@ -3375,7 +3415,11 @@ libgf_client_writev_cbk (call_frame_t *frame, local->reply_stub = fop_writev_cbk_stub (frame, NULL, op_ret, op_errno, stbuf); - libgf_update_iattr_cache (local->fd->inode, LIBGF_UPDATE_STAT, stbuf); + + /* We need to invalidate because it is possible that write-behind + * is a translator below us and returns a stat filled with zeroes. + */ + libgf_invalidate_iattr_cache (local->fd->inode, LIBGF_UPDATE_STAT); LIBGF_REPLY_NOTIFY (local); return 0; } -- cgit