diff options
Diffstat (limited to 'xlators/protocol/client/src/client-rpc-fops.c')
-rw-r--r-- | xlators/protocol/client/src/client-rpc-fops.c | 228 |
1 files changed, 228 insertions, 0 deletions
diff --git a/xlators/protocol/client/src/client-rpc-fops.c b/xlators/protocol/client/src/client-rpc-fops.c index b09c169b806..a80c9e610d8 100644 --- a/xlators/protocol/client/src/client-rpc-fops.c +++ b/xlators/protocol/client/src/client-rpc-fops.c @@ -3030,6 +3030,90 @@ client3_3_releasedir_cbk (struct rpc_req *req, struct iovec *iov, int count, } int +client3_3_compound_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfs3_compound_rsp rsp = {0,}; + compound_args_cbk_t *args_cbk = NULL; + call_frame_t *frame = NULL; + int ret = -1; + xlator_t *this = NULL; + dict_t *xdata = NULL; + clnt_local_t *local = NULL; + int op_errno = 0; + int i,length = 0; + + this = THIS; + + frame = myframe; + local = frame->local; + + if (-1 == req->rpc_status) { + op_errno = ENOTCONN; + goto out; + } + + ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfs3_compound_rsp); + if (ret < 0) { + gf_msg (this->name, GF_LOG_ERROR, EINVAL, + PC_MSG_XDR_DECODING_FAILED, "XDR decoding failed"); + op_errno = EINVAL; + goto out; + } + + args_cbk = GF_CALLOC (1, sizeof (compound_args_cbk_t), gf_mt_compound_rsp_t); + if (!args_cbk) { + op_errno = ENOMEM; + goto out; + } + + length = args_cbk->fop_length = local->length; + + args_cbk->rsp_list = GF_CALLOC (length, sizeof (default_args_cbk_t), + gf_mt_default_args_cbk_t); + if (!args_cbk->rsp_list) { + op_errno = ENOMEM; + goto out; + } + + op_errno = rsp.op_errno; + + for (i = 0; i < args_cbk->fop_length; i++) { + ret = client_process_response (frame, this, req, &rsp, + args_cbk, i); + if (ret) { + op_errno = -ret; + ret = -1; + goto out; + } + + } + + GF_PROTOCOL_DICT_UNSERIALIZE (this, xdata, (rsp.xdata.xdata_val), + (rsp.xdata.xdata_len), ret, + rsp.op_errno, out); + + ret = 0; +out: + CLIENT_STACK_UNWIND (compound, frame, ret, + gf_error_to_errno (op_errno), args_cbk, xdata); + + free (rsp.xdata.xdata_val); + + if (xdata) + dict_unref (xdata); + + if (args_cbk->rsp_list) { + for (i = 0; i < length; i++) { + args_cbk_wipe (&args_cbk->rsp_list[i]); + } + } + GF_FREE (args_cbk->rsp_list); + GF_FREE (args_cbk); + return 0; +} + +int client_fdctx_destroy (xlator_t *this, clnt_fd_ctx_t *fdctx) { clnt_conf_t *conf = NULL; @@ -5889,6 +5973,150 @@ unwind: return 0; } +/* Brief explanation of gfs3_compound_req structure : + * 1) It consists of version of compounding. + * 2) A compound-fop enum, new enum for compound fops + * 3) A 'compound_req_arrray' structure that has + * a) array len - based on the number of fops compounded + * b) compound_req_array_val - pointer to an array of compound_req's + * 4) compound_req - structure that contains: + * a) fop enum of type glusterfs_fop_t + * b) union of structures of xdr requests of all fops. + */ + +int32_t +client3_3_compound (call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_conf_t *conf = NULL; + compound_args_t *c_args = data; + default_args_t *args = NULL; + gfs3_compound_req req = {0,}; + clnt_local_t *local = NULL; + int op_errno = ENOMEM; + int ret = 0; + int i = 0; + int rsp_count = 0; + struct iovec rsp_vector[MAX_IOVEC] = {{0}, }; + struct iovec req_vector[MAX_IOVEC] = {{0}, }; + struct iovec vector[MAX_IOVEC] = {{0}, }; + struct iovec *rsphdr = NULL; + struct iobref *req_iobref = NULL; + struct iobref *rsp_iobref = NULL; + struct iobref *rsphdr_iobref = NULL; + struct iobuf *rsphdr_iobuf = NULL; + int rsphdr_count = 0; + int req_count = 0; + int index = 0; + dict_t *xdata = c_args->xdata; + + GF_ASSERT (frame); + + if (!this || !data) + goto unwind; + + memset (req_vector, 0, sizeof (req_vector)); + memset (rsp_vector, 0, sizeof (rsp_vector)); + + conf = this->private; + + local = mem_get0 (this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + frame->local = local; + + local->length = c_args->fop_length; + local->compound_args = c_args; + + rsphdr_iobref = iobref_new (); + if (rsphdr_iobref == NULL) { + goto unwind; + } + + /* TODO: what is the size we should send ? */ + rsphdr_iobuf = iobuf_get (this->ctx->iobuf_pool); + if (rsphdr_iobuf == NULL) { + goto unwind; + } + + iobref_add (rsphdr_iobref, rsphdr_iobuf); + iobuf_unref (rsphdr_iobuf); + rsphdr = &vector[0]; + rsphdr->iov_base = iobuf_ptr (rsphdr_iobuf); + rsphdr->iov_len = iobuf_pagesize (rsphdr_iobuf); + rsphdr_count = 1; + local->iobref = rsp_iobref; + rsphdr_iobuf = NULL; + rsphdr_iobref = NULL; + + req.compound_fop_enum = c_args->fop_enum; + req.compound_req_array.compound_req_array_len = c_args->fop_length; + /*TODO : Talk to Sowmya about this */ + req.compound_version = 0; + if (xdata) { + GF_PROTOCOL_DICT_SERIALIZE (this, xdata, + (&req.xdata.xdata_val), + req.xdata.xdata_len, + op_errno, unwind); + } + + req.compound_req_array.compound_req_array_val = GF_CALLOC (local->length, + sizeof (compound_req), + gf_client_mt_compound_req_t); + + if (!req.compound_req_array.compound_req_array_val) { + op_errno = ENOMEM; + goto unwind; + } + + for (i = 0; i < local->length; i++) { + ret = client_handle_fop_requirements (this, frame, + &req, local, + req_iobref, rsp_iobref, + req_vector, + rsp_vector, &req_count, + &rsp_count, + &c_args->req_list[i], + c_args->enum_list[i], + index); + if (ret) { + op_errno = ret; + goto unwind; + } + index++; + } + + local->iobref2 = rsp_iobref; + rsp_iobref = NULL; + + ret = client_submit_compound_request (this, &req, frame, conf->fops, + GFS3_OP_COMPOUND, client3_3_compound_cbk, + req_vector, req_count, local->iobref, + rsphdr, rsphdr_count, + rsp_vector, rsp_count, + local->iobref2, + (xdrproc_t) xdr_gfs3_compound_req); + + GF_FREE (req.xdata.xdata_val); + + compound_request_cleanup (&req); + return 0; +unwind: + CLIENT_STACK_UNWIND (compound, frame, -1, op_errno, NULL, NULL); + + if (rsp_iobref) + iobref_unref (rsp_iobref); + + if (rsphdr_iobref) + iobref_unref (rsphdr_iobref); + + GF_FREE (req.xdata.xdata_val); + + compound_request_cleanup (&req); + return 0; +} + /* Table Specific to FOPS */ |