summaryrefslogtreecommitdiffstats
path: root/xlators/protocol/server/src/server-handshake.c
diff options
context:
space:
mode:
authorvmallika <vmallika@redhat.com>2016-03-29 18:34:11 +0530
committerJeff Darcy <jdarcy@redhat.com>2016-03-30 12:39:42 -0700
commit773e660de0c45221b53cf2a489f28209145475db (patch)
tree02686b942e610f362ece4e793fa637d6b0542a5f /xlators/protocol/server/src/server-handshake.c
parent48a0a38fadf9c5164869a908dcff8a951aa21b4b (diff)
server: send lookup on root inode when itable is created
* xlators like quota, marker, posix_acl can cause problems if inode-ctx are not created. sometime these xlarors may not get lookup on root inode with below cases 1) client may not send lookup on root inode (like NSR leader) 2) if the xlators on one of the bricks are not up, and client sending lookup during this time: brick can miss the lookup It is always better to make sure that there is one lookup on root. So send a first lookup when the inode table is created * When sending lookup on root, new inode is created, we need to use itable->root instead Change-Id: Iff2eeaa1a89795328833a7761789ef588f11218f BUG: 1320818 Signed-off-by: vmallika <vmallika@redhat.com> Reviewed-on: http://review.gluster.org/13837 Smoke: Gluster Build System <jenkins@build.gluster.com> CentOS-regression: Gluster Build System <jenkins@build.gluster.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Jeff Darcy <jdarcy@redhat.com>
Diffstat (limited to 'xlators/protocol/server/src/server-handshake.c')
-rw-r--r--xlators/protocol/server/src/server-handshake.c140
1 files changed, 113 insertions, 27 deletions
diff --git a/xlators/protocol/server/src/server-handshake.c b/xlators/protocol/server/src/server-handshake.c
index fe5dfbab516..771595228eb 100644
--- a/xlators/protocol/server/src/server-handshake.c
+++ b/xlators/protocol/server/src/server-handshake.c
@@ -323,12 +323,90 @@ fail:
return 0;
}
+void
+server_first_lookup_done (rpcsvc_request_t *req, gf_setvolume_rsp *rsp) {
+
+ server_submit_reply (NULL, req, rsp, NULL, 0, NULL,
+ (xdrproc_t)xdr_gf_setvolume_rsp);
+
+ GF_FREE (rsp->dict.dict_val);
+ GF_FREE (rsp);
+}
+
+
+int
+server_first_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno,
+ inode_t *inode, struct iatt *buf, dict_t *xattr,
+ struct iatt *postparent)
+{
+ rpcsvc_request_t *req = NULL;
+ gf_setvolume_rsp *rsp = NULL;
+
+ req = cookie;
+ rsp = frame->local;
+ frame->local = NULL;
+
+ if (op_ret < 0 || buf == NULL)
+ gf_log (this->name, GF_LOG_WARNING, "server first lookup failed"
+ " on root inode: %s", strerror (op_errno));
+
+ /* Ignore error from lookup, don't set
+ * failure in rsp->op_ret. lookup on a snapview-server
+ * can fail with ESTALE
+ */
+ server_first_lookup_done (req, rsp);
+
+ STACK_DESTROY (frame->root);
+
+ return 0;
+}
+
+int
+server_first_lookup (xlator_t *this, xlator_t *xl, rpcsvc_request_t *req,
+ gf_setvolume_rsp *rsp)
+{
+ call_frame_t *frame = NULL;
+ loc_t loc = {0, };
+
+ loc.path = "/";
+ loc.name = "";
+ loc.inode = xl->itable->root;
+ loc.parent = NULL;
+ gf_uuid_copy (loc.gfid, loc.inode->gfid);
+
+ frame = create_frame (this, this->ctx->pool);
+ if (!frame) {
+ gf_log ("fuse", GF_LOG_ERROR, "failed to create frame");
+ goto err;
+ }
+
+ frame->local = (void *)rsp;
+ frame->root->uid = frame->root->gid = 0;
+ frame->root->pid = -1;
+ frame->root->type = GF_OP_TYPE_FOP;
+
+ STACK_WIND_COOKIE (frame, server_first_lookup_cbk, (void *)req, xl,
+ xl->fops->lookup, &loc, NULL);
+
+ return 0;
+
+err:
+ rsp->op_ret = -1;
+ rsp->op_errno = ENOMEM;
+ server_first_lookup_done (req, rsp);
+
+ frame->local = NULL;
+ STACK_DESTROY (frame->root);
+
+ return -1;
+}
int
server_setvolume (rpcsvc_request_t *req)
{
gf_setvolume_req args = {{0,},};
- gf_setvolume_rsp rsp = {0,};
+ gf_setvolume_rsp *rsp = NULL;
client_t *client = NULL;
server_ctx_t *serv_ctx = NULL;
server_conf_t *conf = NULL;
@@ -646,21 +724,24 @@ server_setvolume (rpcsvc_request_t *req)
goto fail;
}
- if ((client->bound_xl != NULL) &&
- (ret >= 0) &&
- (client->bound_xl->itable == NULL)) {
- /* create inode table for this bound_xl, if one doesn't
- already exist */
+ LOCK (&conf->itable_lock);
+ {
+ if (client->bound_xl->itable == NULL) {
+ /* create inode table for this bound_xl, if one doesn't
+ already exist */
- gf_msg_trace (this->name, 0, "creating inode table with "
- "lru_limit=%"PRId32", xlator=%s",
- conf->inode_lru_limit, client->bound_xl->name);
+ gf_msg_trace (this->name, 0, "creating inode table with"
+ " lru_limit=%"PRId32", xlator=%s",
+ conf->inode_lru_limit,
+ client->bound_xl->name);
- /* TODO: what is this ? */
- client->bound_xl->itable =
- inode_table_new (conf->inode_lru_limit,
- client->bound_xl);
+ /* TODO: what is this ? */
+ client->bound_xl->itable =
+ inode_table_new (conf->inode_lru_limit,
+ client->bound_xl);
+ }
}
+ UNLOCK (&conf->itable_lock);
ret = dict_set_str (reply, "process-uuid",
this->ctx->process_uuid);
@@ -679,20 +760,25 @@ server_setvolume (rpcsvc_request_t *req)
gf_msg_debug (this->name, 0, "failed to set 'transport-ptr'");
fail:
- rsp.dict.dict_len = dict_serialized_length (reply);
- if (rsp.dict.dict_len > UINT_MAX) {
+ rsp = GF_CALLOC (1, sizeof (gf_setvolume_rsp),
+ gf_server_mt_setvolume_rsp_t);
+ GF_ASSERT (rsp);
+
+ rsp->op_ret = 0;
+ rsp->dict.dict_len = dict_serialized_length (reply);
+ if (rsp->dict.dict_len > UINT_MAX) {
gf_msg_debug ("server-handshake", 0, "failed to get serialized"
" length of reply dict");
op_ret = -1;
op_errno = EINVAL;
- rsp.dict.dict_len = 0;
+ rsp->dict.dict_len = 0;
}
- if (rsp.dict.dict_len) {
- rsp.dict.dict_val = GF_CALLOC (1, rsp.dict.dict_len,
- gf_server_mt_rsp_buf_t);
- if (rsp.dict.dict_val) {
- ret = dict_serialize (reply, rsp.dict.dict_val);
+ if (rsp->dict.dict_len) {
+ rsp->dict.dict_val = GF_CALLOC (1, rsp->dict.dict_len,
+ gf_server_mt_rsp_buf_t);
+ if (rsp->dict.dict_val) {
+ ret = dict_serialize (reply, rsp->dict.dict_val);
if (ret < 0) {
gf_msg_debug ("server-handshake", 0, "failed "
"to serialize reply dict");
@@ -701,8 +787,8 @@ fail:
}
}
}
- rsp.op_ret = op_ret;
- rsp.op_errno = gf_errno_to_error (op_errno);
+ rsp->op_ret = op_ret;
+ rsp->op_errno = gf_errno_to_error (op_errno);
/* if bound_xl is NULL or something fails, then put the connection
* back. Otherwise the connection would have been added to the
@@ -719,14 +805,14 @@ fail:
gf_client_put (client, NULL);
req->trans->xl_private = NULL;
}
- server_submit_reply (NULL, req, &rsp, NULL, 0, NULL,
- (xdrproc_t)xdr_gf_setvolume_rsp);
+ if (op_ret >= 0 && client->bound_xl->itable)
+ server_first_lookup (this, client->bound_xl, req, rsp);
+ else
+ server_first_lookup_done (req, rsp);
free (args.dict.dict_val);
- GF_FREE (rsp.dict.dict_val);
-
dict_unref (params);
dict_unref (reply);
dict_unref (config_params);