r13498: Fix the kernel oplocks code for IRIX. Should fix #3515.
authorJeremy Allison <jra@samba.org>
Tue, 14 Feb 2006 23:00:39 +0000 (23:00 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:10:07 +0000 (11:10 -0500)
Jeremy.
(This used to be commit 006cf9c3654e7f18e01b75a5fe87798df862d26a)

source3/smbd/oplock.c
source3/smbd/oplock_irix.c
source3/smbd/process.c

index 41eb809909c19f07b336c7576ce1cc3324d0d5ad..3efd63064908f5bd60ce46941cdab8ce57c22159 100644 (file)
@@ -56,23 +56,14 @@ BOOL oplock_message_waiting(fd_set *fds)
 }
 
 /****************************************************************************
- Read an oplock break message from either the oplock UDP fd or the
- kernel (if kernel oplocks are supported).
-
- If timeout is zero then *fds contains the file descriptors that
- are ready to be read and acted upon. If timeout is non-zero then
- *fds contains the file descriptors to be selected on for read.
- The timeout is in milliseconds
-
+ Find out if there are any kernel oplock messages waiting and process them
+ if so. pfds is the fd_set from the main select loop (which contains any
+ kernel oplock fd if that's what the system uses (IRIX). If may be NULL if
+ we're calling this in a shutting down state.
 ****************************************************************************/
 
-void process_kernel_oplocks(void)
+void process_kernel_oplocks(fd_set *pfds)
 {
-       fd_set fds;
-
-       FD_ZERO(&fds);
-       smb_read_error = 0;
-
        /*
         * We need to check for kernel oplocks before going into the select
         * here, as the EINTR generated by the linux kernel oplock may have
@@ -83,11 +74,11 @@ void process_kernel_oplocks(void)
                return;
        }
 
-       while (koplocks->msg_waiting(&fds)) { 
+       while (koplocks->msg_waiting(pfds)) { 
                files_struct *fsp;
                char msg[MSG_SMB_KERNEL_BREAK_SIZE];
 
-               fsp = koplocks->receive_message(&fds);
+               fsp = koplocks->receive_message(pfds);
 
                if (fsp == NULL) {
                        DEBUG(3, ("Kernel oplock message announced, but none "
index 2224f9a668283fb09345b272e929dd461f78755b..29bbb0f2cacb486a4ae726fe2bb0381841c0c3f2 100644 (file)
@@ -93,6 +93,9 @@ static files_struct *irix_oplock_receive_message(fd_set *fds)
        char dummy;
        files_struct *fsp;
 
+       /* Ensure we only get one call per select fd set. */
+       FD_CLR(fds, oplock_pipe_read);
+
        /*
         * Read one byte of zero to clear the
         * kernel break notify message.
@@ -204,14 +207,36 @@ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
 
 /****************************************************************************
  Set *maxfd to include oplock read pipe.
+ Note that fds MAY BE NULL ! If so we must do our own select.
 ****************************************************************************/
 
 static BOOL irix_oplock_msg_waiting(fd_set *fds)
 {
+       int maxfd, selrtn;
+       fd_set myfds;
+       struct timeval to;
+
        if (oplock_pipe_read == -1)
                return False;
 
-       return FD_ISSET(oplock_pipe_read,fds);
+       if (fds) {
+               return FD_ISSET(oplock_pipe_read,fds);
+       }
+
+       FD_ZERO(&myfds);
+       maxfd = setup_oplock_select_set(&myfds);
+       /* Only do the select if we have something to select *on*. */
+       if (maxfd == 0) {
+               return False;
+       }
+
+       /* Do a zero-time select. We just need to find out if there
+        * are any outstanding messages. We use sys_select_intr as
+        * we need to ignore any signals. */
+
+       to = timeval_set(0, 0);
+       selrtn = sys_select_intr(maxfd+1,&myfds,NULL,NULL,&to);
+       return (selrtn == 1) ? True : False;
 }
 
 /****************************************************************************
index 2f19f909f2e4df841a5a42c705ca0d6f0e8fbef4..9d35252e28b58bd564bafa4c4884017ac9d0f72f 100644 (file)
@@ -289,13 +289,13 @@ struct idle_event *add_idle_event(TALLOC_CTX *mem_ctx,
  notify events etc.
 ****************************************************************************/
 
-static void async_processing(void)
+static void async_processing(fd_set *pfds)
 {
        DEBUG(10,("async_processing: Doing async processing.\n"));
 
        process_aio_queue();
 
-       process_kernel_oplocks();
+       process_kernel_oplocks(pfds);
 
        /* Do the aio check again after receive_local_message as it does a
           select and may have eaten our signal. */
@@ -432,7 +432,7 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
 
        if (oplock_message_waiting(&fds)) {
                DEBUG(10,("receive_message_or_smb: oplock_message is waiting.\n"));
-               async_processing();
+               async_processing(&fds);
                /*
                 * After async processing we must go and do the select again, as
                 * the state of the flag in fds for the server file descriptor is
@@ -462,7 +462,7 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
           is the best we can do until the oplock code knows more about
           signals */
        if (selrtn == -1 && errno == EINTR) {
-               async_processing();
+               async_processing(&fds);
                /*
                 * After async processing we must go and do the select again, as
                 * the state of the flag in fds for the server file descriptor is
@@ -491,7 +491,7 @@ static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
         */
 
        if (oplock_message_waiting(&fds)) {
-               async_processing();
+               async_processing(&fds);
                /*
                 * After async processing we must go and do the select again, as
                 * the state of the flag in fds for the server file descriptor is
@@ -540,7 +540,7 @@ void respond_to_all_remaining_local_messages(void)
                return;
        }
 
-       process_kernel_oplocks();
+       process_kernel_oplocks(NULL);
 
        return;
 }