From 542af5714d761e787276111ca8bf7a5c69afb721 Mon Sep 17 00:00:00 2001 From: Poornima G Date: Tue, 16 Jan 2018 14:14:39 +0530 Subject: protocol: Implement put fop Updates #353 Change-Id: I755b9208690be76935d763688fa414521eba3a40 Signed-off-by: Poornima G --- xlators/protocol/client/src/client-common.c | 35 +++++++ xlators/protocol/client/src/client-common.h | 5 + xlators/protocol/client/src/client-rpc-fops_v2.c | 121 +++++++++++++++++++++++ xlators/protocol/client/src/client.c | 40 ++++++++ 4 files changed, 201 insertions(+) (limited to 'xlators/protocol/client/src') diff --git a/xlators/protocol/client/src/client-common.c b/xlators/protocol/client/src/client-common.c index 3b4dea1aff1..2a08ce2e0ab 100644 --- a/xlators/protocol/client/src/client-common.c +++ b/xlators/protocol/client/src/client-common.c @@ -3522,6 +3522,41 @@ out: return -op_errno; } +int +client_pre_put_v2 (xlator_t *this, gfx_put_req *req, loc_t *loc, mode_t mode, + mode_t umask, int32_t flags, size_t size, off_t offset, + dict_t *xattr, dict_t *xdata) +{ + int op_errno = ESTALE; + + if (!(loc && loc->parent)) + goto out; + + if (!gf_uuid_is_null (loc->parent->gfid)) + memcpy (req->pargfid, loc->parent->gfid, 16); + else + memcpy (req->pargfid, loc->pargfid, 16); + + GF_ASSERT_AND_GOTO_WITH_ERROR (this->name, + !gf_uuid_is_null (*((uuid_t *)req->pargfid)), + out, op_errno, EINVAL); + req->bname = (char *)loc->name; + req->mode = mode; + req->umask = umask; + req->flag = gf_flags_from_flags (flags); + req->size = size; + req->offset = offset; + + if (xattr) + dict_to_xdr (xattr, &req->xattr); + + dict_to_xdr (xdata, &req->xdata); + + return 0; +out: + return -op_errno; +} + int client_post_create_v2 (xlator_t *this, gfx_create_rsp *rsp, struct iatt *stbuf, struct iatt *preparent, diff --git a/xlators/protocol/client/src/client-common.h b/xlators/protocol/client/src/client-common.h index 76ec0e9279d..b0690aa75d8 100644 --- a/xlators/protocol/client/src/client-common.h +++ b/xlators/protocol/client/src/client-common.h @@ -609,6 +609,11 @@ int client_pre_lease_v2 (xlator_t *this, gfx_lease_req *req, loc_t *loc, struct gf_lease *lease, dict_t *xdata); +int +client_pre_put_v2 (xlator_t *this, gfx_put_req *req, loc_t *loc, mode_t mode, + mode_t umask, int32_t flags, size_t size, off_t offset, + dict_t *xattr, dict_t *xdata); + int client_post_readv_v2 (xlator_t *this, gfx_read_rsp *rsp, struct iobref **iobref, struct iobref *rsp_iobref, struct iatt *stat, diff --git a/xlators/protocol/client/src/client-rpc-fops_v2.c b/xlators/protocol/client/src/client-rpc-fops_v2.c index d30d56e9929..4471825c470 100644 --- a/xlators/protocol/client/src/client-rpc-fops_v2.c +++ b/xlators/protocol/client/src/client-rpc-fops_v2.c @@ -5479,6 +5479,68 @@ client4_icreate_cbk (struct rpc_req *req, dict_unref (xdata); return 0; } + +int +client4_0_put_cbk (struct rpc_req *req, struct iovec *iov, int count, + void *myframe) +{ + gfx_common_3iatt_rsp rsp = {0,}; + call_frame_t *frame = NULL; + int ret = 0; + xlator_t *this = NULL; + dict_t *xdata = NULL; + clnt_local_t *local = NULL; + struct iatt stbuf = {0, }; + struct iatt preparent = {0, }; + struct iatt postparent = {0, }; + inode_t *inode = NULL; + + this = THIS; + + frame = myframe; + local = frame->local; + inode = local->loc.inode; + + if (-1 == req->rpc_status) { + rsp.op_ret = -1; + rsp.op_errno = ENOTCONN; + goto out; + } + + ret = xdr_to_generic (*iov, &rsp, (xdrproc_t)xdr_gfx_common_3iatt_rsp); + if (ret < 0) { + gf_msg (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 (-1 != rsp.op_ret) { + ret = client_post_common_3iatt (this, &rsp, &stbuf, &preparent, + &postparent, &xdata); + if (ret < 0) + goto out; + } +out: + if (rsp.op_ret == -1) { + gf_msg (this->name, GF_LOG_WARNING, + gf_error_to_errno (rsp.op_errno), + PC_MSG_REMOTE_OP_FAILED, + "remote operation failed"); + } + + CLIENT_STACK_UNWIND (put, frame, rsp.op_ret, + gf_error_to_errno (rsp.op_errno), inode, &stbuf, + &preparent, &postparent, xdata); + + if (xdata) + dict_unref (xdata); + + return 0; +} + int32_t client4_namelink (call_frame_t *frame, xlator_t *this, void *data) { @@ -5574,6 +5636,65 @@ client4_icreate (call_frame_t *frame, xlator_t *this, void *data) return 0; } + +int32_t +client4_0_put (call_frame_t *frame, xlator_t *this, void *data) +{ + clnt_args_t *args = NULL; + clnt_conf_t *conf = NULL; + gfx_put_req req = {{0,},}; + int op_errno = ESTALE; + int ret = 0; + clnt_local_t *local = NULL; + + if (!frame || !this || !data) + goto unwind; + + args = data; + conf = this->private; + + local = mem_get0 (this->local_pool); + if (!local) { + op_errno = ENOMEM; + goto unwind; + } + frame->local = local; + + loc_copy (&local->loc, args->loc); + loc_path (&local->loc, NULL); + + ret = client_pre_put_v2 (this, &req, args->loc, args->mode, args->umask, + args->flags, args->size, args->offset, + args->xattr, args->xdata); + + if (ret) { + op_errno = -ret; + goto unwind; + } + + ret = client_submit_vec_request (this, &req, frame, conf->fops, + GFS3_OP_PUT, client4_0_put_cbk, + args->vector, args->count, + args->iobref, + (xdrproc_t)xdr_gfx_put_req); + if (ret) { + /* + * If the lower layers fail to submit a request, they'll also + * do the unwind for us (see rpc_clnt_submit), so don't unwind + * here in such cases. + */ + gf_msg (this->name, GF_LOG_WARNING, 0, PC_MSG_FOP_SEND_FAILED, + "failed to send the fop"); + } + + return 0; + +unwind: + CLIENT_STACK_UNWIND (put, frame, -1, op_errno, NULL, NULL, NULL, NULL, + NULL); + return 0; +} + int32_t client4_0_fsetattr (call_frame_t *frame, xlator_t *this, void *data) { diff --git a/xlators/protocol/client/src/client.c b/xlators/protocol/client/src/client.c index 32d5e65cf47..b267321afbe 100644 --- a/xlators/protocol/client/src/client.c +++ b/xlators/protocol/client/src/client.c @@ -2134,6 +2134,45 @@ client_icreate (call_frame_t *frame, return 0; } +int32_t +client_put (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode, + mode_t umask, uint32_t flags, struct iovec *vector, int32_t count, + off_t off, struct iobref *iobref, dict_t *xattr, dict_t *xdata) +{ + int ret = -1; + clnt_conf_t *conf = NULL; + rpc_clnt_procedure_t *proc = NULL; + clnt_args_t args = {0,}; + + conf = this->private; + if (!conf || !conf->fops) + goto out; + + args.loc = loc; + args.mode = mode; + args.umask = umask; + args.flags = flags; + args.vector = vector; + args.count = count; + args.offset = off; + args.size = iov_length (vector, count); + args.iobref = iobref; + args.xattr = xattr; + args.xdata = xdata; + + client_filter_o_direct (conf, &args.flags); + + proc = &conf->fops->proctable[GF_FOP_PUT]; + if (proc->fn) + ret = proc->fn (frame, this, &args); +out: + if (ret) + STACK_UNWIND_STRICT (put, frame, -1, ENOTCONN, NULL, NULL, + NULL, NULL, NULL); + + return 0; +} + int client_mark_fd_bad (xlator_t *this) { @@ -2854,6 +2893,7 @@ struct xlator_fops fops = { .setactivelk = client_setactivelk, .icreate = client_icreate, .namelink = client_namelink, + .put = client_put, }; -- cgit