diff options
author | Venky Shankar <vshankar@redhat.com> | 2015-03-15 03:43:49 +0530 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2015-03-24 06:34:33 -0700 |
commit | 3c474a042aed68659fe0cfdf32e01285bde9f689 (patch) | |
tree | 6229d9f3ba8de1946182ebf1b66803563cb21d71 | |
parent | 9f5addd987861d0a3a1144d576221a7f93af0970 (diff) |
core: Add inode context merge callback
Certain translators may require to update the inode context
of an already linked inode before unwinding the call to the
client. Normally, such a case in encountered during parallel
operations when a fresh inode is chosen at call (wind) time.
In the callback path, one of inodes is successfully linked
in the inode table, thereby the other inodes being thrown
away (and the inode pointers for these calls being pointed
to the linked inode).
Translators which may have strict dependency on the correct
value in the inode context would get stale values in inode
context. This patch introduces a new callback which provides
gives translators an opportunity to "patch" their respective
inode contexts. Note that, as of now, this callback is only
invoked during create()s unwind path. Although this might
needed to be done for all dentry fops and lookup, but let
that be done as an when required (bitrot stub requires
this *only* for create()).
Change-Id: I6cd91c2af473c44d1511208060d3978e580c67a6
BUG: 1170075
Original-Author: Raghavendra Bhat <rabhat@redhat.com>
Original-Author: Venky Shankar <vshankar@redhat.com>
Signed-off-by: Venky Shankar <vshankar@redhat.com>
Reviewed-on: http://review.gluster.org/9913
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Tested-by: Vijay Bellur <vbellur@redhat.com>
-rw-r--r-- | libglusterfs/src/inode.c | 32 | ||||
-rw-r--r-- | libglusterfs/src/inode.h | 5 | ||||
-rw-r--r-- | libglusterfs/src/xlator.h | 4 | ||||
-rw-r--r-- | xlators/protocol/server/src/server-rpc-fops.c | 1 |
4 files changed, 41 insertions, 1 deletions
diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c index a8958fa3bcc..1ed897ef5ec 100644 --- a/libglusterfs/src/inode.c +++ b/libglusterfs/src/inode.c @@ -344,6 +344,38 @@ __inode_destroy (inode_t *inode) mem_put (inode); } +void +inode_ctx_merge (fd_t *fd, inode_t *inode, inode_t *linked_inode) +{ + int index = 0; + xlator_t *xl = NULL; + xlator_t *old_THIS = NULL; + + if (!fd || !inode || !linked_inode) { + gf_log_callingfn (THIS->name, GF_LOG_WARNING, "invalid inode"); + return; + } + + if (!inode->_ctx || !linked_inode->_ctx) { + gf_log_callingfn (THIS->name, GF_LOG_WARNING, + "invalid inode context"); + return; + } + + for (; index < inode->table->ctxcount; index++) { + if (inode->_ctx[index].xl_key) { + xl = (xlator_t *)(long) inode->_ctx[index].xl_key; + + old_THIS = THIS; + THIS = xl; + if (xl->cbks->ictxmerge) + xl->cbks->ictxmerge (xl, fd, + inode, linked_inode); + THIS = old_THIS; + } + } +} + static void __inode_activate (inode_t *inode) { diff --git a/libglusterfs/src/inode.h b/libglusterfs/src/inode.h index 5c550bc648b..f7ca1925aac 100644 --- a/libglusterfs/src/inode.h +++ b/libglusterfs/src/inode.h @@ -34,7 +34,7 @@ typedef struct _dentry dentry_t; #include "xlator.h" #include "iatt.h" #include "uuid.h" - +#include "fd.h" struct _inode_table { pthread_mutex_t lock; @@ -266,4 +266,7 @@ __inode_table_set_lru_limit (inode_table_t *table, uint32_t lru_limit); void inode_table_set_lru_limit (inode_table_t *table, uint32_t lru_limit); +void +inode_ctx_merge (fd_t *fd, inode_t *inode, inode_t *linked_inode); + #endif /* _INODE_H */ diff --git a/libglusterfs/src/xlator.h b/libglusterfs/src/xlator.h index 5a71ceb3f31..5a0b114d6a8 100644 --- a/libglusterfs/src/xlator.h +++ b/libglusterfs/src/xlator.h @@ -796,6 +796,9 @@ typedef int32_t (*cbk_invalidate_t)(xlator_t *this, inode_t *inode); typedef int32_t (*cbk_client_t)(xlator_t *this, client_t *client); +typedef void (*cbk_ictxmerge_t) (xlator_t *this, fd_t *fd, + inode_t *inode, inode_t *linked_inode); + struct xlator_cbks { cbk_forget_t forget; cbk_release_t release; @@ -803,6 +806,7 @@ struct xlator_cbks { cbk_invalidate_t invalidate; cbk_client_t client_destroy; cbk_client_t client_disconnect; + cbk_ictxmerge_t ictxmerge; }; typedef int32_t (*dumpop_priv_t) (xlator_t *this); diff --git a/xlators/protocol/server/src/server-rpc-fops.c b/xlators/protocol/server/src/server-rpc-fops.c index 051b9771432..024cfc0b8d6 100644 --- a/xlators/protocol/server/src/server-rpc-fops.c +++ b/xlators/protocol/server/src/server-rpc-fops.c @@ -1580,6 +1580,7 @@ server_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, -- don't do this without understanding */ + inode_ctx_merge (fd, fd->inode, link_inode); inode_unref (fd->inode); fd->inode = inode_ref (link_inode); } |