データ構造 | |
struct | fam_watch_context |
型定義 | |
typedef enum FAMCodes | FAMCodes |
関数 | |
static void | fam_handler (struct event_context *event_ctx, struct fd_event *fd_event, uint16 flags, void *private_data) |
static NTSTATUS | fam_open_connection (FAMConnection *fam_conn, struct event_context *event_ctx) |
static void | fam_reopen (FAMConnection *fam_conn, struct event_context *event_ctx, struct fam_watch_context *notify_list) |
static int | fam_watch_context_destructor (struct fam_watch_context *ctx) |
static NTSTATUS | fam_watch (vfs_handle_struct *vfs_handle, 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) |
NTSTATUS | vfs_notify_fam_init (void) |
変数 | |
static FAMConnection | fam_connection |
static BOOL | fam_connection_initialized = False |
static struct fam_watch_context * | fam_notify_list |
static vfs_op_tuple | notify_fam_op_tuples [] |
vfs_notify_fam.c の 30 行で定義されています。
static void fam_handler | ( | struct event_context * | event_ctx, | |
struct fd_event * | fd_event, | |||
uint16 | flags, | |||
void * | private_data | |||
) | [static] |
vfs_notify_fam.c の 133 行で定義されています。
参照先 notify_event::action・ctx・fam_notify_list・fam_reopen().
00137 { 00138 FAMConnection *fam_conn = (FAMConnection *)private_data; 00139 FAMEvent fam_event; 00140 struct fam_watch_context *ctx; 00141 struct notify_event ne; 00142 00143 if (FAMPending(fam_conn) == 0) { 00144 DEBUG(10, ("fam_handler called but nothing pending\n")); 00145 return; 00146 } 00147 00148 if (FAMNextEvent(fam_conn, &fam_event) != 1) { 00149 DEBUG(5, ("FAMNextEvent returned an error\n")); 00150 TALLOC_FREE(fd_event); 00151 fam_reopen(fam_conn, event_ctx, fam_notify_list); 00152 return; 00153 } 00154 00155 DEBUG(10, ("Got FAMCode %d for %s\n", fam_event.code, 00156 fam_event.filename)); 00157 00158 switch (fam_event.code) { 00159 case FAMChanged: 00160 ne.action = NOTIFY_ACTION_MODIFIED; 00161 break; 00162 case FAMCreated: 00163 ne.action = NOTIFY_ACTION_ADDED; 00164 break; 00165 case FAMDeleted: 00166 ne.action = NOTIFY_ACTION_REMOVED; 00167 break; 00168 default: 00169 DEBUG(10, ("Ignoring code FAMCode %d for file %s\n", 00170 (int)fam_event.code, fam_event.filename)); 00171 return; 00172 } 00173 00174 for (ctx = fam_notify_list; ctx; ctx = ctx->next) { 00175 if (memcmp(&fam_event.fr, &ctx->fr, sizeof(FAMRequest)) == 0) { 00176 break; 00177 } 00178 } 00179 00180 if (ctx == NULL) { 00181 DEBUG(5, ("Discarding event for file %s\n", 00182 fam_event.filename)); 00183 return; 00184 } 00185 00186 if ((ne.path = strrchr_m(fam_event.filename, '\\')) == NULL) { 00187 ne.path = fam_event.filename; 00188 } 00189 00190 ctx->callback(ctx->sys_ctx, ctx->private_data, &ne); 00191 }
static NTSTATUS fam_open_connection | ( | FAMConnection * | fam_conn, | |
struct event_context * | event_ctx | |||
) | [static] |
vfs_notify_fam.c の 74 行で定義されています。
参照先 asprintf()・event_add_fd()・fam_handler()・name・sys_getpid().
参照元 fam_reopen()・fam_watch().
00076 { 00077 int res; 00078 char *name; 00079 00080 ZERO_STRUCTP(fam_conn); 00081 FAMCONNECTION_GETFD(fam_conn) = -1; 00082 00083 if (asprintf(&name, "smbd (%lu)", (unsigned long)sys_getpid()) == -1) { 00084 DEBUG(0, ("No memory\n")); 00085 return NT_STATUS_NO_MEMORY; 00086 } 00087 00088 res = FAMOpen2(fam_conn, name); 00089 SAFE_FREE(name); 00090 00091 if (res < 0) { 00092 DEBUG(10, ("FAM file change notifications not available\n")); 00093 /* 00094 * No idea how to get NT_STATUS from a FAM result 00095 */ 00096 FAMCONNECTION_GETFD(fam_conn) = -1; 00097 return NT_STATUS_UNEXPECTED_IO_ERROR; 00098 } 00099 00100 if (event_add_fd(event_ctx, event_ctx, 00101 FAMCONNECTION_GETFD(fam_conn), 00102 EVENT_FD_READ, fam_handler, 00103 (void *)fam_conn) == NULL) { 00104 DEBUG(0, ("event_add_fd failed\n")); 00105 FAMClose(fam_conn); 00106 FAMCONNECTION_GETFD(fam_conn) = -1; 00107 return NT_STATUS_NO_MEMORY; 00108 } 00109 00110 return NT_STATUS_OK; 00111 }
static void fam_reopen | ( | FAMConnection * | fam_conn, | |
struct event_context * | event_ctx, | |||
struct fam_watch_context * | notify_list | |||
) | [static] |
vfs_notify_fam.c の 113 行で定義されています。
参照先 ctx・fam_open_connection().
参照元 fam_handler()・fam_watch().
00116 { 00117 struct fam_watch_context *ctx; 00118 00119 DEBUG(5, ("Re-opening FAM connection\n")); 00120 00121 FAMClose(fam_conn); 00122 00123 if (!NT_STATUS_IS_OK(fam_open_connection(fam_conn, event_ctx))) { 00124 DEBUG(5, ("Re-opening fam connection failed\n")); 00125 return; 00126 } 00127 00128 for (ctx = notify_list; ctx; ctx = ctx->next) { 00129 FAMMonitorDirectory(fam_conn, ctx->path, &ctx->fr, NULL); 00130 } 00131 }
static int fam_watch_context_destructor | ( | struct fam_watch_context * | ctx | ) | [static] |
vfs_notify_fam.c の 193 行で定義されています。
参照先 ctx・fam_connection・fam_notify_list.
参照元 fam_watch().
00194 { 00195 if (FAMCONNECTION_GETFD(ctx->fam_connection) != -1) { 00196 FAMCancelMonitor(&fam_connection, &ctx->fr); 00197 } 00198 DLIST_REMOVE(fam_notify_list, ctx); 00199 return 0; 00200 }
static NTSTATUS fam_watch | ( | vfs_handle_struct * | vfs_handle, | |
struct sys_notify_context * | ctx, | |||
struct notify_entry * | e, | |||
void(*)(struct sys_notify_context *ctx, void *private_data, struct notify_event *ev) | callback, | |||
void * | private_data, | |||
void * | handle_p | |||
) | [static] |
vfs_notify_fam.c の 206 行で定義されています。
参照先 fam_watch_context::callback・fam_watch_context::fam_connection・fam_connection・fam_connection_initialized・fam_notify_list・fam_open_connection()・fam_reopen()・fam_watch_context_destructor()・fam_watch_context::filter・notify_entry::filter・fam_watch_context::fr・handle・notify_entry::path・fam_watch_context::path・fam_watch_context::private_data・fam_watch_context::sys_ctx・talloc_strdup().
00214 { 00215 const uint32 fam_mask = (FILE_NOTIFY_CHANGE_FILE_NAME| 00216 FILE_NOTIFY_CHANGE_DIR_NAME); 00217 struct fam_watch_context *watch; 00218 void **handle = (void **)handle_p; 00219 00220 if ((e->filter & fam_mask) == 0) { 00221 DEBUG(10, ("filter = %u, ignoring in FAM\n", e->filter)); 00222 return NT_STATUS_OK; 00223 } 00224 00225 if (!fam_connection_initialized) { 00226 if (!NT_STATUS_IS_OK(fam_open_connection(&fam_connection, 00227 ctx->ev))) { 00228 /* 00229 * Just let smbd do all the work itself 00230 */ 00231 return NT_STATUS_OK; 00232 } 00233 fam_connection_initialized = True; 00234 } 00235 00236 if (!(watch = TALLOC_P(ctx, struct fam_watch_context))) { 00237 return NT_STATUS_NO_MEMORY; 00238 } 00239 00240 watch->fam_connection = &fam_connection; 00241 00242 watch->callback = callback; 00243 watch->private_data = private_data; 00244 watch->sys_ctx = ctx; 00245 00246 if (!(watch->path = talloc_strdup(watch, e->path))) { 00247 DEBUG(0, ("talloc_asprintf failed\n")); 00248 TALLOC_FREE(watch); 00249 return NT_STATUS_NO_MEMORY; 00250 } 00251 00252 /* 00253 * The FAM module in this early state will only take care of 00254 * FAMCreated and FAMDeleted events, Leave the rest to 00255 * notify_internal.c 00256 */ 00257 00258 watch->filter = fam_mask; 00259 e->filter &= ~fam_mask; 00260 00261 DLIST_ADD(fam_notify_list, watch); 00262 talloc_set_destructor(watch, fam_watch_context_destructor); 00263 00264 /* 00265 * Only directories monitored so far 00266 */ 00267 00268 if (FAMCONNECTION_GETFD(watch->fam_connection) != -1) { 00269 FAMMonitorDirectory(watch->fam_connection, watch->path, 00270 &watch->fr, NULL); 00271 } 00272 else { 00273 /* 00274 * If the re-open is successful, this will establish the 00275 * FAMMonitor from the list 00276 */ 00277 fam_reopen(watch->fam_connection, ctx->ev, fam_notify_list); 00278 } 00279 00280 *handle = (void *)watch; 00281 00282 return NT_STATUS_OK; 00283 }
NTSTATUS vfs_notify_fam_init | ( | void | ) |
vfs_notify_fam.c の 301 行で定義されています。
参照先 notify_fam_op_tuples・smb_register_vfs().
00302 { 00303 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "notify_fam", 00304 notify_fam_op_tuples); 00305 }
FAMConnection fam_connection [static] |
BOOL fam_connection_initialized = False [static] |
struct fam_watch_context* fam_notify_list [static] |
vfs_op_tuple notify_fam_op_tuples[] [static] |
初期値:
{ {SMB_VFS_OP(fam_watch), SMB_VFS_OP_NOTIFY_WATCH, SMB_VFS_LAYER_OPAQUE}, {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} }
vfs_notify_fam.c の 287 行で定義されています。