svn commit: samba r21092 - in branches/SAMBA_3_0/source: include smbd

vlendec at samba.org vlendec at samba.org
Wed Jan 31 14:42:56 GMT 2007


Author: vlendec
Date: 2007-01-31 14:42:56 +0000 (Wed, 31 Jan 2007)
New Revision: 21092

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

Log:
Ok, that's the one that activates the Samba4 notify backend.

Now to clean up / fix lots of stuff.

Volker

Modified:
   branches/SAMBA_3_0/source/include/smb.h
   branches/SAMBA_3_0/source/smbd/files.c
   branches/SAMBA_3_0/source/smbd/notify.c
   branches/SAMBA_3_0/source/smbd/nttrans.c
   branches/SAMBA_3_0/source/smbd/service.c


Changeset:
Modified: branches/SAMBA_3_0/source/include/smb.h
===================================================================
--- branches/SAMBA_3_0/source/include/smb.h	2007-01-31 14:36:50 UTC (rev 21091)
+++ branches/SAMBA_3_0/source/include/smb.h	2007-01-31 14:42:56 UTC (rev 21092)
@@ -669,6 +669,7 @@
 	name_compare_entry *aio_write_behind_list; /* Per-share list of files to use aio write behind on. */       
 	struct dfree_cached_info *dfree_info;
 	struct trans_state *pending_trans;
+	struct notify_context *notify_ctx;
 } connection_struct;
 
 struct current_user {

Modified: branches/SAMBA_3_0/source/smbd/files.c
===================================================================
--- branches/SAMBA_3_0/source/smbd/files.c	2007-01-31 14:36:50 UTC (rev 21091)
+++ branches/SAMBA_3_0/source/smbd/files.c	2007-01-31 14:42:56 UTC (rev 21092)
@@ -483,7 +483,10 @@
 		fsp->fh->ref_count--;
 	}
 
-	TALLOC_FREE(fsp->notify);
+	if (fsp->notify) {
+		notify_remove(fsp->conn->notify_ctx, fsp);
+		TALLOC_FREE(fsp->notify);
+	}
 
 	bitmap_clear(file_bmap, fsp->fnum - FILE_HANDLE_OFFSET);
 	files_used--;

Modified: branches/SAMBA_3_0/source/smbd/notify.c
===================================================================
--- branches/SAMBA_3_0/source/smbd/notify.c	2007-01-31 14:36:50 UTC (rev 21091)
+++ branches/SAMBA_3_0/source/smbd/notify.c	2007-01-31 14:42:56 UTC (rev 21092)
@@ -159,7 +159,8 @@
 }
 
 NTSTATUS change_notify_add_request(const char *inbuf, uint32 max_param_count,
-				   uint32 filter, struct files_struct *fsp)
+				   uint32 filter, BOOL recursive,
+				   struct files_struct *fsp)
 {
 	struct notify_change_request *request = NULL;
 	struct notify_mid_map *map = NULL;
@@ -177,9 +178,7 @@
 	request->max_param_count = max_param_count;
 	request->filter = filter;
 	request->fsp = fsp;
-
-	request->backend_data = cnotify->notify_add(NULL, smbd_event_context(),
-						    fsp, &request->filter);
+	request->backend_data = NULL;
 	
 	DLIST_ADD_END(fsp->notify->requests, request,
 		      struct notify_change_request *);
@@ -343,6 +342,18 @@
 		return;
 	}
 
