diff options
| author | Volker Lendecke <vl@samba.org> | 2014-06-20 08:23:47 +0000 |
|---|---|---|
| committer | Volker Lendecke <vl@samba.org> | 2014-06-21 20:38:11 +0200 |
| commit | f0876ff68a664ab5dd10ae77cddf2186e8a39768 (patch) | |
| tree | 412f94c278a170ac27c1115b919cac52ebac0c06 /source3 | |
| parent | f52158d74039afd0af6fcf185349bf80e8c36511 (diff) | |
| download | samba-f0876ff68a664ab5dd10ae77cddf2186e8a39768.tar.gz samba-f0876ff68a664ab5dd10ae77cddf2186e8a39768.tar.xz samba-f0876ff68a664ab5dd10ae77cddf2186e8a39768.zip | |
libsmb: Make cli_smb2_create_fnum async
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Diffstat (limited to 'source3')
| -rw-r--r-- | source3/libsmb/cli_smb2_fnum.c | 164 | ||||
| -rw-r--r-- | source3/libsmb/cli_smb2_fnum.h | 12 |
2 files changed, 139 insertions, 37 deletions
diff --git a/source3/libsmb/cli_smb2_fnum.c b/source3/libsmb/cli_smb2_fnum.c index 950398a5cb..6c24038674 100644 --- a/source3/libsmb/cli_smb2_fnum.c +++ b/source3/libsmb/cli_smb2_fnum.c @@ -151,32 +151,40 @@ static uint8_t flags_to_smb2_oplock(uint32_t create_flags) /*************************************************************** Small wrapper that allows SMB2 create to return a uint16_t fnum. - Synchronous only. ***************************************************************/ -NTSTATUS cli_smb2_create_fnum(struct cli_state *cli, - const char *fname, - uint32_t create_flags, - uint32_t desired_access, - uint32_t file_attributes, - uint32_t share_access, - uint32_t create_disposition, - uint32_t create_options, - uint16_t *pfid, - struct smb_create_returns *cr) +struct cli_smb2_create_fnum_state { + struct cli_state *cli; + struct smb_create_returns cr; + uint16_t fnum; +}; + +static void cli_smb2_create_fnum_done(struct tevent_req *subreq); + +struct tevent_req *cli_smb2_create_fnum_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + const char *fname, + uint32_t create_flags, + uint32_t desired_access, + uint32_t file_attributes, + uint32_t share_access, + uint32_t create_disposition, + uint32_t create_options) { - NTSTATUS status; - struct smb2_hnd h; + struct tevent_req *req, *subreq; + struct cli_smb2_create_fnum_state *state; - if (smbXcli_conn_has_async_calls(cli->conn)) { - /* - * Can't use sync call while an async call is in flight - */ - return NT_STATUS_INVALID_PARAMETER; + req = tevent_req_create(mem_ctx, &state, + struct cli_smb2_create_fnum_state); + if (req == NULL) { + return NULL; } + state->cli = cli; if (smbXcli_conn_protocol(cli->conn) < PROTOCOL_SMB2_02) { - return NT_STATUS_INVALID_PARAMETER; + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); } if (cli->backup_intent) { @@ -189,27 +197,109 @@ NTSTATUS cli_smb2_create_fnum(struct cli_state *cli, fname++; } - status = smb2cli_create(cli->conn, - cli->timeout, - cli->smb2.session, - cli->smb2.tcon, - fname, - flags_to_smb2_oplock(create_flags), - SMB2_IMPERSONATION_IMPERSONATION, - desired_access, - file_attributes, - share_access, - create_disposition, - create_options, - NULL, - &h.fid_persistent, - &h.fid_volatile, - cr); + subreq = smb2cli_create_send(state, ev, + cli->conn, + cli->timeout, + cli->smb2.session, + cli->smb2.tcon, + fname, + flags_to_smb2_oplock(create_flags), + SMB2_IMPERSONATION_IMPERSONATION, + desired_access, + file_attributes, + share_access, + create_disposition, + create_options, + NULL); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_smb2_create_fnum_done, req); + return req; +} - if (NT_STATUS_IS_OK(status)) { - status = map_smb2_handle_to_fnum(cli, &h, pfid); +static void cli_smb2_create_fnum_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_smb2_create_fnum_state *state = tevent_req_data( + req, struct cli_smb2_create_fnum_state); + struct smb2_hnd h; + NTSTATUS status; + + status = smb2cli_create_recv(subreq, &h.fid_persistent, + &h.fid_volatile, &state->cr); + TALLOC_FREE(subreq); + if (tevent_req_nterror(req, status)) { + return; + } + + status = map_smb2_handle_to_fnum(state->cli, &h, &state->fnum); + if (tevent_req_nterror(req, status)) { + return; + } + tevent_req_done(req); +} + +NTSTATUS cli_smb2_create_fnum_recv(struct tevent_req *req, uint16_t *pfnum, + struct smb_create_returns *cr) +{ + struct cli_smb2_create_fnum_state *state = tevent_req_data( + req, struct cli_smb2_create_fnum_state); + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + if (pfnum != NULL) { + *pfnum = state->fnum; } + if (cr != NULL) { + *cr = state->cr; + } + return NT_STATUS_OK; +} +NTSTATUS cli_smb2_create_fnum(struct cli_state *cli, + const char *fname, + uint32_t create_flags, + uint32_t desired_access, + uint32_t file_attributes, + uint32_t share_access, + uint32_t create_disposition, + uint32_t create_options, + uint16_t *pfid, + struct smb_create_returns *cr) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct tevent_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + if (smbXcli_conn_has_async_calls(cli->conn)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + ev = samba_tevent_context_init(frame); + if (ev == NULL) { + goto fail; + } + req = cli_smb2_create_fnum_send(frame, ev, cli, fname, create_flags, + desired_access, file_attributes, + share_access, create_disposition, + create_options); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto fail; + } + status = cli_smb2_create_fnum_recv(req, pfid, cr); + fail: + TALLOC_FREE(frame); return status; } diff --git a/source3/libsmb/cli_smb2_fnum.h b/source3/libsmb/cli_smb2_fnum.h index a5ed5a0072..9394918dfc 100644 --- a/source3/libsmb/cli_smb2_fnum.h +++ b/source3/libsmb/cli_smb2_fnum.h @@ -25,6 +25,18 @@ struct smbXcli_session; struct cli_state; struct file_info; +struct tevent_req *cli_smb2_create_fnum_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + const char *fname, + uint32_t create_flags, + uint32_t desired_access, + uint32_t file_attributes, + uint32_t share_access, + uint32_t create_disposition, + uint32_t create_options); +NTSTATUS cli_smb2_create_fnum_recv(struct tevent_req *req, uint16_t *pfnum, + struct smb_create_returns *cr); NTSTATUS cli_smb2_create_fnum(struct cli_state *cli, const char *fname, uint32_t create_flags, |
