svn commit: samba r21107 - in branches/SAMBA_3_0/source/smbd: .

vlendec at samba.org vlendec at samba.org
Thu Feb 1 12:36:22 GMT 2007


Author: vlendec
Date: 2007-02-01 12:36:21 +0000 (Thu, 01 Feb 2007)
New Revision: 21107

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

Log:
Adapt notify_fam.c to the new infrastructure. This works in my test, but does
not survive the raw-notify test just because famd is too slow. Events are
coming in too late and are thus unsyncronized.

Now to get that through the VFS.

Volker


Modified:
   branches/SAMBA_3_0/source/smbd/notify_fam.c


Changeset:
Modified: branches/SAMBA_3_0/source/smbd/notify_fam.c
===================================================================
--- branches/SAMBA_3_0/source/smbd/notify_fam.c	2007-02-01 12:24:08 UTC (rev 21106)
+++ branches/SAMBA_3_0/source/smbd/notify_fam.c	2007-02-01 12:36:21 UTC (rev 21107)
@@ -21,7 +21,7 @@
 
 #include "includes.h"
 
-#if 0
+#ifdef HAVE_FAM_CHANGE_NOTIFY
 
 #include <fam.h>
 
@@ -44,23 +44,30 @@
  *	http://sourceforge.net/projects/bsdfam/
  */
 
-static void *fam_notify_add(TALLOC_CTX *mem_ctx,
-			    struct event_context *event_ctx,
-			    files_struct *fsp, uint32 *filter);
-
 /* ------------------------------------------------------------------------- */
 
