diff options
author | Andrew Tridgell <tridge@samba.org> | 2000-06-12 17:06:00 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2000-06-12 17:06:00 +0000 |
commit | c8de9b8fe14fe1e6e85652d543615dc187949a1a (patch) | |
tree | 23b3a6db0f9a180e001cb549858dd74abb620112 /source3/smbd | |
parent | b2d01bd2dbfed8b35cc324fad42eac562fcad3b4 (diff) | |
download | samba-c8de9b8fe14fe1e6e85652d543615dc187949a1a.tar.gz samba-c8de9b8fe14fe1e6e85652d543615dc187949a1a.tar.bz2 samba-c8de9b8fe14fe1e6e85652d543615dc187949a1a.zip |
enable the Linux change notify code and change some notify debug code
(This used to be commit c6be511fcc1be79619a0184f03d4c33dbfe12f04)
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/notify.c | 5 | ||||
-rw-r--r-- | source3/smbd/notify_kernel.c | 51 | ||||
-rw-r--r-- | source3/smbd/oplock_linux.c | 23 |
3 files changed, 64 insertions, 15 deletions
diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c index 40867a71ee..c577d0aef3 100644 --- a/source3/smbd/notify.c +++ b/source3/smbd/notify.c @@ -212,7 +212,10 @@ initialise the change notify subsystem ****************************************************************************/ BOOL init_change_notify(void) { - cnotify = hash_notify_init(); +#if HAVE_KERNEL_CHANGE_NOTIFY + cnotify = kernel_notify_init(); +#endif + if (!cnotify) cnotify = hash_notify_init(); if (!cnotify) { DEBUG(0,("Failed to init change notify system\n")); diff --git a/source3/smbd/notify_kernel.c b/source3/smbd/notify_kernel.c index 7732bc646f..f78198f207 100644 --- a/source3/smbd/notify_kernel.c +++ b/source3/smbd/notify_kernel.c @@ -43,6 +43,14 @@ static unsigned signals_processed; #define RT_SIGNAL_NOTIFY 34 #endif +#ifndef F_SETSIG +#define F_SETSIG 10 +#endif + +#ifndef F_NOTIFY +#define F_NOTIFY 1026 +#endif + /**************************************************************************** This is the structure to keep the information needed to determine if a directory has changed. @@ -73,6 +81,8 @@ static BOOL kernel_check_notify(connection_struct *conn, uint16 vuid, char *path if (data->directory_handle != fd_pending) return False; + DEBUG(3,("kernel change notify on %s fd=%d\n", path, fd_pending)); + close(fd_pending); data->directory_handle = fd_pending = -1; signals_processed++; @@ -86,15 +96,17 @@ remove a change notify data structure static void kernel_remove_notify(void *datap) { struct change_data *data = (struct change_data *)datap; - if (data->directory_handle != -1) { - if (data->directory_handle == fd_pending) { - data->directory_handle = fd_pending = -1; + int fd = data->directory_handle; + if (fd != -1) { + if (fd == fd_pending) { + fd_pending = -1; signals_processed++; BlockSignals(False, RT_SIGNAL_NOTIFY); } - close(data->directory_handle); + close(fd); } free(data); + DEBUG(3,("removed kernel change notify fd=%d\n", fd)); } @@ -107,10 +119,10 @@ static void *kernel_register_notify(connection_struct *conn, char *path, uint32 int fd; unsigned long kernel_flags; - fd = dos_open(fsp->fsp_name, O_RDONLY, 0); + fd = dos_open(path, O_RDONLY, 0); if (fd == -1) { - DEBUG(3,("Failed to open directory %s for change notify\n", fsp->fsp_name)); + DEBUG(3,("Failed to open directory %s for change notify\n", path)); return NULL; } @@ -120,8 +132,8 @@ static void *kernel_register_notify(connection_struct *conn, char *path, uint32 } kernel_flags = 0; - if (flags & FILE_NOTIFY_CHANGE_FILE_NAME) kernel_flags |= DN_RENAME; - if (flags & FILE_NOTIFY_CHANGE_DIR_NAME) kernel_flags |= DN_RENAME; + if (flags & FILE_NOTIFY_CHANGE_FILE_NAME) kernel_flags |= DN_RENAME|DN_DELETE; + if (flags & FILE_NOTIFY_CHANGE_DIR_NAME) kernel_flags |= DN_RENAME|DN_DELETE; if (flags & FILE_NOTIFY_CHANGE_ATTRIBUTES) kernel_flags |= DN_MODIFY; if (flags & FILE_NOTIFY_CHANGE_SIZE) kernel_flags |= DN_MODIFY; if (flags & FILE_NOTIFY_CHANGE_LAST_WRITE) kernel_flags |= DN_MODIFY; @@ -133,11 +145,32 @@ static void *kernel_register_notify(connection_struct *conn, char *path, uint32 return NULL; } + if (fcntl(fd, F_SETOWN, sys_getpid()) == -1) { + DEBUG(3,("Failed to set owner for change notify\n")); + return NULL; + } + data.directory_handle = fd; + DEBUG(3,("kernel change notify on %s (flags=0x%x) fd=%d\n", + path, (int)kernel_flags, fd)); + return (void *)memdup(&data, sizeof(data)); } +/**************************************************************************** +see if the kernel supports change notify +****************************************************************************/ +static BOOL kernel_notify_available(void) +{ + int fd, ret; + fd = open("/tmp", O_RDONLY); + if (fd == -1) return False; /* uggh! */ + ret = fcntl(fd, F_NOTIFY, 0); + close(fd); + return ret == 0 || errno != EINVAL; +} + /**************************************************************************** setup kernel based change notify @@ -147,6 +180,8 @@ struct cnotify_fns *kernel_notify_init(void) static struct cnotify_fns cnotify; struct sigaction act; + if (!kernel_notify_available()) return NULL; + act.sa_handler = NULL; act.sa_sigaction = signal_handler; act.sa_flags = SA_SIGINFO; diff --git a/source3/smbd/oplock_linux.c b/source3/smbd/oplock_linux.c index de2a4300a7..c53dd1c57f 100644 --- a/source3/smbd/oplock_linux.c +++ b/source3/smbd/oplock_linux.c @@ -47,6 +47,10 @@ static int fd_pending; /* the fd of the current pending signal */ #define RT_SIGNAL_LEASE 33 #endif +#ifndef F_SETSIG +#define F_SETSIG 10 +#endif + /**************************************************************************** handle a LEASE signal, incrementing the signals_received and blocking the signal ****************************************************************************/ @@ -60,8 +64,7 @@ static void signal_handler(int signal, siginfo_t *info, void *unused) /**************************************************************************** try to gain a linux capability -****************************************************************************/ -static void set_capability(unsigned capability) +****************************************************************************/static void set_capability(unsigned capability) { #ifndef _LINUX_CAPABILITY_VERSION #define _LINUX_CAPABILITY_VERSION 0x19980330 @@ -101,6 +104,12 @@ try again static int linux_setlease(int fd, int leasetype) { int ret; + + if (fcntl(fd, F_SETSIG, RT_SIGNAL_LEASE) == -1) { + DEBUG(3,("Failed to set signal handler for kernel lease\n")); + return -1; + } + ret = fcntl(fd, F_SETLEASE, leasetype); if (ret == -1 && errno == EACCES) { set_capability(CAP_LEASE); @@ -133,7 +142,7 @@ static BOOL linux_oplock_receive_message(fd_set *fds, char *buffer, int buffer_l dev = sbuf.st_dev; inode = sbuf.st_ino; - DEBUG(5,("receive_local_message: kernel oplock break request received for \ + DEBUG(3,("receive_local_message: kernel oplock break request received for \ dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode )); /* @@ -167,14 +176,14 @@ dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode )); static BOOL linux_set_kernel_oplock(files_struct *fsp, int oplock_type) { if (linux_setlease(fsp->fd, F_WRLCK) == -1) { - DEBUG(5,("set_file_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(10,("set_file_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f\n", + DEBUG(3,("set_file_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f\n", fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode)); return True; @@ -226,7 +235,7 @@ static BOOL linux_kernel_oplock_parse(char *msg_start, int msg_len, SMB_INO_T *i memcpy((char *)inode, msg_start+KERNEL_OPLOCK_BREAK_INODE_OFFSET, sizeof(*inode)); memcpy((char *)dev, msg_start+KERNEL_OPLOCK_BREAK_DEV_OFFSET, sizeof(*dev)); - DEBUG(5,("kernel oplock break request for file dev = %x, inode = %.0f\n", + DEBUG(3,("kernel oplock break request for file dev = %x, inode = %.0f\n", (unsigned int)*dev, (double)*inode)); return True; @@ -283,6 +292,8 @@ struct kernel_oplocks *linux_init_kernel_oplocks(void) koplocks.msg_waiting = linux_oplock_msg_waiting; koplocks.notification_fd = -1; + DEBUG(3,("Linux kernel oplocks enabled\n")); + return &koplocks; } |