From 4abccf0b65235d6a01c0dc194f06fac748ee4029 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 17 Aug 2012 12:22:17 +0200 Subject: s3: Fix a panic when shutting down When a client disconnects while we have aio open, there is no close request that cleans up. We can't send out the replies anymore, so just drop the aio requests that are pending. Found using the new python lib writing multiple files simultaneously TODO: check tdis and logoff Signed-off-by: Stefan Metzmacher Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Sat Sep 8 01:27:34 CEST 2012 on sn-devel-104 --- source3/smbd/close.c | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/source3/smbd/close.c b/source3/smbd/close.c index d4b9ad0223..51432320b0 100644 --- a/source3/smbd/close.c +++ b/source3/smbd/close.c @@ -708,18 +708,40 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp, connection_struct *conn = fsp->conn; if (fsp->num_aio_requests != 0) { + + 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"); + } + /* - * 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. + * 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. */ - DEBUG(0, ("fsp->num_aio_requests=%u\n", - fsp->num_aio_requests)); - smb_panic("can not close with outstanding aio requests"); + TALLOC_FREE(fsp->deferred_close); + + while (fsp->num_aio_requests != 0) { + /* + * The destructor of the req will remove + * itself from the fsp + */ + TALLOC_FREE(fsp->aio_requests[0]); + } } /* -- cgit