+	{
+		char *fullpath;
+
+		if (asprintf(&fullpath, "%s/%s/%s", conn->connectpath,
+			     parent, name) != -1) {
+			notify_trigger(conn->notify_ctx, action, filter,
+				       fullpath);
+			SAFE_FREE(fullpath);
+		}
+		return;
+	}
+
 	if (!(lck = get_share_mode_lock(NULL, sbuf.st_dev, sbuf.st_ino,
 					NULL, NULL))) {
 		return;
@@ -405,20 +416,21 @@
 void notify_fname(connection_struct *conn, uint32 action, uint32 filter,
 		  const char *path)
 {
-	char *parent;
-	const char *name;
+	char *fullpath;
 
-	if (!parent_dirname_talloc(tmp_talloc_ctx(), path, &parent, &name)) {
+	if (asprintf(&fullpath, "%s/%s", conn->connectpath, path) == -1) {
+		DEBUG(0, ("asprintf failed\n"));
 		return;
 	}
 
-	notify_action(conn, parent, name, filter, action);
-	TALLOC_FREE(parent);
+	notify_trigger(conn->notify_ctx, action, filter, fullpath);
+	SAFE_FREE(fullpath);
 }
 
-void notify_fsp(files_struct *fsp, uint32 action, char *name)
+void notify_fsp(files_struct *fsp, uint32 action, const char *name)
 {
 	struct notify_change *change, *changes;
+	char *name2;
 
 	if (fsp->notify == NULL) {
 		/*
@@ -427,36 +439,13 @@
 		return;
 	}
 
-	if (fsp->notify->requests != NULL) {
-		/*
-		 * Someone is waiting for the change, trigger the reply
-		 * immediately.
-		 *
-		 * TODO: do we have to walk the lists of requests pending?
-		 */
-
-		struct notify_change_request *req = fsp->notify->requests;
-		struct notify_change onechange;
-
-		if (name == NULL) {
-			/*
-			 * Catch-all change, possibly from notify_hash.c
-			 */
-			change_notify_reply(req->request_buf,
-					    req->max_param_count,
-					    -1, NULL);
+	if (!(name2 = talloc_strdup(fsp->notify, name))) {
+		DEBUG(0, ("talloc_strdup failed\n"));
 			return;
 		}
 
-		onechange.action = action;
-		onechange.name = name;
+	string_replace(name2, '/', '\\');
 
-		change_notify_reply(req->request_buf, req->max_param_count,
-				    1, &onechange);
-		change_notify_remove_request(req);
-		return;
-	}
-
 	/*
 	 * Someone has triggered a notify previously, queue the change for
 	 * later. TODO: Limit the number of changes queued, test how filters
@@ -468,6 +457,7 @@
 		 * W2k3 seems to store at most 30 changes.
 		 */
 		TALLOC_FREE(fsp->notify->changes);
+		TALLOC_FREE(name2);
 		fsp->notify->num_changes = -1;
 		return;
 	}
@@ -480,6 +470,7 @@
 		      fsp->notify, fsp->notify->changes,
 		      struct notify_change, fsp->notify->num_changes+1))) {
 		DEBUG(0, ("talloc_realloc failed\n"));
+		TALLOC_FREE(name2);
 		return;
 	}
 
@@ -487,14 +478,40 @@
 
 	change = &(fsp->notify->changes[fsp->notify->num_changes]);
 
-	if (!(change->name = talloc_strdup(changes, name))) {
-		DEBUG(0, ("talloc_strdup failed\n"));
-		return;
-	}
+	change->name = talloc_move(changes, &name2);
 	change->action = action;
 	fsp->notify->num_changes += 1;
 
