summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghavendra Bhat <raghavendra@redhat.com>2015-07-14 16:16:00 +0530
committerRaghavendra G <rgowdapp@redhat.com>2015-07-15 23:13:46 -0700
commitb5c37403995b9ecfaa949088c3a09495d783bd87 (patch)
tree73f065b638db96e86138013d46b4c733f73f9069
parent431565e35afea5d99931276d3f0599473d088b8a (diff)
protocol/server: use different dict for resolving
protocol/server has to resolve the inode before continuing with any fop coming from the clients. For resolving it, server xlator was using the same dict associated with the fop. It causes problems in some situations. If a directory's inode was forgotten because of lru limit being exceeded, then when a create fop comes for an entry within that directory, server tries to resolve it. But since the parent directory's inode is not found in the inode table, it tries to do a hard resolve by doing a lookup on the parent gfid. If any xlator below server wants to get some extended attributes whenever lookup comes, then they set the new keys in the same dict that came along with the create fop. Now, the lookup of the parent succeeds and the create fop proceeds with the same dict (with extra keys present). posix xlaror creates those xattrs that are present in the dict. Thus the xattrs which were not to be present by default are also set as part of create. (Ex: bit-rot related xattrs such as bad-file, version and sign xattrs) Change-Id: I4bdad175a1d7a04a3aa36073667c556d6c260263 Signed-off-by: Raghavendra Bhat <raghavendra@redhat.com> Reviewed-on: http://review.gluster.org/11661 Reviewed-by: Vijaikumar Mallikarjuna <vmallika@redhat.com> Tested-by: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
-rw-r--r--xlators/protocol/server/src/server-resolve.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/xlators/protocol/server/src/server-resolve.c b/xlators/protocol/server/src/server-resolve.c
index aa1410e7336..91654ceb172 100644
--- a/xlators/protocol/server/src/server-resolve.c
+++ b/xlators/protocol/server/src/server-resolve.c
@@ -101,6 +101,7 @@ resolve_gfid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
server_resolve_t *resolve = NULL;
inode_t *link_inode = NULL;
loc_t *resolve_loc = NULL;
+ dict_t *dict = NULL;
state = CALL_STATE (frame);
resolve = state->resolve_now;
@@ -161,10 +162,19 @@ resolve_gfid_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
inode_path (resolve_loc->parent, resolve_loc->name,
(char **) &resolve_loc->path);
+ dict = dict_copy_with_ref (state->xdata, NULL);
+ if (!dict && state->xdata)
+ gf_msg (this->name, GF_LOG_ERROR, ENOMEM, PS_MSG_NO_MEMORY,
+ "BUG: dict allocation failed (pargfid: %s, name: %s), "
+ "still continuing", uuid_utoa (resolve_loc->gfid),
+ resolve_loc->name);
+
STACK_WIND (frame, resolve_gfid_entry_cbk,
frame->root->client->bound_xl,
frame->root->client->bound_xl->fops->lookup,
- &resolve->resolve_loc, state->xdata);
+ &resolve->resolve_loc, dict);
+ if (dict)
+ dict_unref (dict);
return 0;
out:
resolve_continue (frame);
@@ -180,6 +190,7 @@ resolve_gfid (call_frame_t *frame)
server_resolve_t *resolve = NULL;
loc_t *resolve_loc = NULL;
int ret = 0;
+ dict_t *xdata = NULL;
state = CALL_STATE (frame);
this = frame->this;
@@ -194,10 +205,21 @@ resolve_gfid (call_frame_t *frame)
resolve_loc->inode = inode_new (state->itable);
ret = loc_path (resolve_loc, NULL);
+ xdata = dict_copy_with_ref (state->xdata, NULL);
+ if (!xdata && state->xdata)
+ gf_msg (this->name, GF_LOG_ERROR, ENOMEM, PS_MSG_NO_MEMORY,
+ "BUG: dict allocation failed (gfid: %s), "
+ "still continuing",
+ uuid_utoa (resolve_loc->gfid));
+
STACK_WIND (frame, resolve_gfid_cbk,
frame->root->client->bound_xl,
frame->root->client->bound_xl->fops->lookup,
- &resolve->resolve_loc, state->xdata);
+ &resolve->resolve_loc, xdata);
+
+ if (xdata)
+ dict_unref (xdata);
+
return 0;
}