diff options
Diffstat (limited to 'source3/smbd/oplock.c')
-rw-r--r-- | source3/smbd/oplock.c | 79 |
1 files changed, 26 insertions, 53 deletions
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index 14b243b36e..23606f1d14 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -72,69 +72,34 @@ BOOL oplock_message_waiting(fd_set *fds) ****************************************************************************/ -BOOL receive_local_message( char *buffer, int buffer_len, int timeout) +BOOL receive_local_message(fd_set *fds, char *buffer, int buffer_len, int timeout) { struct sockaddr_in from; - socklen_t fromlen = sizeof(from); + int fromlen = sizeof(from); int32 msg_len = 0; - fd_set fds; - int selrtn = -1; - 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 - * already been eaten. JRA. - */ - - if (koplocks && koplocks->msg_waiting(&fds)) { - return koplocks->receive_message(&fds, buffer, buffer_len); - } - - while (timeout > 0 && selrtn == -1) { + if(timeout != 0) { struct timeval to; + int selrtn; int maxfd = oplock_sock; - time_t starttime = time(NULL); - FD_ZERO(&fds); - maxfd = setup_oplock_select_set(&fds); + if (koplocks && koplocks->notification_fd != -1) { + FD_SET(koplocks->notification_fd, fds); + maxfd = MAX(maxfd, koplocks->notification_fd); + } to.tv_sec = timeout / 1000; to.tv_usec = (timeout % 1000) * 1000; - DEBUG(5,("receive_local_message: doing select with timeout of %d ms\n", timeout)); - - selrtn = sys_select(maxfd+1,&fds,NULL,NULL,&to); + selrtn = sys_select(maxfd+1,fds,NULL,NULL,&to); if (selrtn == -1 && errno == EINTR) { - /* could be a kernel oplock interrupt */ - if (koplocks && koplocks->msg_waiting(&fds)) { - return koplocks->receive_message(&fds, buffer, buffer_len); - } - - /* - * Linux 2.0.x seems to have a bug in that - * it can return -1, EINTR with a timeout of zero. - * Make sure we bail out here with a read timeout - * if we got EINTR on a timeout of 1 or less. - */ - - if (timeout <= 1) { - smb_read_error = READ_TIMEOUT; - return False; + if (koplocks && koplocks->msg_waiting(fds)) { + return koplocks->receive_message(fds, buffer, buffer_len); } - - /* Not a kernel interrupt - could be a SIGUSR1 message. We must restart. */ - /* We need to decrement the timeout here. */ - timeout -= ((time(NULL) - starttime)*1000); - if (timeout < 0) - timeout = 1; - - DEBUG(5,("receive_local_message: EINTR : new timeout %d ms\n", timeout)); - continue; } /* Check if error */ @@ -151,11 +116,11 @@ BOOL receive_local_message( char *buffer, int buffer_len, int timeout) } } - if (koplocks && koplocks->msg_waiting(&fds)) { - return koplocks->receive_message(&fds, buffer, buffer_len); + if (koplocks && koplocks->msg_waiting(fds)) { + return koplocks->receive_message(fds, buffer, buffer_len); } - if (!FD_ISSET(oplock_sock, &fds)) + if (!FD_ISSET(oplock_sock, fds)) return False; /* @@ -166,7 +131,7 @@ BOOL receive_local_message( char *buffer, int buffer_len, int timeout) /* * Read a loopback udp message. */ - msg_len = sys_recvfrom(oplock_sock, &buffer[OPBRK_CMD_HEADER_LEN], + msg_len = recvfrom(oplock_sock, &buffer[OPBRK_CMD_HEADER_LEN], buffer_len - OPBRK_CMD_HEADER_LEN, 0, (struct sockaddr *)&from, &fromlen); if(msg_len < 0) { @@ -452,7 +417,7 @@ oplocks. Returning success.\n")); toaddr.sin_port = htons(from_port); toaddr.sin_family = AF_INET; - if(sys_sendto( oplock_sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0, + if(sendto( oplock_sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0, (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0) { DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n", (int)remotepid, strerror(errno))); @@ -965,7 +930,7 @@ dev = %x, inode = %.0f, file_id = %lu and no fsp found !\n", (unsigned int)dev, (double)inode, file_id ); } - if(sys_sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0, + if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0, (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0) { if( DEBUGLVL( 0 ) ) { dbgtext( "request_oplock_break: failed when sending a oplock " ); @@ -1002,8 +967,16 @@ dev = %x, inode = %.0f, file_id = %lu and no fsp found !\n", char op_break_reply[OPBRK_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN]; uint16 reply_from_port; char *reply_msg_start; + fd_set fds; + + FD_ZERO(&fds); + FD_SET(oplock_sock,&fds); + + if (koplocks && koplocks->notification_fd != -1) { + FD_SET(koplocks->notification_fd, &fds); + } - if(receive_local_message(op_break_reply, sizeof(op_break_reply), + if(receive_local_message(&fds, op_break_reply, sizeof(op_break_reply), time_left ? time_left * 1000 : 1) == False) { if(smb_read_error == READ_TIMEOUT) { if( DEBUGLVL( 0 ) ) { |