-struct fam_notify_ctx {
-	struct fam_notify_ctx *prev, *next;
+struct fam_watch_context {
+	struct fam_watch_context *prev, *next;
 	FAMConnection *fam_connection;
 	struct FAMRequest fr;
-	files_struct *fsp;
-	char *path;
-	uint32 filter;
+	struct sys_notify_context *sys_ctx;
+	void (*callback)(struct sys_notify_context *ctx, 
+			 void *private_data,
+			 struct notify_event *ev);
+	void *private_data;
+	uint32_t mask; /* the inotify mask */
+	uint32_t filter; /* the windows completion filter */
+	const char *path;
 };
 
-static struct fam_notify_ctx *fam_notify_list;
+
+/*
+ * We want one FAM connection per smbd, not one per tcon.
+ */
 static FAMConnection fam_connection;
+static BOOL fam_connection_initialized = False;
+
+static struct fam_watch_context *fam_notify_list;
 static void fam_handler(struct event_context *event_ctx,
 			struct fd_event *fd_event,
 			uint16 flags,
@@ -84,7 +91,7 @@
 	SAFE_FREE(name);
 
 	if (res < 0) {
-		DEBUG(5, ("FAM file change notifications not available\n"));
+		DEBUG(10, ("FAM file change notifications not available\n"));
 		/*
 		 * No idea how to get NT_STATUS from a FAM result
 		 */
@@ -107,9 +114,9 @@
 
 static void fam_reopen(FAMConnection *fam_conn,
 		       struct event_context *event_ctx,
-		       struct fam_notify_ctx *notify_list)
+		       struct fam_watch_context *notify_list)
 {
-	struct fam_notify_ctx *ctx;
+	struct fam_watch_context *ctx;
 
 	DEBUG(5, ("Re-opening FAM connection\n"));
 
@@ -132,8 +139,8 @@
 {
 	FAMConnection *fam_conn = (FAMConnection *)private_data;
 	FAMEvent fam_event;
-	struct fam_notify_ctx *ctx;
-	char *name;
+	struct fam_watch_context *ctx;
+	struct notify_event ne;
 
 	if (FAMPending(fam_conn) == 0) {
 		DEBUG(10, ("fam_handler called but nothing pending\n"));
@@ -141,13 +148,23 @@
 	}
 
 	if (FAMNextEvent(fam_conn, &fam_event) != 1) {
-		DEBUG(10, ("FAMNextEvent returned an error\n"));
+		DEBUG(5, ("FAMNextEvent returned an error\n"));
 		TALLOC_FREE(fd_event);
 		fam_reopen(fam_conn, event_ctx, fam_notify_list);
 		return;
 	}
 
-	if ((fam_event.code != FAMCreated) && (fam_event.code != FAMDeleted)) {
+	DEBUG(10, ("Got FAMCode %d for %s\n", fam_event.code,
+		   fam_event.filename));
+
+	switch (fam_event.code) {
+	case FAMCreated:
+		ne.action = NOTIFY_ACTION_ADDED;
+		break;
+	case FAMDeleted:
+		ne.action = NOTIFY_ACTION_REMOVED;
+		break;
+	default:
 		DEBUG(10, ("Ignoring code FAMCode %d for file %s\n",
 			   (int)fam_event.code, fam_event.filename));
 		return;
@@ -165,17 +182,14 @@
 		return;
 	}
 
-	if ((name = strrchr_m(fam_event.filename, '\\')) == NULL) {
-		name = fam_event.filename;
+	if ((ne.path = strrchr_m(fam_event.filename, '\\')) == NULL) {
+		ne.path = fam_event.filename;
 	}
 
-	notify_fsp(ctx->fsp,
-		   fam_event.code == FAMCreated
-		   ? NOTIFY_ACTION_ADDED : NOTIFY_ACTION_REMOVED,
-		   name);
+	ctx->callback(ctx->sys_ctx, ctx->private_data, &ne);
 }
 
-static int fam_notify_ctx_destructor(struct fam_notify_ctx *ctx)
+static int fam_watch_context_destructor(struct fam_watch_context *ctx)
 {
 	if (FAMCONNECTION_GETFD(ctx->fam_connection) != -1) {
 		FAMCancelMonitor(&fam_connection, &ctx->fr);
@@ -184,86 +198,86 @@
 	return 0;
 }
 
-static void *fam_notify_add(TALLOC_CTX *mem_ctx,
-			    struct event_context *event_ctx,
-			    files_struct *fsp, uint32 *filter)
+/*
+  add a watch. The watch is removed when the caller calls
+  talloc_free() on *handle
+*/
+NTSTATUS fam_watch(struct sys_notify_context *ctx,
+		   struct notify_entry *e,
+		   void (*callback)(struct sys_notify_context *ctx, 
+				    void *private_data,
+				    struct notify_event *ev),
+		   void *private_data, 
+		   void *handle_p)
 {
-	struct fam_notify_ctx *ctx;
+	const uint32 fam_mask = (FILE_NOTIFY_CHANGE_FILE_NAME|
+				 FILE_NOTIFY_CHANGE_DIR_NAME);
+	struct fam_watch_context *watch;
+	void **handle = (void **)handle_p;
 
-	if ((*filter & FILE_NOTIFY_CHANGE_FILE_NAME) == 0) {
-		DEBUG(10, ("filter = %u, no FILE_NOTIFY_CHANGE_FILE_NAME\n",
-			   *filter));
-		return NULL;
+	if ((e->filter & fam_mask) == 0) {
+		DEBUG(10, ("filter = %u, ignoring in FAM\n", e->filter));
+		return NT_STATUS_OK;
 	}
 
-	if (!(ctx = TALLOC_P(mem_ctx, struct fam_notify_ctx))) {
-		return NULL;
+	if (!fam_connection_initialized) {
+		if (!NT_STATUS_IS_OK(fam_open_connection(&fam_connection,
+							 ctx->ev))) {
+			/*
+			 * Just let smbd do all the work itself
+			 */
+			return NT_STATUS_OK;
+		}
+		fam_connection_initialized = True;
 	}
 
-	ctx->fsp = fsp;
-	ctx->fam_connection = &fam_connection;
+	if (!(watch = TALLOC_P(ctx, struct fam_watch_context))) {
+		return NT_STATUS_NO_MEMORY;
+	}
 
-	/*
-	 * The FAM module in this early state will only take care of
-	 * FAMCreated and FAMDeleted events
-	 */
+	watch->fam_connection = &fam_connection;
 
-	ctx->filter = FILE_NOTIFY_CHANGE_FILE_NAME;
+	watch->callback = callback;
+	watch->private_data = private_data;
+	watch->sys_ctx = ctx;
 
-	if (!(ctx->path = talloc_asprintf(ctx, "%s/%s", fsp->conn->connectpath,
-					  fsp->fsp_name))) {
+	if (!(watch->path = talloc_strdup(watch, e->path))) {
 		DEBUG(0, ("talloc_asprintf failed\n"));
-		TALLOC_FREE(ctx);
-		return NULL;
+		TALLOC_FREE(watch);
+		return NT_STATUS_NO_MEMORY;
 	}
 
 	/*
-	 * Leave the rest to smbd itself
+	 * The FAM module in this early state will only take care of
+	 * FAMCreated and FAMDeleted events, Leave the rest to
+	 * notify_internal.c
 	 */
 
-	*filter &= ~FILE_NOTIFY_CHANGE_FILE_NAME;
+	watch->filter = fam_mask;
+	e->filter &= ~fam_mask;
 
-	DLIST_ADD(fam_notify_list, ctx);
-	talloc_set_destructor(ctx, fam_notify_ctx_destructor);
+	DLIST_ADD(fam_notify_list, watch);
+	talloc_set_destructor(watch, fam_watch_context_destructor);
 
 	/*
 	 * Only directories monitored so far
 	 */
 
-	if (FAMCONNECTION_GETFD(ctx->fam_connection) != -1) {
-		FAMMonitorDirectory(ctx->fam_connection, ctx->path, &ctx->fr,
-				    NULL);
+	if (FAMCONNECTION_GETFD(watch->fam_connection) != -1) {
+		FAMMonitorDirectory(watch->fam_connection, watch->path,
+				    &watch->fr, NULL);
 	}
 	else {
 		/*
 		 * If the re-open is successful, this will establish the
 		 * FAMMonitor from the list
 		 */
-		fam_reopen(ctx->fam_connection, event_ctx, fam_notify_list);
+		fam_reopen(watch->fam_connection, ctx->ev, fam_notify_list);
 	}
 
-	return ctx;
-}
+	*handle = (void *)watch;
 
-static struct cnotify_fns global_fam_notify =
-{
-    fam_notify_add,
-};
-
-struct cnotify_fns *fam_notify_init(struct event_context *event_ctx)
-{
-
-	ZERO_STRUCT(fam_connection);
-	FAMCONNECTION_GETFD(&fam_connection) = -1;
-
-	if (!NT_STATUS_IS_OK(fam_open_connection(&fam_connection,
-						 event_ctx))) {
-		DEBUG(0, ("FAM file change notifications not available\n"));
-		return NULL;
-	}
-
-	DEBUG(10, ("enabling FAM change notifications\n"));
-	return &global_fam_notify;
+	return NT_STATUS_OK;
 }
 
 #endif /* HAVE_FAM_CHANGE_NOTIFY */



More information about the samba-cvs mailing list