summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShehjar Tikoo <shehjart@gluster.com>2009-07-17 08:47:32 +0000
committerAnand V. Avati <avati@dev.gluster.com>2009-07-17 12:01:29 -0700
commitdbccda35cdcad06208e2fc7554287b539e0060a6 (patch)
treebf945225eda568492119ca83235890b7fe4a3831
parentfe134d4b0b675f13f3c2aa1152a1380be7192ced (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
-rwxr-xr-xlibglusterfsclient/src/libglusterfsclient-internals.h2
-rwxr-xr-xlibglusterfsclient/src/libglusterfsclient.c48
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;
}