diff options
Diffstat (limited to 'xlators/protocol/server/src')
-rw-r--r-- | xlators/protocol/server/src/server-handshake.c | 140 | ||||
-rw-r--r-- | xlators/protocol/server/src/server-helpers.c | 9 | ||||
-rw-r--r-- | xlators/protocol/server/src/server-helpers.h | 4 | ||||
-rw-r--r-- | xlators/protocol/server/src/server-mem-types.h | 1 | ||||
-rw-r--r-- | xlators/protocol/server/src/server-resolve.c | 6 | ||||
-rw-r--r-- | xlators/protocol/server/src/server-rpc-fops.c | 6 | ||||
-rw-r--r-- | xlators/protocol/server/src/server.c | 2 | ||||
-rw-r--r-- | xlators/protocol/server/src/server.h | 2 |
8 files changed, 139 insertions, 31 deletions
diff --git a/xlators/protocol/server/src/server-handshake.c b/xlators/protocol/server/src/server-handshake.c index af079798804..77b81feddcb 100644 --- a/xlators/protocol/server/src/server-handshake.c +++ b/xlators/protocol/server/src/server-handshake.c @@ -327,12 +327,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; @@ -644,21 +722,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); @@ -677,20 +758,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"); @@ -699,8 +785,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 @@ -717,14 +803,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); diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c index 48df41c4df6..f8621be61ee 100644 --- a/xlators/protocol/server/src/server-helpers.c +++ b/xlators/protocol/server/src/server-helpers.c @@ -1220,3 +1220,12 @@ out: return ret; } + +inode_t * +server_inode_new (inode_table_t *itable, uuid_t gfid) { + if (__is_root_gfid (gfid)) + return itable->root; + else + return inode_new (itable); +} + diff --git a/xlators/protocol/server/src/server-helpers.h b/xlators/protocol/server/src/server-helpers.h index 73b01b197e0..6cc5829e7df 100644 --- a/xlators/protocol/server/src/server-helpers.h +++ b/xlators/protocol/server/src/server-helpers.h @@ -58,4 +58,8 @@ int auth_set_username_passwd (dict_t *input_params, dict_t *config_params, server_ctx_t *server_ctx_get (client_t *client, xlator_t *xlator); int server_process_event_upcall (xlator_t *this, void *data); + +inode_t * +server_inode_new (inode_table_t *itable, uuid_t gfid); + #endif /* !_SERVER_HELPERS_H */ diff --git a/xlators/protocol/server/src/server-mem-types.h b/xlators/protocol/server/src/server-mem-types.h index 19c3466d37f..9e2fcbc645f 100644 --- a/xlators/protocol/server/src/server-mem-types.h +++ b/xlators/protocol/server/src/server-mem-types.h @@ -25,6 +25,7 @@ enum gf_server_mem_types_ { gf_server_mt_rsp_buf_t, gf_server_mt_volfile_ctx_t, gf_server_mt_timer_data_t, + gf_server_mt_setvolume_rsp_t, gf_server_mt_end, }; #endif /* __SERVER_MEM_TYPES_H__ */ diff --git a/xlators/protocol/server/src/server-resolve.c b/xlators/protocol/server/src/server-resolve.c index 5f3d475c595..26bf37e3308 100644 --- a/xlators/protocol/server/src/server-resolve.c +++ b/xlators/protocol/server/src/server-resolve.c @@ -162,7 +162,8 @@ resolve_gfid_cbk (call_frame_t *frame, void *cookie, xlator_t *this, resolve_loc->name = resolve->bname; - resolve_loc->inode = inode_new (state->itable); + resolve_loc->inode = server_inode_new (state->itable, + resolve_loc->gfid); inode_path (resolve_loc->parent, resolve_loc->name, (char **) &resolve_loc->path); @@ -209,7 +210,8 @@ resolve_gfid (call_frame_t *frame) else if (!gf_uuid_is_null (resolve->gfid)) gf_uuid_copy (resolve_loc->gfid, resolve->gfid); - resolve_loc->inode = inode_new (state->itable); + resolve_loc->inode = server_inode_new (state->itable, + resolve_loc->gfid); ret = loc_path (resolve_loc, NULL); if (state->xdata) { diff --git a/xlators/protocol/server/src/server-rpc-fops.c b/xlators/protocol/server/src/server-rpc-fops.c index 77d8a51a082..67c87979e47 100644 --- a/xlators/protocol/server/src/server-rpc-fops.c +++ b/xlators/protocol/server/src/server-rpc-fops.c @@ -96,7 +96,8 @@ server_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, state->is_revalidate = 2; loc_copy (&fresh_loc, &state->loc); inode_unref (fresh_loc.inode); - fresh_loc.inode = inode_new (state->itable); + fresh_loc.inode = server_inode_new (state->itable, + fresh_loc.gfid); STACK_WIND (frame, server_lookup_cbk, frame->root->client->bound_xl, @@ -3090,7 +3091,8 @@ server_lookup_resume (call_frame_t *frame, xlator_t *bound_xl) goto err; if (!state->loc.inode) - state->loc.inode = inode_new (state->itable); + state->loc.inode = server_inode_new (state->itable, + state->loc.gfid); else state->is_revalidate = 1; diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c index 81e99801112..347a5fb5814 100644 --- a/xlators/protocol/server/src/server.c +++ b/xlators/protocol/server/src/server.c @@ -954,6 +954,8 @@ init (xlator_t *this) INIT_LIST_HEAD (&conf->xprt_list); pthread_mutex_init (&conf->mutex, NULL); + LOCK_INIT (&conf->itable_lock); + /* Set event threads to the configured default */ GF_OPTION_INIT("event-threads", conf->event_threads, int32, out); ret = server_check_event_threads (this, conf, STARTING_EVENT_THREADS, diff --git a/xlators/protocol/server/src/server.h b/xlators/protocol/server/src/server.h index 37a1367c14c..e1f3bf8bdac 100644 --- a/xlators/protocol/server/src/server.h +++ b/xlators/protocol/server/src/server.h @@ -72,6 +72,8 @@ struct server_conf { * in case if volume set options * (say *.allow | *.reject) are * tweeked */ + + gf_lock_t itable_lock; }; typedef struct server_conf server_conf_t; |