From 1f5aec877fc48ff96b14a0e95f01c68a29dd8718 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 15 Jul 2009 11:49:33 -0700 Subject: Make cli_unlock and cli_unlock64 async. Fix POSIX lock test. Jeremy. --- source3/libsmb/clifile.c | 270 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 206 insertions(+), 64 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 0e2b3640f2..5ea0579839 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1893,7 +1893,6 @@ struct tevent_req *cli_nt_delete_on_close_send(TALLOC_CTX *mem_ctx, SSVAL(&state->setup, 0, TRANSACT2_SETFILEINFO); /* Setup param array. */ - memset(state->param, '\0', 6); SSVAL(state->param,0,fnum); SSVAL(state->param,2,SMB_SET_FILE_DISPOSITION_INFO); @@ -2010,6 +2009,7 @@ struct tevent_req *cli_ntcreate_send(TALLOC_CTX *mem_ctx, if (req == NULL) { return NULL; } + vwv = state->vwv; SCVAL(vwv+0, 0, 0xFF); @@ -2367,6 +2367,7 @@ struct tevent_req *cli_close_create(TALLOC_CTX *mem_ctx, if (req == NULL) { return NULL; } + SSVAL(state->vwv+0, 0, fnum); SIVALS(state->vwv+1, 0, -1); @@ -2708,42 +2709,114 @@ bool cli_lock(struct cli_state *cli, uint16_t fnum, Unlock a file. ****************************************************************************/ -bool cli_unlock(struct cli_state *cli, uint16_t fnum, uint32_t offset, uint32_t len) +struct cli_unlock_state { + uint16_t vwv[8]; + uint8_t data[10]; +}; + +static void cli_unlock_done(struct tevent_req *subreq); + +struct tevent_req *cli_unlock_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len) + { - char *p; + struct tevent_req *req = NULL, *subreq = NULL; + struct cli_unlock_state *state = NULL; + uint8_t additional_flags = 0; - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); + req = tevent_req_create(mem_ctx, &state, struct cli_unlock_state); + if (req == NULL) { + return NULL; + } - cli_set_message(cli->outbuf,8,0,True); + SCVAL(state->vwv+0, 0, 0xFF); + SSVAL(state->vwv+2, 0, fnum); + SCVAL(state->vwv+3, 0, 0); + SIVALS(state->vwv+4, 0, 0); + SSVAL(state->vwv+6, 0, 1); + SSVAL(state->vwv+7, 0, 0); - SCVAL(cli->outbuf,smb_com,SMBlockingX); - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); + SSVAL(state->data, 0, cli->pid); + SIVAL(state->data, 2, offset); + SIVAL(state->data, 6, len); - SCVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,fnum); - SCVAL(cli->outbuf,smb_vwv3,0); - SIVALS(cli->outbuf, smb_vwv4, 0); - SSVAL(cli->outbuf,smb_vwv6,1); - SSVAL(cli->outbuf,smb_vwv7,0); + subreq = cli_smb_send(state, ev, cli, SMBlockingX, additional_flags, + 8, state->vwv, 10, state->data); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_unlock_done, req); + return req; +} - p = smb_buf(cli->outbuf); - SSVAL(p, 0, cli->pid); - SIVAL(p, 2, offset); - SIVAL(p, 6, len); - p += 10; - cli_setup_bcc(cli, p); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; +static void cli_unlock_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + NTSTATUS status; + + status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; } + tevent_req_done(req); +} - if (cli_is_error(cli)) { - return False; +NTSTATUS cli_unlock_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_ntstatus(req); +} + +NTSTATUS cli_unlock(struct cli_state *cli, + uint16_t fnum, + uint32_t offset, + uint32_t len) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_OK; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; } - return True; + ev = event_context_init(frame); + if (ev == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + req = cli_unlock_send(frame, ev, cli, + fnum, offset, len); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + if (!tevent_req_poll(req, ev)) { + status = map_nt_error_from_unix(errno); + goto fail; + } + + status = cli_unlock_recv(req); + + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } /**************************************************************************** @@ -2811,46 +2884,118 @@ bool cli_lock64(struct cli_state *cli, uint16_t fnum, Unlock a file with 64 bit offsets. ****************************************************************************/ -bool cli_unlock64(struct cli_state *cli, uint16_t fnum, uint64_t offset, uint64_t len) +struct cli_unlock64_state { + uint16_t vwv[8]; + uint8_t data[20]; +}; + +static void cli_unlock64_done(struct tevent_req *subreq); + +struct tevent_req *cli_unlock64_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len) + { - char *p; + struct tevent_req *req = NULL, *subreq = NULL; + struct cli_unlock64_state *state = NULL; + uint8_t additional_flags = 0; - if (! (cli->capabilities & CAP_LARGE_FILES)) { - return cli_unlock(cli, fnum, offset, len); + req = tevent_req_create(mem_ctx, &state, struct cli_unlock64_state); + if (req == NULL) { + return NULL; } - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); + SCVAL(state->vwv+0, 0, 0xff); + SSVAL(state->vwv+2, 0, fnum); + SCVAL(state->vwv+3, 0,LOCKING_ANDX_LARGE_FILES); + SIVALS(state->vwv+4, 0, 0); + SSVAL(state->vwv+6, 0, 1); + SSVAL(state->vwv+7, 0, 0); - cli_set_message(cli->outbuf,8,0,True); + SIVAL(state->data, 0, cli->pid); + SOFF_T_R(state->data, 4, offset); + SOFF_T_R(state->data, 12, len); - SCVAL(cli->outbuf,smb_com,SMBlockingX); - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); + subreq = cli_smb_send(state, ev, cli, SMBlockingX, additional_flags, + 8, state->vwv, 20, state->data); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_unlock64_done, req); + return req; +} - SCVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,fnum); - SCVAL(cli->outbuf,smb_vwv3,LOCKING_ANDX_LARGE_FILES); - SIVALS(cli->outbuf, smb_vwv4, 0); - SSVAL(cli->outbuf,smb_vwv6,1); - SSVAL(cli->outbuf,smb_vwv7,0); +static void cli_unlock64_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + NTSTATUS status; - p = smb_buf(cli->outbuf); - SIVAL(p, 0, cli->pid); - SOFF_T_R(p, 4, offset); - SOFF_T_R(p, 12, len); - p += 20; - cli_setup_bcc(cli, p); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; + status = cli_smb_recv(subreq, 0, NULL, NULL, NULL, NULL); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; } + tevent_req_done(req); +} - if (cli_is_error(cli)) { - return False; +NTSTATUS cli_unlock64_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_ntstatus(req); +} + +NTSTATUS cli_unlock64(struct cli_state *cli, + uint16_t fnum, + uint64_t offset, + uint64_t len) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_OK; + + if (! (cli->capabilities & CAP_LARGE_FILES)) { + return cli_unlock(cli, fnum, offset, len); } - return True; + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + + ev = event_context_init(frame); + if (ev == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + req = cli_unlock64_send(frame, ev, cli, + fnum, offset, len); + if (req == NULL) { + status = NT_STATUS_NO_MEMORY; + goto fail; + } + + if (!tevent_req_poll(req, ev)) { + status = map_nt_error_from_unix(errno); + goto fail; + } + + status = cli_unlock64_recv(req); + + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; } /**************************************************************************** @@ -3421,7 +3566,7 @@ NTSTATUS cli_getatr(struct cli_state *cli, static void cli_setattrE_done(struct tevent_req *subreq); struct cli_setattrE_state { - int dummy; + uint16_t vwv[7]; }; struct tevent_req *cli_setattrE_send(TALLOC_CTX *mem_ctx, @@ -3435,21 +3580,19 @@ struct tevent_req *cli_setattrE_send(TALLOC_CTX *mem_ctx, struct tevent_req *req = NULL, *subreq = NULL; struct cli_setattrE_state *state = NULL; uint8_t additional_flags = 0; - uint16_t vwv[7]; req = tevent_req_create(mem_ctx, &state, struct cli_setattrE_state); if (req == NULL) { return NULL; } - memset(vwv, '\0', sizeof(vwv)); - SSVAL(vwv+0, 0, fnum); - cli_put_dos_date2(cli, (char *)&vwv[1], 0, change_time); - cli_put_dos_date2(cli, (char *)&vwv[3], 0, access_time); - cli_put_dos_date2(cli, (char *)&vwv[5], 0, write_time); + SSVAL(state->vwv+0, 0, fnum); + cli_put_dos_date2(cli, (char *)&state->vwv[1], 0, change_time); + cli_put_dos_date2(cli, (char *)&state->vwv[3], 0, access_time); + cli_put_dos_date2(cli, (char *)&state->vwv[5], 0, write_time); subreq = cli_smb_send(state, ev, cli, SMBsetattrE, additional_flags, - 7, vwv, 0, NULL); + 7, state->vwv, 0, NULL); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } @@ -3556,7 +3699,6 @@ struct tevent_req *cli_setatr_send(TALLOC_CTX *mem_ctx, return NULL; } - memset(state->vwv, '\0', sizeof(state->vwv)); SSVAL(state->vwv+0, 0, attr); cli_put_dos_date3(cli, (char *)&state->vwv[1], 0, mtime); -- cgit