svn commit: samba r14755 - in branches/SAMBA_4_0/source/ntvfs: common posix

tridge at samba.org tridge at samba.org
Wed Mar 29 13:31:30 GMT 2006


Author: tridge
Date: 2006-03-29 13:31:30 +0000 (Wed, 29 Mar 2006)
New Revision: 14755

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

Log:

the change notify code now passes most of the RAW-NOTIFY test. Still
more work to do though

Modified:
   branches/SAMBA_4_0/source/ntvfs/common/notify.c
   branches/SAMBA_4_0/source/ntvfs/posix/pvfs_mkdir.c
   branches/SAMBA_4_0/source/ntvfs/posix/pvfs_notify.c
   branches/SAMBA_4_0/source/ntvfs/posix/pvfs_wait.c


Changeset:
Modified: branches/SAMBA_4_0/source/ntvfs/common/notify.c
===================================================================
--- branches/SAMBA_4_0/source/ntvfs/common/notify.c	2006-03-29 10:20:28 UTC (rev 14754)
+++ branches/SAMBA_4_0/source/ntvfs/common/notify.c	2006-03-29 13:31:30 UTC (rev 14755)
@@ -332,9 +332,6 @@
 		return False;
 	}
 
-	if (path[len] == 0) {
-		return True;
-	}
 	if (path[len] != '/') {
 		return False;
 	}
@@ -395,7 +392,9 @@
 	/* this needs to be changed to a log(n) search */
 	for (i=0;i<notify->array->num_entries;i++) {
 		if (notify_match(notify, &notify->array->entries[i], path, action)) {
-			notify_send(notify, &notify->array->entries[i], path, action);
+			notify_send(notify, &notify->array->entries[i], 
+				    path + strlen(notify->array->entries[i].path) + 1, 
+				    action);
 		}
 	}
 }

Modified: branches/SAMBA_4_0/source/ntvfs/posix/pvfs_mkdir.c
===================================================================
--- branches/SAMBA_4_0/source/ntvfs/posix/pvfs_mkdir.c	2006-03-29 10:20:28 UTC (rev 14754)
+++ branches/SAMBA_4_0/source/ntvfs/posix/pvfs_mkdir.c	2006-03-29 13:31:30 UTC (rev 14755)
@@ -83,6 +83,8 @@
 		return status;
 	}
 
+	notify_trigger(pvfs->notify_context, NOTIFY_ACTION_ADDED, name->full_name);
+
 	return NT_STATUS_OK;
 }
 
@@ -135,6 +137,8 @@
 		return status;
 	}
 
+	notify_trigger(pvfs->notify_context, NOTIFY_ACTION_ADDED, name->full_name);
+
 	return NT_STATUS_OK;
 }
 
@@ -172,5 +176,7 @@
 		return pvfs_map_errno(pvfs, errno);
 	}
 
+	notify_trigger(pvfs->notify_context, NOTIFY_ACTION_REMOVED, name->full_name);
+
 	return NT_STATUS_OK;
 }

Modified: branches/SAMBA_4_0/source/ntvfs/posix/pvfs_notify.c
===================================================================
--- branches/SAMBA_4_0/source/ntvfs/posix/pvfs_notify.c	2006-03-29 10:20:28 UTC (rev 14754)
+++ branches/SAMBA_4_0/source/ntvfs/posix/pvfs_notify.c	2006-03-29 13:31:30 UTC (rev 14755)
@@ -33,10 +33,13 @@
 	struct notify_changes *changes;
 	uint32_t max_buffer_size;
 	uint32_t current_buffer_size;
-	void *wait_handle;
+	
+	/* these last two are only present when a notify request is
+	   pending */
+	struct ntvfs_request *req;
+	struct smb_notify *info;
 };
 
-
 /*
   destroy a notify buffer. Called when the handle is closed
  */
@@ -48,14 +51,52 @@
 	return 0;
 }
 
