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.c41
1 files changed, 37 insertions, 4 deletions
diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c
index bc2d46bb95..1455b4d8e5 100644
--- a/source3/smbd/oplock.c
+++ b/source3/smbd/oplock.c
@@ -40,6 +40,29 @@ extern int smb_read_error;
static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval);
/****************************************************************************
+ Setup the kernel level oplock backchannel for this process.
+****************************************************************************/
+
+BOOL setup_kernel_oplock_pipe(void)
+{
+#if defined(HAVE_KERNEL_OPLOCKS)
+ if(lp_kernel_oplocks()) {
+ int pfd[2];
+
+ if(pipe(pfd) != 0) {
+ DEBUG(0,("setup_kernel_oplock_pipe: Unable to create pipe. Error was %s\n",
+ strerror(errno) ));
+ return False;
+ }
+
+ oplock_pipe_read = pfd[0];
+ oplock_pipe_write = pfd[1];
+ }
+#endif /* HAVE_KERNEL_OPLOCKS */
+ return True;
+}
+
+/****************************************************************************
open the oplock IPC socket communication
****************************************************************************/
BOOL open_oplock_ipc(void)
@@ -71,6 +94,9 @@ address %lx. Error was %s\n", (long)htonl(INADDR_LOOPBACK), strerror(errno)));
}
global_oplock_port = ntohs(sock_name.sin_port);
+ if(!setup_kernel_oplock_pipe())
+ return False;
+
DEBUG(3,("open_oplock ipc: pid = %d, global_oplock_port = %u\n",
(int)getpid(), global_oplock_port));
@@ -158,6 +184,13 @@ Error was %s.\n", strerror(errno) ));
if(fcntl(oplock_pipe_read, F_OPLKSTAT, &os) < 0) {
DEBUG(0,("receive_local_message: fcntl of kernel notification failed. \
Error was %s.\n", strerror(errno) ));
+ if(errno == EAGAIN) {
+ /*
+ * Duplicate kernel break message - ignore.
+ */
+ memset(buffer, '\0', KERNEL_OPLOCK_BREAK_MSG_LEN);
+ return True;
+ }
smb_read_error = READ_ERROR;
return False;
}
@@ -1056,7 +1089,7 @@ void check_kernel_oplocks(void)
return;
}
- if((fd = sys_open(tmpname, O_RDWR|O_CREAT|O_TRUNC|O_EXCL, 0600)) < 0) {
+ if((fd = sys_open(tmpname, O_RDWR|O_CREAT|O_EXCL|O_TRUNC, 0600)) < 0) {
DEBUG(0,("check_kernel_oplocks: Unable to open temp test file %s. Error was %s\n",
tmpname, strerror(errno) ));
unlink( tmpname );
@@ -1085,13 +1118,13 @@ Disabling kernel oplock support.\n", strerror(errno) ));
return;
}
- oplock_pipe_read = pfd[0];
- oplock_pipe_write = pfd[1];
+ close(pfd[0]);
+ close(pfd[1]);
close(fd);
lp_set_kernel_oplocks(True);
- DEBUG(3,("check_kernel_oplocks: Kernel oplocks available and set to %s.\n",
+ DEBUG(0,("check_kernel_oplocks: Kernel oplocks available and set to %s.\n",
lp_kernel_oplocks() ? "True" : "False" ));
}