summaryrefslogtreecommitdiff
path: root/source3/smbd/aio.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd/aio.c')
-rw-r--r--source3/smbd/aio.c72
1 files changed, 32 insertions, 40 deletions
diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c
index c0367a5ee8..751fed168f 100644
--- a/source3/smbd/aio.c
+++ b/source3/smbd/aio.c
@@ -45,11 +45,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)
{
@@ -184,6 +184,7 @@ bool schedule_aio_read_and_X(connection_struct *conn,
return False;
}
+ outstanding_aio_calls++;
aio_ex->req = talloc_move(aio_ex, &req);
DEBUG(10,("schedule_aio_read_and_X: scheduled aio_read for file %s, "
@@ -191,7 +192,6 @@ bool schedule_aio_read_and_X(connection_struct *conn,
fsp_str_dbg(fsp), (double)startpos, (unsigned int)smb_maxcnt,
(unsigned int)aio_ex->req->mid ));
- outstanding_aio_calls++;
return True;
}
@@ -279,6 +279,7 @@ bool schedule_aio_write_and_X(connection_struct *conn,
return False;
}
+ outstanding_aio_calls++;
aio_ex->req = talloc_move(aio_ex, &req);
/* This should actually be improved to span the write. */
@@ -302,7 +303,6 @@ bool schedule_aio_write_and_X(connection_struct *conn,
DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write "
"behind for file %s\n", fsp_str_dbg(fsp)));
}
- outstanding_aio_calls++;
DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write for file "
"%s, offset %.0f, len = %u (mid = %u) "
@@ -319,9 +319,8 @@ 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;
char *outbuf = aio_ex->outbuf;
char *data = smb_buf(outbuf);
@@ -333,18 +332,11 @@ 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) {
- 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",
- fsp_str_dbg(aio_ex->fsp), strerror(errno)));
+ fsp_str_dbg(aio_ex->fsp), (int)nread, strerror(errcode)));
- ret = errno;
- ERROR_NT(map_nt_error_from_unix(ret));
+ ERROR_NT(map_nt_error_from_unix(errcode));
outsize = srv_set_message(outbuf,0,0,true);
} else {
outsize = srv_set_message(outbuf,12,nread,False);
@@ -377,17 +369,16 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
fsp_str_dbg(aio_ex->fsp), (double)aio_ex->acb.aio_offset,
(unsigned int)nread ));
- return ret;
+ return errcode;
}
/****************************************************************************
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;
char *outbuf = aio_ex->outbuf;
ssize_t numtowrite = aio_ex->acb.aio_nbytes;
@@ -399,8 +390,7 @@ 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_str_dbg(fsp), strerror(errno)));
- ret = errno;
+ fsp_str_dbg(fsp), strerror(errcode)));
} else {
DEBUG(0,("handle_aio_write_complete: "
"aio_write_behind failed ! File %s "
@@ -408,13 +398,14 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
"only wrote %d\n", fsp_str_dbg(fsp),
(unsigned int)numtowrite,
(int)nwritten ));
- ret = EIO;
+ errcode = EIO;
}
} else {
DEBUG(10,("handle_aio_write_complete: "
"aio_write_behind completed for file %s\n",
fsp_str_dbg(fsp)));
}
+ /* TODO: should no return 0 in case of an error !!! */
return 0;
}
@@ -425,16 +416,9 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
DEBUG( 3,( "handle_aio_write: file %s wanted %u bytes. "
"nwritten == %d. Error = %s\n",
fsp_str_dbg(fsp), (unsigned int)numtowrite,
- (int)nwritten, strerror(errno) ));
+ (int)nwritten, strerror(errcode) ));
- /* If errno is ECANCELED then don't return anything to the
- * client. */
- if (errno == ECANCELED) {
- return 0;
- }
-
- ret = errno;
- ERROR_BOTH(map_nt_error_from_unix(ret), ERRHRD, ERRdiskfull);
+ ERROR_NT(map_nt_error_from_unix(errcode));
srv_set_message(outbuf,0,0,true);
} else {
bool write_through = BITSETW(aio_ex->req->vwv+7,0);
@@ -451,8 +435,8 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
fsp->fnum, (int)numtowrite, (int)nwritten));
status = sync_file(fsp->conn,fsp, write_through);
if (!NT_STATUS_IS_OK(status)) {
- ret = errno;
- ERROR_BOTH(map_nt_error_from_unix(ret),
+ errcode = errno;
+ ERROR_BOTH(map_nt_error_from_unix(errcode),
ERRHRD, ERRdiskfull);
srv_set_message(outbuf,0,0,true);
DEBUG(5,("handle_aio_write: sync_file for %s returned %s\n",
@@ -475,7 +459,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
fsp_str_dbg(fsp), (double)aio_ex->acb.aio_offset,
(unsigned int)numtowrite, (unsigned int)nwritten ));
- return ret;
+ return errcode;
}
/****************************************************************************
@@ -493,14 +477,21 @@ 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, fsp_str_dbg(aio_ex->fsp)));
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));
+ 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. */
}
@@ -510,7 +501,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)
@@ -519,6 +509,8 @@ void smbd_aio_complete_mid(unsigned int mid)
struct aio_extra *aio_ex = find_aio_ex(mid);
int ret = 0;
+ outstanding_aio_calls--;
+
DEBUG(10,("smbd_aio_complete_mid: mid[%u]\n", mid));
if (!aio_ex) {