diff options
author | Shehjar Tikoo <shehjart@gluster.com> | 2009-07-17 08:48:10 +0000 |
---|---|---|
committer | Anand V. Avati <avati@dev.gluster.com> | 2009-07-17 12:01:25 -0700 |
commit | 4b3633cde1bb9a9a692eade129e4a45dbf82d8ec (patch) | |
tree | 605a6c9802a455e2f03578bf51ff512c96ceef80 /libglusterfsclient/src | |
parent | 847e02d901a5cedf4f28d34fa2431b41a07b9a2a (diff) |
libglusterfsclient: Invalidate not update iattr cache on writev
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 149 (libglusterfsclient interacts incorrectly with write-behind on writev)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=149
Diffstat (limited to 'libglusterfsclient/src')
-rwxr-xr-x | libglusterfsclient/src/libglusterfsclient-internals.h | 2 | ||||
-rwxr-xr-x | libglusterfsclient/src/libglusterfsclient.c | 48 |
2 files changed, 48 insertions, 2 deletions
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; } |