+	if (fsp->notify->requests == NULL) {
+		/*
+		 * Nobody is waiting, so don't send anything. The ot
+		 */
+		return;
+	}
+
+	if (action == NOTIFY_ACTION_OLD_NAME) {
+		/*
+		 * We have to send the two rename events in one reply. So hold
+		 * the first part back.
+		 */
 	return;
+	}
+
+	/*
+	 * Someone is waiting for the change, trigger the reply immediately.
+	 *
+	 * TODO: do we have to walk the lists of requests pending?
+	 */
+
+	change_notify_reply(fsp->notify->requests->request_buf,
+			    fsp->notify->requests->max_param_count,
+			    fsp->notify->num_changes,
+			    fsp->notify->changes);
+
+	change_notify_remove_request(fsp->notify->requests);
+
+	TALLOC_FREE(fsp->notify->changes);
+	fsp->notify->num_changes = 0;
 }
 
 static void notify_message_callback(int msgtype, struct process_id pid,

Modified: branches/SAMBA_3_0/source/smbd/nttrans.c
===================================================================
--- branches/SAMBA_3_0/source/smbd/nttrans.c	2007-01-31 14:36:50 UTC (rev 21091)
+++ branches/SAMBA_3_0/source/smbd/nttrans.c	2007-01-31 14:42:56 UTC (rev 21092)
@@ -1787,6 +1787,13 @@
  don't allow a directory to be opened.
 ****************************************************************************/
 
+static void notify_callback(void *private_data, const struct notify_event *e)
+{
+	files_struct *fsp = (files_struct *)private_data;
+	DEBUG(10, ("notify_callback called for %s\n", fsp->fsp_name));
+	notify_fsp(fsp, e->action, e->path);
+}
+
 static int call_nt_transact_notify_change(connection_struct *conn, char *inbuf,
 					  char *outbuf, int length,
 					  int bufsize, 
@@ -1801,6 +1808,7 @@
 	files_struct *fsp;
 	uint32 filter;
 	NTSTATUS status;
+	BOOL recursive;
 
 	if(setup_count < 6) {
 		return ERROR_DOS(ERRDOS,ERRbadfunc);
@@ -1808,6 +1816,7 @@
 
 	fsp = file_fsp((char *)setup,4);
 	filter = IVAL(setup, 0);
+	recursive = (SVAL(setup, 6) != 0) ? True : False;
 
 	DEBUG(3,("call_nt_transact_notify_change\n"));
 
@@ -1815,18 +1824,55 @@
 		return ERROR_DOS(ERRDOS,ERRbadfid);
 	}
 
-	DEBUG(3,("call_nt_transact_notify_change: notify change called on "
-		 "directory name = %s\n", fsp->fsp_name ));
+	{
+		char *filter_string;
 
+		if (!(filter_string = notify_filter_string(NULL, filter))) {
+			return ERROR_NT(NT_STATUS_NO_MEMORY);
+		}
+
+		DEBUG(3,("call_nt_transact_notify_change: notify change "
+			 "called on %s, filter = %s, recursive = %d\n",
+			 fsp->fsp_name, filter_string, recursive));
+
+		TALLOC_FREE(filter_string);
+	}
+
 	if((!fsp->is_directory) || (conn != fsp->conn)) {
 		return ERROR_DOS(ERRDOS,ERRbadfid);
 	}
 
 	if (fsp->notify == NULL) {
+		char *fullpath;
+		struct notify_entry e;
+
 		if (!(fsp->notify = TALLOC_ZERO_P(
 			      NULL, struct notify_change_buf))) {
 			return ERROR_NT(NT_STATUS_NO_MEMORY);
 		}
+
+		if (asprintf(&fullpath, "%s/%s", fsp->conn->connectpath,
+			     fsp->fsp_name) == -1) {
+			DEBUG(0, ("asprintf failed\n"));
+			return ERROR_NT(NT_STATUS_NO_MEMORY);
+		}
+
+		e.path = fullpath;
+		e.filter = filter;
+		e.subdir_filter = 0;
+		if (recursive) {
+			e.subdir_filter = filter;
+		}
+
+		status = notify_add(fsp->conn->notify_ctx, &e, notify_callback,
+				    fsp);
+		SAFE_FREE(fullpath);
+
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(10, ("notify_add returned %s\n",
+				   nt_errstr(status)));
+			return ERROR_NT(status);
+		}
 	}
 
 	if (fsp->notify->num_changes != 0) {
@@ -1840,8 +1886,6 @@
 		 * here.
 		 */
 
-		SMB_ASSERT(fsp->notify->requests == NULL);
-
 		change_notify_reply(inbuf, max_param_count,
 				    fsp->notify->num_changes,
 				    fsp->notify->changes);
@@ -1861,7 +1905,7 @@
 	 */
 
 	status = change_notify_add_request(inbuf, max_param_count, filter,
-					   fsp);
+					   recursive, fsp);
 	if (!NT_STATUS_IS_OK(status)) {
 		return ERROR_NT(status);
 	}

Modified: branches/SAMBA_3_0/source/smbd/service.c
===================================================================
--- branches/SAMBA_3_0/source/smbd/service.c	2007-01-31 14:36:50 UTC (rev 21091)
+++ branches/SAMBA_3_0/source/smbd/service.c	2007-01-31 14:42:56 UTC (rev 21092)
@@ -946,6 +946,13 @@
 		set_conn_connectpath(conn,s);
 	}
 
+	if ((!conn->printer) && (!conn->ipc)) {
+		conn->notify_ctx = notify_init(conn->mem_ctx, server_id_self(),
+					       smbd_messaging_context(),
+					       smbd_event_context(),
+					       conn->params);
+	}
+
 /* ROOT Activities: */	
 	/* check number of connections */
 	if (!claim_connection(conn,



More information about the samba-cvs mailing list