summaryrefslogtreecommitdiffstats
path: root/xlators/protocol/client/src/client-handshake.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/protocol/client/src/client-handshake.c')
-rw-r--r--xlators/protocol/client/src/client-handshake.c264
1 files changed, 261 insertions, 3 deletions
diff --git a/xlators/protocol/client/src/client-handshake.c b/xlators/protocol/client/src/client-handshake.c
index fe6e923c077..def95c15cf9 100644
--- a/xlators/protocol/client/src/client-handshake.c
+++ b/xlators/protocol/client/src/client-handshake.c
@@ -655,6 +655,257 @@ protocol_client_reopen (clnt_fd_ctx_t *fdctx, xlator_t *this)
protocol_client_reopenfile (fdctx, this);
}
+/* v4.x + */
+int
+client4_0_reopen_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ int32_t ret = -1;
+ gfx_open_rsp rsp = {0,};
+ clnt_local_t *local = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ call_frame_t *frame = NULL;
+ xlator_t *this = NULL;
+
+ frame = myframe;
+ this = frame->this;
+ local = frame->local;
+ fdctx = local->fdctx;
+
+ if (-1 == req->rpc_status) {
+ gf_msg (frame->this->name, GF_LOG_WARNING, ENOTCONN,
+ PC_MSG_RPC_STATUS_ERROR, "received RPC status error, "
+ "returning ENOTCONN");
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfx_open_rsp);
+ if (ret < 0) {
+ gf_msg (frame->this->name, GF_LOG_ERROR, EINVAL,
+ PC_MSG_XDR_DECODING_FAILED, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (rsp.op_ret < 0) {
+ gf_msg (frame->this->name, GF_LOG_WARNING, rsp.op_errno,
+ PC_MSG_DIR_OP_SUCCESS, "reopen on %s failed.",
+ local->loc.path);
+ } else {
+ gf_msg_debug (frame->this->name, 0,
+ "reopen on %s succeeded (remote-fd = %"PRId64")",
+ local->loc.path, rsp.fd);
+ }
+
+ if (rsp.op_ret == -1) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ fdctx->reopen_done (fdctx, (rsp.op_ret) ? -1 : rsp.fd, this);
+
+ frame->local = NULL;
+ STACK_DESTROY (frame->root);
+
+ client_local_wipe (local);
+
+ return 0;
+}
+
+int
+client4_0_reopendir_cbk (struct rpc_req *req, struct iovec *iov, int count,
+ void *myframe)
+{
+ int32_t ret = -1;
+ gfx_open_rsp rsp = {0,};
+ clnt_local_t *local = NULL;
+ clnt_fd_ctx_t *fdctx = NULL;
+ call_frame_t *frame = NULL;
+
+ frame = myframe;
+ local = frame->local;
+ fdctx = local->fdctx;
+
+ if (-1 == req->rpc_status) {
+ gf_msg (frame->this->name, GF_LOG_WARNING, ENOTCONN,
+ PC_MSG_RPC_STATUS_ERROR, "received RPC status error, "
+ "returning ENOTCONN");
+ rsp.op_ret = -1;
+ rsp.op_errno = ENOTCONN;
+ goto out;
+ }
+
+ ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfx_open_rsp);
+ if (ret < 0) {
+ gf_msg (frame->this->name, GF_LOG_ERROR, EINVAL,
+ PC_MSG_XDR_DECODING_FAILED, "XDR decoding failed");
+ rsp.op_ret = -1;
+ rsp.op_errno = EINVAL;
+ goto out;
+ }
+
+ if (rsp.op_ret < 0) {
+ gf_msg (frame->this->name, GF_LOG_WARNING, rsp.op_errno,
+ PC_MSG_DIR_OP_FAILED, "reopendir on %s failed",
+ local->loc.path);
+ } else {
+ gf_msg (frame->this->name, GF_LOG_INFO, 0,
+ PC_MSG_DIR_OP_SUCCESS, "reopendir on %s succeeded "
+ "(fd = %"PRId64")", local->loc.path, rsp.fd);
+ }
+
+ if (-1 == rsp.op_ret) {
+ ret = -1;
+ goto out;
+ }
+
+out:
+ fdctx->reopen_done (fdctx, (rsp.op_ret) ? -1 : rsp.fd, frame->this);
+
+ frame->local = NULL;
+ STACK_DESTROY (frame->root);
+ client_local_wipe (local);
+
+ return 0;
+}
+
+static int
+protocol_client_reopendir_v2 (clnt_fd_ctx_t *fdctx, xlator_t *this)
+{
+ int ret = -1;
+ gfx_opendir_req req = {{0,},};
+ clnt_local_t *local = NULL;
+ call_frame_t *frame = NULL;
+ clnt_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ local = mem_get0 (this->local_pool);
+ if (!local) {
+ ret = -1;
+ goto out;
+ }
+ local->fdctx = fdctx;
+
+ gf_uuid_copy (local->loc.gfid, fdctx->gfid);
+ ret = loc_path (&local->loc, NULL);
+ if (ret < 0)
+ goto out;
+
+ frame = create_frame (this, this->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
+
+ memcpy (req.gfid, fdctx->gfid, 16);
+
+ gf_msg_debug (frame->this->name, 0,
+ "attempting reopen on %s", local->loc.path);
+
+ frame->local = local;
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_OPENDIR,
+ client4_0_reopendir_cbk, NULL,
+ NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfx_opendir_req);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0, PC_MSG_DIR_OP_FAILED,
+ "failed to send the re-opendir request");
+ }
+
+ return 0;
+
+out:
+ if (local)
+ client_local_wipe (local);
+
+ fdctx->reopen_done (fdctx, fdctx->remote_fd, this);
+
+ return 0;
+
+}
+
+static int
+protocol_client_reopenfile_v2 (clnt_fd_ctx_t *fdctx, xlator_t *this)
+{
+ int ret = -1;
+ gfx_open_req req = {{0,},};
+ clnt_local_t *local = NULL;
+ call_frame_t *frame = NULL;
+ clnt_conf_t *conf = NULL;
+
+ conf = this->private;
+
+ frame = create_frame (this, this->ctx->pool);
+ if (!frame) {
+ ret = -1;
+ goto out;
+ }
+
+ local = mem_get0 (this->local_pool);
+ if (!local) {
+ ret = -1;
+ goto out;
+ }
+
+ local->fdctx = fdctx;
+ gf_uuid_copy (local->loc.gfid, fdctx->gfid);
+ ret = loc_path (&local->loc, NULL);
+ if (ret < 0)
+ goto out;
+
+ frame->local = local;
+
+ memcpy (req.gfid, fdctx->gfid, 16);
+ req.flags = gf_flags_from_flags (fdctx->flags);
+ req.flags = req.flags & (~(O_TRUNC|O_CREAT|O_EXCL));
+
+ gf_msg_debug (frame->this->name, 0,
+ "attempting reopen on %s", local->loc.path);
+
+ ret = client_submit_request (this, &req, frame, conf->fops,
+ GFS3_OP_OPEN, client4_0_reopen_cbk, NULL,
+ NULL, 0, NULL, 0, NULL,
+ (xdrproc_t)xdr_gfx_open_req);
+ if (ret) {
+ gf_msg (this->name, GF_LOG_ERROR, 0, PC_MSG_DIR_OP_FAILED,
+ "failed to send the re-open request");
+ }
+
+ return 0;
+
+out:
+ if (frame) {
+ frame->local = NULL;
+ STACK_DESTROY (frame->root);
+ }
+
+ if (local)
+ client_local_wipe (local);
+
+ fdctx->reopen_done (fdctx, fdctx->remote_fd, this);
+
+ return 0;
+
+}
+
+static void
+protocol_client_reopen_v2 (clnt_fd_ctx_t *fdctx, xlator_t *this)
+{
+ if (fdctx->is_dir)
+ protocol_client_reopendir_v2 (fdctx, this);
+ else
+ protocol_client_reopenfile_v2 (fdctx, this);
+}
+
gf_boolean_t
__is_fd_reopen_in_progress (clnt_fd_ctx_t *fdctx)
{
@@ -695,8 +946,12 @@ client_attempt_reopen (fd_t *fd, xlator_t *this)
}
unlock:
pthread_spin_unlock (&conf->fd_lock);
- if (reopen)
- protocol_client_reopen (fdctx, this);
+ if (reopen) {
+ if (conf->fops->progver == GLUSTER_FOP_VERSION_v2)
+ protocol_client_reopen_v2 (fdctx, this);
+ else
+ protocol_client_reopen (fdctx, this);
+ }
out:
return;
}
@@ -743,7 +998,10 @@ client_post_handshake (call_frame_t *frame, xlator_t *this)
list_for_each_entry_safe (fdctx, tmp, &reopen_head, sfd_pos) {
list_del_init (&fdctx->sfd_pos);
- protocol_client_reopen (fdctx, this);
+ if (conf->fops->progver == GLUSTER_FOP_VERSION_v2)
+ protocol_client_reopen_v2 (fdctx, this);
+ else
+ protocol_client_reopen (fdctx, this);
}
} else {
gf_msg_debug (this->name, 0,