+/*
+  send a reply to a pending notify request
+*/
+static void pvfs_notify_send(struct pvfs_notify_buffer *notify_buffer)
+{
+	struct ntvfs_request *req = notify_buffer->req;
+	struct smb_notify *info = notify_buffer->info;
 
+	info->out.num_changes = notify_buffer->num_changes;
+	info->out.changes = talloc_steal(req, notify_buffer->changes);
+	notify_buffer->num_changes = 0;
+	notify_buffer->changes = NULL;
+	notify_buffer->current_buffer_size = 0;
+	
+	notify_buffer->req = NULL;
+	notify_buffer->info = NULL;
+
+	DEBUG(0,("sending %d changes\n", info->out.num_changes));
+
+	if (info->out.num_changes == 0) {
+		req->async_states->status = NT_STATUS_CANCELLED;
+	} else {
+		req->async_states->status = NT_STATUS_OK;
+	}
+	req->async_states->send_fn(req);
+}
+
+
+
 /*
   called when a async notify event comes in
 */
 static void pvfs_notify_callback(void *private, const struct notify_event *ev)
 {
 	struct pvfs_notify_buffer *n = talloc_get_type(private, struct pvfs_notify_buffer);
-	DEBUG(0,("got notify for '%s'\n", ev->path));
+
+	n->changes = talloc_realloc(n, n->changes, struct notify_changes, n->num_changes+1);
+	n->changes[n->num_changes].action = ev->action;
+	n->changes[n->num_changes].name.s = talloc_strdup(n->changes, ev->path);
+	n->num_changes++;
+
+	DEBUG(0,("got notify for '%s' action=%d\n", ev->path, ev->action));
+
+	if (n->req != NULL) {
+		pvfs_notify_send(n);
+	}
 }
 
 /*
@@ -86,7 +127,23 @@
 	return NT_STATUS_OK;
 }
 
+/*
+  called from the pvfs_wait code when either an event has come in, or
+  the notify request has been cancelled
+*/
+static void pvfs_notify_end(void *private, enum pvfs_wait_notice reason)
+{
+	struct pvfs_notify_buffer *notify_buffer = talloc_get_type(private, struct pvfs_notify_buffer);
+	struct ntvfs_request *req = notify_buffer->req;
 
+	if (req == NULL) {
+		/* nothing to do, nobody is waiting */
+		return;
+	}
+
+	pvfs_notify_send(notify_buffer);
+}
+
 /* change notify request - always async. This request blocks until the
    event buffer is non-empty */
 NTSTATUS pvfs_notify(struct ntvfs_module_context *ntvfs, 
@@ -110,7 +167,7 @@
 
 	/* its only valid for directories */
 	if (f->handle->fd != -1) {
-		return NT_STATUS_NOT_A_DIRECTORY;
+		return NT_STATUS_INVALID_PARAMETER;
 	}
 
 	/* if the handle doesn't currently have a notify buffer then
@@ -123,19 +180,27 @@
 		NT_STATUS_NOT_OK_RETURN(status);
 	}
 
+	req->async_states->status = NT_STATUS_OK;
+	
+	if (f->notify_buffer->req != NULL) {
+		DEBUG(0,("Notify already setup\n"));
+		pvfs_notify_send(f->notify_buffer);
+	}
+
+	f->notify_buffer->req = talloc_reference(f->notify_buffer, req);
+	f->notify_buffer->info = info;
+
 	/* if the buffer is empty then start waiting */
 	if (f->notify_buffer->num_changes == 0) {
-		req->async_states->state |= NTVFS_ASYNC_STATE_ASYNC;
+		void *wait_handle =
+			pvfs_wait_message(pvfs, req, -1, timeval_zero(), 
+					  pvfs_notify_end, f->notify_buffer);
+		NT_STATUS_HAVE_NO_MEMORY(wait_handle);
+		talloc_steal(req, wait_handle);
 		return NT_STATUS_OK;
 	}
 
-	/* otherwise if the buffer is not empty then return its
-	   contents immediately */
-	info->out.num_changes = f->notify_buffer->num_changes;
-	info->out.changes = talloc_steal(req, f->notify_buffer->changes);
-	f->notify_buffer->num_changes = 0;
-	f->notify_buffer->changes = NULL;
-	f->notify_buffer->current_buffer_size = 0;
+	pvfs_notify_send(f->notify_buffer);
 
 	return NT_STATUS_OK;
 }

Modified: branches/SAMBA_4_0/source/ntvfs/posix/pvfs_wait.c
===================================================================
--- branches/SAMBA_4_0/source/ntvfs/posix/pvfs_wait.c	2006-03-29 10:20:28 UTC (rev 14754)
+++ branches/SAMBA_4_0/source/ntvfs/posix/pvfs_wait.c	2006-03-29 13:31:30 UTC (rev 14755)
@@ -105,7 +105,9 @@
 static int pvfs_wait_destructor(void *ptr)
 {
 	struct pvfs_wait *pwait = ptr;
-	messaging_deregister(pwait->msg_ctx, pwait->msg_type, pwait);
+	if (pwait->msg_type != -1) {
+		messaging_deregister(pwait->msg_ctx, pwait->msg_type, pwait);
+	}
 	DLIST_REMOVE(pwait->pvfs->wait_list, pwait);
 	return 0;
 }
@@ -116,6 +118,9 @@
 
   the return value is a handle. To stop waiting talloc_free this
   handle.
+
+  if msg_type == -1 then no message is registered, and it is assumed
+  that the caller handles any messaging setup needed
 */
 void *pvfs_wait_message(struct pvfs_state *pvfs, 
 			struct ntvfs_request *req, 
@@ -146,10 +151,12 @@
 
 	/* register with the messaging subsystem for this message
 	   type */
-	messaging_register(pwait->msg_ctx,
-			   pwait,
-			   msg_type,
-			   pvfs_wait_dispatch);
+	if (msg_type != -1) {
+		messaging_register(pwait->msg_ctx,
+				   pwait,
+				   msg_type,
+				   pvfs_wait_dispatch);
+	}
 
 	/* tell the main smb server layer that we will be replying 
 	   asynchronously */



More information about the samba-cvs mailing list