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:
parent
95cfcda13f
commit
acb0b01761
@ -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(
|
||||
|
Loading…
x
Reference in New Issue
Block a user