[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Fri Jun 4 22:02:47 MDT 2010


The branch, master has been updated
       via  62e0a74... Fix a long-standing bug with async io that would only be triggered by SMB2.
      from  79ec886... s3:build: add shared lib flag for HP-UX compiler

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 62e0a744e23ced873241b8fd531276e8f0c870b7
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Jun 4 21:00:24 2010 -0700

    Fix a long-standing bug with async io that would only be triggered by SMB2.
    
    On normal or shutdown close, ensure we wait for any pending IO to
    complete before returning. Implement a blocking aio_suspend inside
    vfs_aio_fork.c. These changes pass make test when the aio_fork module
    is used by default on the test shares.
    
    Jeremy.

-----------------------------------------------------------------------

Summary of changes:
 source3/modules/vfs_aio_fork.c |  124 ++++++++++++++++++++++++++++++++++++++++
 source3/smbd/close.c           |   10 ++--
 2 files changed, 129 insertions(+), 5 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/modules/vfs_aio_fork.c b/source3/modules/vfs_aio_fork.c
index b026254..b43aad2 100644
--- a/source3/modules/vfs_aio_fork.c
+++ b/source3/modules/vfs_aio_fork.c
@@ -2,6 +2,7 @@
  * Simulate the Posix AIO using mmap/fork
  *
  * Copyright (C) Volker Lendecke 2008
+ * Copyright (C) Jeremy Allison 2010
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -343,9 +344,12 @@ static void aio_child_loop(int sockfd, struct mmap_area *map)
 			ret_struct.size = sys_pread(
 				fd, (void *)map->ptr, cmd_struct.n,
 				cmd_struct.offset);
+#if 0
+/* This breaks "make test" when run with aio_fork module. */
 #ifdef ENABLE_BUILD_FARM_HACKS
 			ret_struct.size = MAX(1, ret_struct.size * 0.9);
 #endif
+#endif
 		}
 		else {
 			ret_struct.size = sys_pwrite(
@@ -723,12 +727,132 @@ static int aio_fork_error_fn(struct vfs_handle_struct *handle,
 	return child->retval.ret_errno;
 }
 
+static void aio_fork_suspend_timed_out(struct tevent_context *event_ctx,
+					struct tevent_timer *te,
+					struct timeval now,
+					void *private_data)
+{
+	bool *timed_out = (bool *)private_data;
+	/* Remove this timed event handler. */
+	TALLOC_FREE(te);
+	*timed_out = true;
+}
+
+static int aio_fork_suspend(struct vfs_handle_struct *handle,
+			struct files_struct *fsp,
+			const SMB_STRUCT_AIOCB * const aiocb_array[],
+			int n,
+			const struct timespec *timeout)
+{
+	struct aio_child_list *children = NULL;
+	TALLOC_CTX *frame = talloc_stackframe();
+	struct event_context *ev = NULL;
+	int i;
+	int ret = -1;
+	bool timed_out = false;
+
+	children = init_aio_children(handle);
+	if (children == NULL) {
+		errno = EINVAL;
+		goto out;
+	}
+
+	/* This is a blocking call, and has to use a sub-event loop. */
+	ev = event_context_init(frame);
+	if (ev == NULL) {
+		errno = ENOMEM;
+		goto out;
+	}
+
+	if (timeout) {
+		struct timeval tv;
+		struct tevent_timer *te = tevent_add_timer(ev,
+						frame,
+						timeval_current_ofs(tv.tv_sec,0),
+						aio_fork_suspend_timed_out,
+						&timed_out);
+		if (!te) {
+			errno = ENOMEM;
+			goto out;
+		}
+	}
+
+	for (i = 0; i < n; i++) {
+		struct aio_child *child = NULL;
+		const SMB_STRUCT_AIOCB *aiocb = aiocb_array[i];
+
+		if (!aiocb) {
+			continue;
+		}
+
+		/*
+		 * We're going to cheat here. We know that smbd/aio.c
+		 * only calls this when it's waiting for every single
+		 * outstanding call to finish on a close, so just wait
+		 * individually for each IO to complete. We don't care
+		 * what order they finish - only that they all do. JRA.
+		 */
+
+		for (child = children->children; child != NULL; child = child->next) {
+			if (child->aiocb == NULL) {
+				continue;
+			}
+			if (child->aiocb->aio_fildes != fsp->fh->fd) {
+				continue;
+			}
+			if (child->aiocb != aiocb) {
+				continue;
+			}
+
+			if (child->aiocb->aio_sigevent.sigev_value.sival_ptr == NULL) {
+				continue;
+			}
+
+			/* We're never using this event on the
+			 * main event context again... */
+			TALLOC_FREE(child->sock_event);
+
+			child->sock_event = event_add_fd(ev,
+						child,
+						child->sockfd,
+						EVENT_FD_READ,
+						handle_aio_completion,
+						child);
+
+			while (1) {
+				if (tevent_loop_once(ev) == -1) {
+					goto out;
+				}
+
+				if (timed_out) {
+					errno = EAGAIN;
+					goto out;
+				}
+
+				/* We set child->aiocb to NULL in our hooked
+				 * AIO_RETURN(). */
+				if (child->aiocb == NULL) {
+					break;
+				}
+			}
+		}
+	}
+
+	ret = 0;
+
+  out:
+
+	TALLOC_FREE(frame);
+	return ret;
+}
+
 static struct vfs_fn_pointers vfs_aio_fork_fns = {
 	.aio_read = aio_fork_read,
 	.aio_write = aio_fork_write,
 	.aio_return_fn = aio_fork_return_fn,
 	.aio_cancel = aio_fork_cancel,
 	.aio_error_fn = aio_fork_error_fn,
+	.aio_suspend = aio_fork_suspend,
 };
 
 NTSTATUS vfs_aio_fork_init(void);
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index 20fe9e4..b35d544 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -580,9 +580,11 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
 	NTSTATUS tmp;
 	connection_struct *conn = fsp->conn;
 
-	if (fsp->aio_write_behind) {
+	if (close_type == ERROR_CLOSE) {
+		cancel_aio_by_fsp(fsp);
+	} else {
 		/*
-	 	 * If we're finishing write behind on a close we can get a write
+	 	 * If we're finishing async io on a close we can get a write
 		 * error here, we must remember this.
 		 */
 		int ret = wait_for_aio_completion(fsp);
@@ -590,10 +592,8 @@ static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
 			status = ntstatus_keeperror(
 				status, map_nt_error_from_unix(ret));
 		}
-	} else {
-		cancel_aio_by_fsp(fsp);
 	}
- 
+
 	/*
 	 * If we're flushing on a close we can get a write
 	 * error here, we must remember this.


-- 
Samba Shared Repository


More information about the samba-cvs mailing list