diff options
| author | Poornima G <pgurusid@redhat.com> | 2018-01-16 14:14:39 +0530 | 
|---|---|---|
| committer | Amar Tumballi <amarts@redhat.com> | 2018-01-31 09:13:58 +0000 | 
| commit | 542af5714d761e787276111ca8bf7a5c69afb721 (patch) | |
| tree | c546c94eac9711ad403bd5c04493f5bb543c800b | |
| parent | bb34b07fd2ec5e6c3eed4fe0cdf33479dbf5127b (diff) | |
protocol: Implement put fop
Updates #353
Change-Id: I755b9208690be76935d763688fa414521eba3a40
Signed-off-by: Poornima G <pgurusid@redhat.com>
| -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)  | 
