From 5c149702b0885db8d63f189f4bba0e17fdaad7a4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 14 Feb 2006 23:00:39 +0000 Subject: r13498: Fix the kernel oplocks code for IRIX. Should fix #3515. Jeremy. (This used to be commit 006cf9c3654e7f18e01b75a5fe87798df862d26a) --- source3/smbd/oplock.c | 23 +++++++---------------- source3/smbd/oplock_irix.c | 27 ++++++++++++++++++++++++++- source3/smbd/process.c | 12 ++++++------ 3 files changed, 39 insertions(+), 23 deletions(-) (limited to 'source3') diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index 41eb809909..3efd630649 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -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 " diff --git a/source3/smbd/oplock_irix.c b/source3/smbd/oplock_irix.c index 2224f9a668..29bbb0f2ca 100644 --- a/source3/smbd/oplock_irix.c +++ b/source3/smbd/oplock_irix.c @@ -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; } /**************************************************************************** diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 2f19f909f2..9d35252e28 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -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; } -- cgit