summaryrefslogtreecommitdiff
path: root/source3/smbd/oplock_linux.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd/oplock_linux.c')
-rw-r--r--source3/smbd/oplock_linux.c57
1 files changed, 27 insertions, 30 deletions
diff --git a/source3/smbd/oplock_linux.c b/source3/smbd/oplock_linux.c
index 85f89c12a0..d946578380 100644
--- a/source3/smbd/oplock_linux.c
+++ b/source3/smbd/oplock_linux.c
@@ -22,9 +22,9 @@
#if HAVE_KERNEL_OPLOCKS_LINUX
-static SIG_ATOMIC_T signals_received;
-#define FD_PENDING_SIZE 100
-static SIG_ATOMIC_T fd_pending_array[FD_PENDING_SIZE];
+static VOLATILE sig_atomic_t signals_received;
+static VOLATILE sig_atomic_t signals_processed;
+static VOLATILE sig_atomic_t fd_pending; /* the fd of the current pending signal */
#ifndef F_SETLEASE
#define F_SETLEASE 1024
@@ -52,10 +52,9 @@ static SIG_ATOMIC_T fd_pending_array[FD_PENDING_SIZE];
static void signal_handler(int sig, siginfo_t *info, void *unused)
{
- if (signals_received < FD_PENDING_SIZE - 1) {
- fd_pending_array[signals_received] = (SIG_ATOMIC_T)info->si_fd;
- signals_received++;
- } /* Else signal is lost. */
+ BlockSignals(True, sig);
+ fd_pending = (sig_atomic_t)info->si_fd;
+ signals_received++;
sys_select_signal();
}
@@ -125,28 +124,20 @@ static int linux_setlease(int fd, int leasetype)
static BOOL linux_oplock_receive_message(fd_set *fds, char *buffer, int buffer_len)
{
- int fd;
+ BOOL ret = True;
struct files_struct *fsp;
- BlockSignals(True, RT_SIGNAL_LEASE);
- fd = fd_pending_array[0];
- fsp = file_find_fd(fd);
- fd_pending_array[0] = (SIG_ATOMIC_T)-1;
- if (signals_received > 1)
- memmove((void *)&fd_pending_array[0], (void *)&fd_pending_array[1],
- sizeof(SIG_ATOMIC_T)*(signals_received-1));
- signals_received--;
- /* now we can receive more signals */
- BlockSignals(False, RT_SIGNAL_LEASE);
-
- if (fsp == NULL) {
- DEBUG(0,("Invalid file descriptor %d in kernel oplock break!\n", (int)fd));
+ if (signals_received == signals_processed)
return False;
+
+ if ((fsp = file_find_fd(fd_pending)) == NULL) {
+ DEBUG(0,("Invalid file descriptor %d in kernel oplock break!\n", (int)fd_pending));
+ ret = False;
+ goto out;
}
- DEBUG(3,("linux_oplock_receive_message: kernel oplock break request received for \
-dev = %x, inode = %.0f fd = %d, fileid = %lu \n", (unsigned int)fsp->dev, (double)fsp->inode,
- fd, fsp->file_id));
+ DEBUG(3,("receive_local_message: kernel oplock break request received for \
+dev = %x, inode = %.0f\n", (unsigned int)fsp->dev, (double)fsp->inode ));
/*
* Create a kernel oplock break message.
@@ -164,7 +155,13 @@ dev = %x, inode = %.0f fd = %d, fileid = %lu \n", (unsigned int)fsp->dev, (doubl
memcpy(buffer + KERNEL_OPLOCK_BREAK_INODE_OFFSET, (char *)&fsp->inode, sizeof(fsp->inode));
memcpy(buffer + KERNEL_OPLOCK_BREAK_FILEID_OFFSET, (char *)&fsp->file_id, sizeof(fsp->file_id));
- return True;
+ out:
+ /* now we can receive more signals */
+ fd_pending = (sig_atomic_t)-1;
+ signals_processed++;
+ BlockSignals(False, RT_SIGNAL_LEASE);
+
+ return ret;
}
/****************************************************************************
@@ -174,14 +171,14 @@ dev = %x, inode = %.0f fd = %d, fileid = %lu \n", (unsigned int)fsp->dev, (doubl
static BOOL linux_set_kernel_oplock(files_struct *fsp, int oplock_type)
{
if (linux_setlease(fsp->fd, F_WRLCK) == -1) {
- DEBUG(3,("linux_set_kernel_oplock: Refused oplock on file %s, fd = %d, dev = %x, \
+ DEBUG(3,("set_file_oplock: Refused oplock on file %s, fd = %d, dev = %x, \
inode = %.0f. (%s)\n",
fsp->fsp_name, fsp->fd,
(unsigned int)fsp->dev, (double)fsp->inode, strerror(errno)));
return False;
}
- DEBUG(3,("linux_set_kernel_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f, file_id = %lu\n",
+ DEBUG(3,("set_file_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f, file_id = %lu\n",
fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id));
return True;
@@ -199,7 +196,7 @@ static void linux_release_kernel_oplock(files_struct *fsp)
* oplock state of this file.
*/
int state = fcntl(fsp->fd, F_GETLEASE, 0);
- dbgtext("linux_release_kernel_oplock: file %s, dev = %x, inode = %.0f file_id = %lu has kernel \
+ dbgtext("release_kernel_oplock: file %s, dev = %x, inode = %.0f file_id = %lu has kernel \
oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
(double)fsp->inode, fsp->file_id, state );
}
@@ -209,7 +206,7 @@ oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
*/
if (linux_setlease(fsp->fd, F_UNLCK) == -1) {
if (DEBUGLVL(0)) {
- dbgtext("linux_release_kernel_oplock: Error when removing kernel oplock on file " );
+ dbgtext("release_kernel_oplock: Error when removing kernel oplock on file " );
dbgtext("%s, dev = %x, inode = %.0f, file_id = %lu. Error was %s\n",
fsp->fsp_name, (unsigned int)fsp->dev,
(double)fsp->inode, fsp->file_id, strerror(errno) );
@@ -247,7 +244,7 @@ static BOOL linux_kernel_oplock_parse(char *msg_start, int msg_len, SMB_INO_T *i
static BOOL linux_oplock_msg_waiting(fd_set *fds)
{
- return signals_received != 0;
+ return signals_processed != signals_received;
}
/****************************************************************************