TODO review tdis/logoff s3: Fix a panic when shutting down
authorVolker Lendecke <vl@samba.org>
Fri, 17 Aug 2012 10:22:17 +0000 (12:22 +0200)
committerStefan Metzmacher <metze@samba.org>
Sun, 2 Sep 2012 11:30:06 +0000 (13:30 +0200)
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

Signed-off-by: Stefan Metzmacher <metze@samba.org>
source3/smbd/close.c

index d4b9ad0223420e120f19bde4d0629b22db093860..51432320b0293deb0d6b98e597e4a9963b9a7a84 100644 (file)
@@ -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]);
+               }
        }
 
        /*