svn commit: samba r7623 - in trunk/source/smbd: .
jra at samba.org
jra at samba.org
Wed Jun 15 22:48:15 GMT 2005
Author: jra
Date: 2005-06-15 22:48:15 +0000 (Wed, 15 Jun 2005)
New Revision: 7623
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=7623
Log:
Get the write behind working reliably. I now know how to correctly
use aio_error and aio_suspend.
Jeremy.
Modified:
trunk/source/smbd/aio.c
Changeset:
Modified: trunk/source/smbd/aio.c
===================================================================
--- trunk/source/smbd/aio.c 2005-06-15 21:45:09 UTC (rev 7622)
+++ trunk/source/smbd/aio.c 2005-06-15 22:48:15 UTC (rev 7623)
@@ -297,7 +297,7 @@
}
if (outstanding_aio_calls >= AIO_PENDING_SIZE) {
- DEBUG(10,("schedule_aio_write_and_X: Already have %d aio activities outstanding.\n",
+ DEBUG(3,("schedule_aio_write_and_X: Already have %d aio activities outstanding.\n",
outstanding_aio_calls ));
DEBUG(10,("schedule_aio_write_and_X: failed to schedule aio_write for file %s, offset %.0f, len = %u (mid = %u)\n",
fsp->fsp_name, (double)startpos, (unsigned int)numtowrite, (unsigned int)aio_ex->mid ));
@@ -492,6 +492,35 @@
}
/****************************************************************************
+ Handle any aio completion. Returns True if finished (and sets *perr if err was non-zero),
+ False if not.
+*****************************************************************************/
+
+static BOOL handle_aio_completed(struct aio_extra *aio_ex, int *perr)
+{
+ int err;
+
+ /* Ensure the operation has really completed. */
+ if (SMB_VFS_AIO_ERROR(aio_ex->fsp, &aio_ex->acb) == EINPROGRESS) {
+ DEBUG(10,( "handle_aio_completed: operation mid %u still in process for file %s\n",
+ aio_ex->mid, aio_ex->fsp->fsp_name ));
+ return False;
+ }
+
+ if (aio_ex->read_req) {
+ err = handle_aio_read_complete(aio_ex);
+ } else {
+ err = handle_aio_write_complete(aio_ex);
+ }
+
+ if (err) {
+ *perr = err; /* Only save non-zero errors. */
+ }
+
+ return True;
+}
+
+/****************************************************************************
Handle any aio completion inline.
Returns non-zero errno if fail or zero if all ok.
*****************************************************************************/
@@ -513,7 +542,6 @@
/* Drain all the complete aio_reads. */
for (i = 0; i < signals_received; i++) {
- int err = 0;
uint16 mid = aio_pending_array[i];
files_struct *fsp = NULL;
struct aio_extra *aio_ex = find_aio_ex(mid);
@@ -533,23 +561,13 @@
continue;
}
- /* Ensure the operation has really completed. */
- if (SMB_VFS_AIO_ERROR(fsp,&aio_ex->acb) == EINPROGRESS) {
- DEBUG( 3,( "process_aio_queue: operation still in process for file %s\n", fsp->fsp_name ));
+ if (!handle_aio_completed(aio_ex, &ret)) {
continue;
}
- if (aio_ex->read_req) {
- err = handle_aio_read_complete(aio_ex);
- } else {
- err = handle_aio_write_complete(aio_ex);
- }
-
- if (err) {
- ret = err; /* Only save non-zero errors. */
- }
delete_aio_ex(aio_ex);
}
+
outstanding_aio_calls -= signals_received;
signals_received = 0;
BlockSignals(False, RT_SIGNAL_AIO);
@@ -557,21 +575,23 @@
}
/****************************************************************************
- We're doing write behind and the client closed the file. Wait up to 15 seconds
+ We're doing write behind and the client closed the file. Wait up to 30 seconds
(my arbitrary choice) for the aio to complete. Return 0 if all writes completed,
errno to return if not.
*****************************************************************************/
+#define SMB_TIME_FOR_AIO_COMPLETE_WAIT 29
+
BOOL wait_for_aio_completion(files_struct *fsp)
{
struct aio_extra *aio_ex;
const SMB_STRUCT_AIOCB **aiocb_list;
int aio_completion_count = 0;
time_t start_time = time(NULL);
- int seconds_left = 15;
+ int seconds_left;
int ret = 0;
- for (seconds_left = 15; seconds_left >= 0;) {
+ for (seconds_left = SMB_TIME_FOR_AIO_COMPLETE_WAIT; seconds_left >= 0;) {
int err = 0;
int i;
struct timespec ts;
@@ -601,31 +621,45 @@
}
}
- /* Now wait up to 15 seconds for completion. */
+ /* Now wait up to seconds_left for completion. */
ts.tv_sec = seconds_left;
ts.tv_nsec = 0;
- DEBUG(3,("wait_for_aio_completion: doing a wait of %d seconds.\n", seconds_left ));
+ DEBUG(10,("wait_for_aio_completion: %d events, doing a wait of %d seconds.\n",
+ aio_completion_count, seconds_left ));
err = SMB_VFS_AIO_SUSPEND(fsp, aiocb_list, aio_completion_count, &ts);
+ DEBUG(10,("wait_for_aio_completion: returned err = %d, errno = %s\n",
+ err, strerror(errno) ));
+
if (err == -1 && errno == EAGAIN) {
+ DEBUG(0,("wait_for_aio_completion: aio_suspend timed out waiting for %d events after a wait of %d seconds\n",
+ aio_completion_count, seconds_left));
/* Timeout. */
- break;
+ cancel_aio_by_fsp(fsp);
+ SAFE_FREE(aiocb_list);
+ return ret ? ret : EIO;
}
- err = process_aio_queue();
- if (err) {
- /* Only return non-zero errors. */
- ret = err;
+ /* One or more events might have completed - process them if so. */
+ for( i = 0; i < aio_completion_count; i++) {
+ uint16 mid = *(uint16 *)aiocb_list[i]->aio_sigevent.sigev_value.sival_ptr;
+
+ aio_ex = find_aio_ex(mid);
+
+ if (!handle_aio_completed(aio_ex, &err)) {
+ continue;
+ }
+ delete_aio_ex(aio_ex);
}
SAFE_FREE(aiocb_list);
- seconds_left -= (time(NULL) - start_time);
+ seconds_left = SMB_TIME_FOR_AIO_COMPLETE_WAIT - (time(NULL) - start_time);
}
/* We timed out - we don't know why. Return ret if already an error, else EIO. */
- DEBUG(0,("wait_for_aio_completion: aio_suspend timed out waiting for %d events\n",
+ DEBUG(10,("wait_for_aio_completion: aio_suspend timed out waiting for %d events\n",
aio_completion_count));
return ret ? ret : EIO;
More information about the samba-cvs
mailing list