1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-09 08:58:35 +03:00

smbd: move pending aio cleanup to a helper function

We'll be reusing this from close_directory() in the next commit.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14301

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
Ralph Boehme 2020-03-09 11:16:37 +01:00 committed by Jeremy Allison
parent 95cfcda13f
commit acb0b01761

View File

@ -635,6 +635,69 @@ static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
return s2;
}
static void close_free_pending_aio(struct files_struct *fsp,
enum file_close_type close_type)
{
unsigned num_requests = fsp->num_aio_requests;
if (num_requests == 0) {
return;
}
if (close_type != SHUTDOWN_CLOSE) {
/*
* reply_close and the smb2 close must have
* taken care of this. No other callers of
* close_file should ever have created async
* I/O.
*
* We need to panic here because if we close()
* the fd while we have outstanding async I/O
* requests, in the worst case we could end up
* writing to the wrong file.
*/
DBG_ERR("fsp->num_aio_requests=%u\n", num_requests);
smb_panic("can not close with outstanding aio requests");
return;
}
/*
* For shutdown close, just drop the async requests
* including a potential close request pending for
* this fsp. Drop the close request first, the
* destructor for the aio_requests would execute it.
*/
TALLOC_FREE(fsp->deferred_close);
while (fsp->num_aio_requests != 0) {
/*
* Previously we just called talloc_free()
* on the outstanding request, but this
* caused crashes (before the async callback
* functions were fixed not to reference req
* directly) and also leaves the SMB2 request
* outstanding on the processing queue.
*
* Using tevent_req_error() instead
* causes the outstanding SMB1/2/3 request to
* return with NT_STATUS_INVALID_HANDLE
* and removes it from the processing queue.
*
* The callback function called from this
* calls talloc_free(req). The destructor will remove
* itself from the fsp and the aio_requests array.
*/
tevent_req_error(fsp->aio_requests[0], EBADF);
/* Paranoia to ensure we don't spin. */
num_requests--;
if (fsp->num_aio_requests != num_requests) {
smb_panic("cannot cancel outstanding aio "
"requests");
}
}
}
/****************************************************************************
Close a file.
@ -651,63 +714,7 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
connection_struct *conn = fsp->conn;
bool is_durable = false;
if (fsp->num_aio_requests != 0) {
unsigned num_requests = fsp->num_aio_requests;
if (close_type != SHUTDOWN_CLOSE) {
/*
* reply_close and the smb2 close must have
* taken care of this. No other callers of
* close_file should ever have created async
* I/O.
*
* We need to panic here because if we close()
* the fd while we have outstanding async I/O
* requests, in the worst case we could end up
* writing to the wrong file.
*/
DEBUG(0, ("fsp->num_aio_requests=%u\n",
fsp->num_aio_requests));
smb_panic("can not close with outstanding aio "
"requests");
}
/*
* For shutdown close, just drop the async requests
* including a potential close request pending for
* this fsp. Drop the close request first, the
* destructor for the aio_requests would execute it.
*/
TALLOC_FREE(fsp->deferred_close);
while (fsp->num_aio_requests != 0) {
/*
* Previously we just called talloc_free()
* on the outstanding request, but this
* caused crashes (before the async callback
* functions were fixed not to reference req
* directly) and also leaves the SMB2 request
* outstanding on the processing queue.
*
* Using tevent_req_error() instead
* causes the outstanding SMB1/2/3 request to
* return with NT_STATUS_INVALID_HANDLE
* and removes it from the processing queue.
*
* The callback function called from this
* calls talloc_free(req). The destructor will remove
* itself from the fsp and the aio_requests array.
*/
tevent_req_error(fsp->aio_requests[0], EBADF);
/* Paranoia to ensure we don't spin. */
num_requests--;
if (fsp->num_aio_requests != num_requests) {
smb_panic("cannot cancel outstanding aio "
"requests");
}
}
}
close_free_pending_aio(fsp, close_type);
while (talloc_array_length(fsp->blocked_smb1_lock_reqs) != 0) {
smbd_smb1_brl_finish_by_req(