summaryrefslogtreecommitdiff
path: root/source3/smbd/oplock.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd/oplock.c')
-rw-r--r--source3/smbd/oplock.c79
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 ) ) {