diff options
-rw-r--r-- | rpc/rpc-lib/src/protocol-common.h | 1 | ||||
-rw-r--r-- | rpc/xdr/src/glusterfs4-xdr.x | 12 | ||||
-rw-r--r-- | rpc/xdr/src/libgfxdr.sym | 1 | ||||
-rw-r--r-- | xlators/protocol/client/src/client-common.c | 35 | ||||
-rw-r--r-- | xlators/protocol/client/src/client-common.h | 5 | ||||
-rw-r--r-- | xlators/protocol/client/src/client-rpc-fops_v2.c | 121 | ||||
-rw-r--r-- | xlators/protocol/client/src/client.c | 40 | ||||
-rw-r--r-- | xlators/protocol/server/src/server-messages.h | 3 | ||||
-rw-r--r-- | xlators/protocol/server/src/server-rpc-fops_v2.c | 139 |
9 files changed, 356 insertions, 1 deletions
diff --git a/rpc/rpc-lib/src/protocol-common.h b/rpc/rpc-lib/src/protocol-common.h index aafd94400c6..e922c890854 100644 --- a/rpc/rpc-lib/src/protocol-common.h +++ b/rpc/rpc-lib/src/protocol-common.h @@ -67,6 +67,7 @@ enum gf_fop_procnum { GFS3_OP_SETACTIVELK, GFS3_OP_ICREATE, GFS3_OP_NAMELINK, + GFS3_OP_PUT, GFS3_OP_MAXVALUE, }; diff --git a/rpc/xdr/src/glusterfs4-xdr.x b/rpc/xdr/src/glusterfs4-xdr.x index bf92c8db9de..5ee86c24a0b 100644 --- a/rpc/xdr/src/glusterfs4-xdr.x +++ b/rpc/xdr/src/glusterfs4-xdr.x @@ -153,6 +153,18 @@ struct gfx_icreate_req { gfx_dict xdata; }; +struct gfx_put_req { + opaque pargfid[16]; + string bname<>; + unsigned int mode; + unsigned int umask; + unsigned int flag; + u_quad_t offset; + unsigned int size; + gfx_dict xattr; + gfx_dict xdata; +}; + struct gfx_namelink_req { opaque pargfid[16]; string bname<>; diff --git a/rpc/xdr/src/libgfxdr.sym b/rpc/xdr/src/libgfxdr.sym index 89fc513eda7..bd9131be7c6 100644 --- a/rpc/xdr/src/libgfxdr.sym +++ b/rpc/xdr/src/libgfxdr.sym @@ -339,6 +339,7 @@ xdr_gfx_getsnap_name_uuid_rsp xdr_gfx_getactivelk_rsp xdr_gfx_getactivelk_req xdr_gfx_setactivelk_req +xdr_gfx_put_req xdr_compound_req_v2 xdr_gfx_compound_req xdr_compound_rsp_v2 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 @@ -3523,6 +3523,41 @@ out: } 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, struct iatt *postparent, 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 @@ -610,6 +610,11 @@ 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, struct iovec *vector, struct iovec *rsp_vector, 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, }; diff --git a/xlators/protocol/server/src/server-messages.h b/xlators/protocol/server/src/server-messages.h index b0fb45070da..f7698806e3c 100644 --- a/xlators/protocol/server/src/server-messages.h +++ b/xlators/protocol/server/src/server-messages.h @@ -115,7 +115,8 @@ GLFS_MSGID(PS, PS_MSG_SEEK_INFO, PS_MSG_COMPOUND_INFO, PS_MSG_CLIENT_OPVERSION_GET_FAILED, - PS_MSG_CHILD_STATUS_FAILED + PS_MSG_CHILD_STATUS_FAILED, + PS_MSG_PUT_INFO ); #endif /* !_PS_MESSAGES_H__ */ diff --git a/xlators/protocol/server/src/server-rpc-fops_v2.c b/xlators/protocol/server/src/server-rpc-fops_v2.c index dca88ab85f5..2408c36ad15 100644 --- a/xlators/protocol/server/src/server-rpc-fops_v2.c +++ b/xlators/protocol/server/src/server-rpc-fops_v2.c @@ -2131,6 +2131,50 @@ out: return 0; } +int +server4_put_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, inode_t *inode, + struct iatt *stbuf, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) +{ + server_state_t *state = NULL; + rpcsvc_request_t *req = NULL; + gfx_common_3iatt_rsp rsp = {0,}; + + dict_to_xdr (xdata, &rsp.xdata); + + state = CALL_STATE (frame); + + if (op_ret < 0) { + gf_msg (this->name, GF_LOG_INFO, op_errno, PS_MSG_PUT_INFO, + "%"PRId64": PUT %s (%s/%s), client: %s, " + "error-xlator: %s", frame->root->unique, + state->loc.path, uuid_utoa (state->resolve.pargfid), + state->resolve.bname, STACK_CLIENT_NAME (frame->root), + STACK_ERR_XL_NAME (frame->root)); + goto out; + } + + gf_msg_trace (frame->root->client->bound_xl->name, 0, "%"PRId64": " + "PUT %s (%s)", frame->root->unique, state->loc.name, + uuid_utoa (stbuf->ia_gfid)); + + server4_post_common_3iatt (state, &rsp, inode, stbuf, preparent, + postparent); + +out: + rsp.op_ret = op_ret; + rsp.op_errno = gf_errno_to_error (op_errno); + + req = frame->local; + server_submit_reply (frame, req, &rsp, NULL, 0, NULL, + (xdrproc_t)xdr_gfx_common_3iatt_rsp); + + GF_FREE (rsp.xdata.pairs.pairs_val); + + return 0; +} + /* Resume function section */ int @@ -2183,6 +2227,32 @@ err: } int +server4_put_resume (call_frame_t *frame, xlator_t *bound_xl) +{ + server_state_t *state = NULL; + + state = CALL_STATE (frame); + + if (state->resolve.op_ret != 0) + goto err; + + state->loc.inode = inode_new (state->itable); + + STACK_WIND (frame, server4_put_cbk, + bound_xl, bound_xl->fops->put, + &(state->loc), state->mode, state->umask, state->flags, + state->payload_vector, state->payload_count, state->offset, + state->iobref, state->dict, state->xdata); + + return 0; +err: + server4_put_cbk (frame, NULL, frame->this, state->resolve.op_ret, + state->resolve.op_errno, NULL, NULL, NULL, + NULL, NULL); + return 0; +} + +int server4_lk_resume (call_frame_t *frame, xlator_t *bound_xl) { server_state_t *state = NULL; @@ -5678,6 +5748,75 @@ out: } int +server4_0_put (rpcsvc_request_t *req) +{ + server_state_t *state = NULL; + call_frame_t *frame = NULL; + gfx_put_req args = {{0,},}; + int ret = -1; + int op_errno = 0; + ssize_t len = 0; + int i = 0; + + if (!req) + return ret; + + args.bname = alloca (req->msg[0].iov_len); + + ret = rpc_receive_common (req, &frame, &state, &len, &args, + xdr_gfx_put_req, GF_FOP_PUT); + if (ret != 0) { + goto out; + } + + state->resolve.bname = gf_strdup (args.bname); + state->mode = args.mode; + state->umask = args.umask; + state->flags = gf_flags_to_flags (args.flag); + state->offset = args.offset; + state->size = args.size; + state->iobref = iobref_ref (req->iobref); + + if (len < req->msg[0].iov_len) { + state->payload_vector[0].iov_base + = (req->msg[0].iov_base + len); + state->payload_vector[0].iov_len + = req->msg[0].iov_len - len; + state->payload_count = 1; + } + + for (i = 1; i < req->count; i++) { + state->payload_vector[state->payload_count++] + = req->msg[i]; + } + + len = iov_length (state->payload_vector, state->payload_count); + + GF_ASSERT (state->size == len); + + set_resolve_gfid (frame->root->client, state->resolve.pargfid, + args.pargfid); + + if (state->flags & O_EXCL) { + state->resolve.type = RESOLVE_NOT; + } else { + state->resolve.type = RESOLVE_DONTCARE; + } + + xdr_to_dict (&args.xattr, &state->dict); + xdr_to_dict (&args.xdata, &state->xdata); + + ret = 0; + resolve_and_resume (frame, server4_put_resume); + +out: + if (op_errno) + SERVER_REQ_SET_ERROR (req, ret); + + return ret; +} + +int server4_compound_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, void *data, dict_t *xdata) |