svn commit: samba r15825 - in branches/SAMBA_4_0/source/ntvfs/posix: .

tridge at samba.org tridge at samba.org
Tue May 23 03:52:57 GMT 2006


Author: tridge
Date: 2006-05-23 03:52:57 +0000 (Tue, 23 May 2006)
New Revision: 15825

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=15825

Log:

there are quite subtle semantics with change notify events being sent
when a context (such as a tree connect) is destroyed. The behaviour
was changed by the ntvfs memory leak fix, and this patch is needed to
make it all work again.

Modified:
   branches/SAMBA_4_0/source/ntvfs/posix/pvfs_notify.c


Changeset:
Modified: branches/SAMBA_4_0/source/ntvfs/posix/pvfs_notify.c
===================================================================
--- branches/SAMBA_4_0/source/ntvfs/posix/pvfs_notify.c	2006-05-23 03:51:44 UTC (rev 15824)
+++ branches/SAMBA_4_0/source/ntvfs/posix/pvfs_notify.c	2006-05-23 03:52:57 UTC (rev 15825)
@@ -25,6 +25,7 @@
 #include "lib/messaging/irpc.h"
 #include "messaging/messaging.h"
 #include "dlinklist.h"
+#include "lib/events/events.h"
 
 /* pending notifies buffer, hung off struct pvfs_file for open directories
    that have used change notify */
@@ -44,9 +45,22 @@
 };
 
 /*
+  send a notify on the next event run. 
+*/
+void pvfs_notify_send_next(struct event_context *ev, struct timed_event *te, 
+			   struct timeval t, void *ptr)
+{
+	struct ntvfs_request *req = talloc_get_type(ptr, struct ntvfs_request);
+	talloc_free(req);
+	req->async_states->send_fn(req);
+}
+
+
+/*
   send a reply to a pending notify request
 */
-static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer, NTSTATUS status)
+static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer, 
+			     NTSTATUS status, BOOL immediate)
 {
 	struct notify_pending *pending = notify_buffer->pending;
 	struct ntvfs_request *req;
@@ -57,7 +71,7 @@
 		/* on buffer overflow return no changes and destroys the notify buffer */
 		notify_buffer->num_changes = 0;
 		while (notify_buffer->pending) {
-			pvfs_notify_send(notify_buffer, NT_STATUS_OK);
+			pvfs_notify_send(notify_buffer, NT_STATUS_OK, immediate);
 		}
 		talloc_free(notify_buffer);
 		return;
@@ -86,7 +100,18 @@
 	}
 
 	req->async_states->status = status;
-	req->async_states->send_fn(req);
+
+	if (immediate) {
+		req->async_states->send_fn(req);
+		return;
+	} 
+
+	/* we can't call pvfs_notify_send() directly here, as that
+	   would free the request, and the ntvfs modules above us
+	   could use it, so call it on the next event */
+	talloc_reference(notify_buffer, req);
+	event_add_timed(req->ctx->event_ctx, 
+			req, timeval_zero(), pvfs_notify_send_next, req);
 }
 
 /*
@@ -97,7 +122,7 @@
 	struct pvfs_notify_buffer *n = talloc_get_type(ptr, struct pvfs_notify_buffer);
 	notify_remove(n->f->pvfs->notify_context, n);
 	n->f->notify_buffer = NULL;
-	pvfs_notify_send(n, NT_STATUS_OK);
+	pvfs_notify_send(n, NT_STATUS_OK, True);
 	return 0;
 }
 
@@ -140,7 +165,7 @@
 
 	/* send what we have, unless its the first part of a rename */
 	if (ev->action != NOTIFY_ACTION_OLD_NAME) {
-		pvfs_notify_send(n, NT_STATUS_OK);
+		pvfs_notify_send(n, NT_STATUS_OK, True);
 	}
 }
 
@@ -185,9 +210,9 @@
 	struct pvfs_notify_buffer *notify_buffer = talloc_get_type(private, 
 								   struct pvfs_notify_buffer);
 	if (reason == PVFS_WAIT_CANCEL) {
-		pvfs_notify_send(notify_buffer, NT_STATUS_CANCELLED);
+		pvfs_notify_send(notify_buffer, NT_STATUS_CANCELLED, False);
 	} else {
-		pvfs_notify_send(notify_buffer, NT_STATUS_OK);
+		pvfs_notify_send(notify_buffer, NT_STATUS_OK, True);
 	}
 }
 
@@ -251,7 +276,8 @@
 		return NT_STATUS_OK;
 	}
 
-	pvfs_notify_send(f->notify_buffer, NT_STATUS_OK);
+	req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC;
+	pvfs_notify_send(f->notify_buffer, NT_STATUS_OK, False);
 
 	return NT_STATUS_OK;
 }



More information about the samba-cvs mailing list