s3/aio: Correctly handle aio_error() and errno.
authorOlaf Flebbe <o.flebbe@science-computing.de>
Tue, 6 Oct 2009 09:09:28 +0000 (11:09 +0200)
committerKarolin Seeger <kseeger@samba.org>
Thu, 15 Oct 2009 12:34:31 +0000 (14:34 +0200)
Fix bug #6805.

source3/smbd/aio.c

index ab986752e8de7ffa736deabdbf4a37b36e206501..406ec1b3e351d456852f7fa0ec0897a3f2991da3 100644 (file)
@@ -48,11 +48,11 @@ struct aio_extra {
        files_struct *fsp;
        struct smb_request *req;
        char *outbuf;
-       int (*handle_completion)(struct aio_extra *ex);
+       int (*handle_completion)(struct aio_extra *ex, int errcode);
 };
 
-static int handle_aio_read_complete(struct aio_extra *aio_ex);
-static int handle_aio_write_complete(struct aio_extra *aio_ex);
+static int handle_aio_read_complete(struct aio_extra *aio_ex, int errcode);
+static int handle_aio_write_complete(struct aio_extra *aio_ex, int errcode);
 
 static int aio_extra_destructor(struct aio_extra *aio_ex)
 {
@@ -324,7 +324,7 @@ bool schedule_aio_write_and_X(connection_struct *conn,
  Returns errno or zero if all ok.
 *****************************************************************************/
 
-static int handle_aio_read_complete(struct aio_extra *aio_ex)
+static int handle_aio_read_complete(struct aio_extra *aio_ex, int errcode)
 {
        int ret = 0;
        int outsize;
@@ -338,19 +338,12 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
                   will return an error. Hopefully this is
                   true.... JRA. */
 
-               /* If errno is ECANCELED then don't return anything to the
-                * client. */
-               if (errno == ECANCELED) {
-                       srv_cancel_sign_response(aio_ex->req->mid, false);
-                       return 0;
-               }
-
-               DEBUG( 3,( "handle_aio_read_complete: file %s nread == -1. "
+               DEBUG( 3,( "handle_aio_read_complete: file %s nread == %d "
                           "Error = %s\n",
-                          aio_ex->fsp->fsp_name, strerror(errno) ));
+                          aio_ex->fsp->fsp_name, (int)nread, strerror(errcode) ));
 
-               ret = errno;
-               ERROR_NT(map_nt_error_from_unix(ret));
+               ret = errcode;
+               ERROR_NT(map_nt_error_from_unix( ret));
                outsize = srv_set_message(outbuf,0,0,true);
        } else {
                outsize = srv_set_message(outbuf,12,nread,False);
@@ -387,10 +380,10 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
 
 /****************************************************************************
  Complete the write and return the data or error back to the client.
- Returns errno or zero if all ok.
+ Returns error code or zero if all ok.
 *****************************************************************************/
 
-static int handle_aio_write_complete(struct aio_extra *aio_ex)
+static int handle_aio_write_complete(struct aio_extra *aio_ex, int errcode)
 {
        int ret = 0;
        files_struct *fsp = aio_ex->fsp;
@@ -404,8 +397,8 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
                                DEBUG(5,("handle_aio_write_complete: "
                                         "aio_write_behind failed ! File %s "
                                         "is corrupt ! Error %s\n",
-                                        fsp->fsp_name, strerror(errno) ));
-                               ret = errno;
+                                        fsp->fsp_name, strerror(errcode) ));
+                               ret = errcode;
                        } else {
                                DEBUG(0,("handle_aio_write_complete: "
                                         "aio_write_behind failed ! File %s "
@@ -420,6 +413,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
                                  "aio_write_behind completed for file %s\n",
                                  fsp->fsp_name ));
                }
+               /* TODO: should no return 0 in case of an error !!! */
                return 0;
        }
 
@@ -432,15 +426,8 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
                           fsp->fsp_name, (unsigned int)numtowrite,
                           (int)nwritten, strerror(errno) ));
 
-               /* If errno is ECANCELED then don't return anything to the
-                * client. */
-               if (errno == ECANCELED) {
-                       srv_cancel_sign_response(aio_ex->req->mid, false);
-                       return 0;
-               }
-
-               ret = errno;
-               ERROR_BOTH(map_nt_error_from_unix(ret), ERRHRD, ERRdiskfull);
+               ret = errcode;
+               ERROR_NT(map_nt_error_from_unix(ret));
                srv_set_message(outbuf,0,0,true);
         } else {
                bool write_through = BITSETW(aio_ex->req->vwv+7,0);
@@ -497,14 +484,22 @@ static bool handle_aio_completed(struct aio_extra *aio_ex, int *perr)
        }
 
        /* Ensure the operation has really completed. */
-       if (SMB_VFS_AIO_ERROR(aio_ex->fsp, &aio_ex->acb) == EINPROGRESS) {
+       err = SMB_VFS_AIO_ERROR(aio_ex->fsp, &aio_ex->acb);
+       if (err == EINPROGRESS) {
                DEBUG(10,( "handle_aio_completed: operation mid %u still in "
                           "process for file %s\n",
                           aio_ex->req->mid, aio_ex->fsp->fsp_name ));
                return False;
-       }
+       } else if (err == ECANCELED) {
+               /* If error is ECANCELED then don't return anything to the
+                * client. */
+               DEBUG(10,( "handle_aio_completed: operation mid %u"
+                           " canceled\n", aio_ex->req->mid));
+                srv_cancel_sign_response(aio_ex->req->mid, false);
+               return True;
+        }
 
-       err = aio_ex->handle_completion(aio_ex);
+       err = aio_ex->handle_completion(aio_ex, err);
        if (err) {
                *perr = err; /* Only save non-zero errors. */
        }
@@ -514,7 +509,6 @@ static bool handle_aio_completed(struct aio_extra *aio_ex, int *perr)
 
 /****************************************************************************
  Handle any aio completion inline.
- Returns non-zero errno if fail or zero if all ok.
 *****************************************************************************/
 
 void smbd_aio_complete_mid(unsigned int mid)