diff options
-rw-r--r-- | source3/include/smb.h | 1 | ||||
-rw-r--r-- | source3/smbd/notify.c | 9 | ||||
-rw-r--r-- | source3/smbd/notify_fam.c | 36 | ||||
-rw-r--r-- | source3/smbd/notify_hash.c | 1 | ||||
-rw-r--r-- | source3/smbd/notify_kernel.c | 1 | ||||
-rw-r--r-- | source3/smbd/oplock.c | 15 | ||||
-rw-r--r-- | source3/smbd/process.c | 25 |
7 files changed, 60 insertions, 28 deletions
diff --git a/source3/include/smb.h b/source3/include/smb.h index dc03ba44d4..fd3c23e575 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1581,6 +1581,7 @@ struct cnotify_fns { BOOL (*check_notify)(connection_struct *conn, uint16 vuid, char *path, uint32 flags, void *data, time_t t); void (*remove_notify)(void *data); int select_time; + int notification_fd; }; #include "smb_macros.h" diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c index df3d45d20b..b2d0fc3326 100644 --- a/source3/smbd/notify.c +++ b/source3/smbd/notify.c @@ -206,6 +206,15 @@ BOOL change_notify_set(char *inbuf, files_struct *fsp, connection_struct *conn, return True; } +int change_notify_fd(void) +{ + if (cnotify) { + return cnotify->notification_fd; + } + + return -1; +} + /**************************************************************************** Initialise the change notify subsystem. ****************************************************************************/ diff --git a/source3/smbd/notify_fam.c b/source3/smbd/notify_fam.c index 413340266e..9f02bfdee9 100644 --- a/source3/smbd/notify_fam.c +++ b/source3/smbd/notify_fam.c @@ -63,9 +63,30 @@ static int global_fc_generation; #define FAM_TRACE 8 #define FAM_TRACE_LOW 10 -#define FAM_NOTIFY_CHECK_TIMEOUT 1 /* secs */ #define FAM_EVENT_DRAIN ((uint32_t)(-1)) +static void * fam_register_notify(connection_struct * conn, + char * path, + uint32 flags); + +static BOOL fam_check_notify(connection_struct * conn, + uint16_t vuid, + char * path, + uint32_t flags, + void * data, + time_t when); + +static void fam_remove_notify(void * data) + +static struct cnotify_fns global_fam_notify = +{ + fam_register_notify, + fam_check_notify, + fam_remove_notify, + -1, + -1 +}; + /* Turn a FAM event code into a string. Don't rely on specific code values, * because that might not work across all flavours of FAM. */ @@ -110,6 +131,7 @@ fam_check_reconnect(void) } } + global_fam_notify.notification_fd = FAMCONNECTION_GETFD(&global_fc); return(True); } @@ -420,18 +442,6 @@ fam_remove_notify(void * data) struct cnotify_fns * fam_notify_init(void) { - static struct cnotify_fns global_fam_notify = - { - fam_register_notify, - fam_check_notify, - fam_remove_notify, - FAM_NOTIFY_CHECK_TIMEOUT - }; - - /* TODO: rather than relying on FAM_NOTIFY_CHECK_TIMEOUT, we should have an - * API to push the FAM fd into the global server fd set. - */ - FAMCONNECTION_GETFD(&global_fc) = -1; if (!fam_test_connection()) { diff --git a/source3/smbd/notify_hash.c b/source3/smbd/notify_hash.c index 859a92a61e..a98a028fae 100644 --- a/source3/smbd/notify_hash.c +++ b/source3/smbd/notify_hash.c @@ -230,6 +230,7 @@ struct cnotify_fns *hash_notify_init(void) cnotify.check_notify = hash_check_notify; cnotify.remove_notify = hash_remove_notify; cnotify.select_time = lp_change_notify_timeout(); + cnotify.notification_fd = -1; return &cnotify; } diff --git a/source3/smbd/notify_kernel.c b/source3/smbd/notify_kernel.c index 02abe0b4b6..0c20effc3d 100644 --- a/source3/smbd/notify_kernel.c +++ b/source3/smbd/notify_kernel.c @@ -232,6 +232,7 @@ struct cnotify_fns *kernel_notify_init(void) cnotify.check_notify = kernel_check_notify; cnotify.remove_notify = kernel_remove_notify; cnotify.select_time = -1; + cnotify.notification_fd = -1; /* the signal can start off blocked due to a bug in bash */ BlockSignals(False, RT_SIGNAL_NOTIFY); diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index 755bcffc7f..41eb809909 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -240,21 +240,16 @@ BOOL downgrade_oplock(files_struct *fsp) } /**************************************************************************** - Setup the listening set of file descriptors for an oplock break - message either from the UDP socket or from the kernel. Returns the maximum - fd used. + Return the fd (if any) used for receiving oplock notifications. ****************************************************************************/ -int setup_oplock_select_set( fd_set *fds) +int oplock_notify_fd(void) { - int maxfd = 0; - - if (koplocks && koplocks->notification_fd != -1) { - FD_SET(koplocks->notification_fd, fds); - maxfd = MAX(maxfd, koplocks->notification_fd); + if (koplocks) { + return koplocks->notification_fd; } - return maxfd; + return -1; } /**************************************************************************** diff --git a/source3/smbd/process.c b/source3/smbd/process.c index d646ebe02d..2f19f909f2 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -283,7 +283,7 @@ struct idle_event *add_idle_event(TALLOC_CTX *mem_ctx, return result; } - + /**************************************************************************** Do all async processing in here. This includes kernel oplock messages, change notify events etc. @@ -319,6 +319,20 @@ static void async_processing(void) } /**************************************************************************** + Add a fd to the set we will be select(2)ing on. +****************************************************************************/ + +static int select_on_fd(int fd, int maxfd, fd_set *fds) +{ + if (fd != -1) { + FD_SET(fd, fds); + maxfd = MAX(maxfd, fd); + } + + return maxfd; +} + +/**************************************************************************** Do a select on an two fd's - with timeout. If a local udp message has been pushed onto the @@ -344,7 +358,7 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout) fd_set fds; int selrtn; struct timeval to = timeval_set(SMBD_SELECT_TIMEOUT, 0); - int maxfd; + int maxfd = 0; smb_read_error = 0; @@ -437,10 +451,11 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout) } } - FD_SET(smbd_server_fd(),&fds); - maxfd = setup_oplock_select_set(&fds); + maxfd = select_on_fd(smbd_server_fd(), maxfd, &fds); + maxfd = select_on_fd(change_notify_fd(), maxfd, &fds); + maxfd = select_on_fd(oplock_notify_fd(), maxfd, &fds); - selrtn = sys_select(MAX(maxfd,smbd_server_fd())+1,&fds,NULL,NULL,&to); + selrtn = sys_select(maxfd+1,&fds,NULL,NULL,&to); /* if we get EINTR then maybe we have received an oplock signal - treat this as select returning 1. This is ugly, but |