r23183: Check in a change made by Tridge:
[sfrench/samba-autobuild/.git] / source / smbd / oplock_irix.c
index ffcf3d0af4dad5250980d5c24642fbdc9cbf919c..1ac0cb4674cb998c324366d713961fbce9c22c74 100644 (file)
@@ -18,6 +18,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
 
+#define DBGC_CLASS DBGC_LOCKING
 #include "includes.h"
 
 #if HAVE_KERNEL_OPLOCKS_IRIX
@@ -35,18 +36,21 @@ static BOOL irix_oplocks_available(void)
        int pfd[2];
        pstring tmpname;
 
-       oplock_set_capability(True, False);
+       set_effective_capability(KERNEL_OPLOCK_CAPABILITY);
 
-       slprintf(tmpname,sizeof(tmpname)-1, "%s/koplock.%d", lp_lockdir(), (int)sys_getpid());
+       slprintf(tmpname,sizeof(tmpname)-1, "%s/koplock.%d", lp_lockdir(),
+                (int)sys_getpid());
 
        if(pipe(pfd) != 0) {
-               DEBUG(0,("check_kernel_oplocks: Unable to create pipe. Error was %s\n",
+               DEBUG(0,("check_kernel_oplocks: Unable to create pipe. Error "
+                        "was %s\n",
                         strerror(errno) ));
                return False;
        }
 
        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",
+               DEBUG(0,("check_kernel_oplocks: Unable to open temp test file "
+                        "%s. Error was %s\n",
                         tmpname, strerror(errno) ));
                unlink( tmpname );
                close(pfd[0]);
@@ -57,8 +61,9 @@ static BOOL irix_oplocks_available(void)
        unlink(tmpname);
 
        if(sys_fcntl_long(fd, F_OPLKREG, pfd[1]) == -1) {
-               DEBUG(0,("check_kernel_oplocks: Kernel oplocks are not available on this machine. \
-Disabling kernel oplock support.\n" ));
+               DEBUG(0,("check_kernel_oplocks: Kernel oplocks are not "
+                        "available on this machine. Disabling kernel oplock "
+                        "support.\n" ));
                close(pfd[0]);
                close(pfd[1]);
                close(fd);
@@ -66,8 +71,9 @@ Disabling kernel oplock support.\n" ));
        }
 
        if(sys_fcntl_long(fd, F_OPLKACK, OP_REVOKE) < 0 ) {
-               DEBUG(0,("check_kernel_oplocks: Error when removing kernel oplock. Error was %s. \
-Disabling kernel oplock support.\n", strerror(errno) ));
+               DEBUG(0,("check_kernel_oplocks: Error when removing kernel "
+                        "oplock. Error was %s. Disabling kernel oplock "
+                        "support.\n", strerror(errno) ));
                close(pfd[0]);
                close(pfd[1]);
                close(fd);
@@ -86,23 +92,27 @@ Disabling kernel oplock support.\n", strerror(errno) ));
  * oplock break protocol.
 ****************************************************************************/
 
-static BOOL irix_oplock_receive_message(fd_set *fds, char *buffer, int buffer_len)
+static files_struct *irix_oplock_receive_message(fd_set *fds)
 {
        extern int smb_read_error;
        oplock_stat_t os;
        char dummy;
        files_struct *fsp;
 
+       /* Ensure we only get one call per select fd set. */
+       FD_CLR(oplock_pipe_read, fds);
+
        /*
         * Read one byte of zero to clear the
         * kernel break notify message.
         */
 
        if(read(oplock_pipe_read, &dummy, 1) != 1) {
-               DEBUG(0,("irix_oplock_receive_message: read of kernel notification failed. \
-Error was %s.\n", strerror(errno) ));
+               DEBUG(0,("irix_oplock_receive_message: read of kernel "
+                        "notification failed. Error was %s.\n",
+                        strerror(errno) ));
                smb_read_error = READ_ERROR;
-               return False;
+               return NULL;
        }
 
        /*
@@ -112,17 +122,17 @@ Error was %s.\n", strerror(errno) ));
         */
 
        if(sys_fcntl_ptr(oplock_pipe_read, F_OPLKSTAT, &os) < 0) {
-               DEBUG(0,("irix_oplock_receive_message: fcntl of kernel notification failed. \
-Error was %s.\n", strerror(errno) ));
+               DEBUG(0,("irix_oplock_receive_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;
+                       return NULL;
                }
                smb_read_error = READ_ERROR;
-               return False;
+               return NULL;
        }
 
        /*
@@ -130,32 +140,20 @@ Error was %s.\n", strerror(errno) ));
         * is the first fsp open with this dev,ino pair.
         */
 
-       if ((fsp = file_find_di_first((SMB_DEV_T)os.os_dev, (SMB_INO_T)os.os_ino)) == NULL) {
-               DEBUG(0,("irix_oplock_receive_message: unable to find open file with dev = %x, inode = %.0f\n",
-                       (unsigned int)os.os_dev, (double)os.os_ino ));
-               return False;
+       if ((fsp = file_find_di_first((SMB_DEV_T)os.os_dev,
+                                     (SMB_INO_T)os.os_ino)) == NULL) {
+               DEBUG(0,("irix_oplock_receive_message: unable to find open "
+                        "file with dev = %x, inode = %.0f\n",
+                        (unsigned int)os.os_dev, (double)os.os_ino ));
+               return NULL;
        }
      
-       DEBUG(5,("irix_oplock_receive_message: kernel oplock break request received for \
-dev = %x, inode = %.0f\n, file_id = %ul", (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id ));
-     
-       /*
-        * Create a kernel oplock break message.
-        */
-    
-       /* Setup the message header */
-       SIVAL(buffer,OPBRK_CMD_LEN_OFFSET,KERNEL_OPLOCK_BREAK_MSG_LEN);
-       SSVAL(buffer,OPBRK_CMD_PORT_OFFSET,0);
-   
-       buffer += OPBRK_CMD_HEADER_LEN;
-     
-       SSVAL(buffer,OPBRK_MESSAGE_CMD_OFFSET,KERNEL_OPLOCK_BREAK_CMD);
-   
-       memcpy(buffer + KERNEL_OPLOCK_BREAK_DEV_OFFSET, (char *)&fsp->dev, sizeof(fsp->dev));
-       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;
+       DEBUG(5,("irix_oplock_receive_message: kernel oplock break request "
+                "received for file_id %s gen_id = %ul",
+                file_id_static_string(&fsp->file_id),
+                fsp->fh->gen_id ));
+
+       return fsp;
 }
 
 /****************************************************************************
@@ -164,22 +162,30 @@ dev = %x, inode = %.0f\n, file_id = %ul", (unsigned int)fsp->dev, (double)fsp->i
 
 static BOOL irix_set_kernel_oplock(files_struct *fsp, int oplock_type)
 {
-       if (sys_fcntl_long(fsp->fd, F_OPLKREG, oplock_pipe_write) == -1) {
+       if (sys_fcntl_long(fsp->fh->fd, F_OPLKREG, oplock_pipe_write) == -1) {
                if(errno != EAGAIN) {
-                       DEBUG(0,("irix_set_kernel_oplock: Unable to get kernel oplock on file %s, dev = %x, \
-inode = %.0f, file_id = %ul. Error was %s\n", 
-                                fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id,
+                       DEBUG(0,("irix_set_kernel_oplock: Unable to get "
+                                "kernel oplock on file %s, file_id %s "
+                                "gen_id = %ul. Error was %s\n", 
+                                fsp->fsp_name, file_id_static_string(&fsp->file_id), 
+                                fsp->fh->gen_id,
                                 strerror(errno) ));
                } else {
-                       DEBUG(5,("irix_set_kernel_oplock: Refused oplock on file %s, fd = %d, dev = %x, \
-inode = %.0f, file_id = %ul. Another process had the file open.\n",
-                                fsp->fsp_name, fsp->fd, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id ));
+                       DEBUG(5,("irix_set_kernel_oplock: Refused oplock on "
+                                "file %s, fd = %d, file_id = 5s, "
+                                "gen_id = %ul. Another process had the file "
+                                "open.\n",
+                                fsp->fsp_name, fsp->fh->fd,
+                                file_id_static_string(&fsp->file_id),
+                                fsp->fh->gen_id ));
                }
                return False;
        }
        
-       DEBUG(10,("irix_set_kernel_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f, file_id = %ul\n",
-                 fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id));
+       DEBUG(10,("irix_set_kernel_oplock: got kernel oplock on file %s, file_id = %s "
+                 "gen_id = %ul\n",
+                 fsp->fsp_name, file_id_static_string(&fsp->file_id),
+                 fsp->fh->gen_id));
 
        return True;
 }
@@ -195,59 +201,57 @@ static void irix_release_kernel_oplock(files_struct *fsp)
                 * Check and print out the current kernel
                 * oplock state of this file.
                 */
-               int state = sys_fcntl_long(fsp->fd, F_OPLKACK, -1);
-               dbgtext("irix_release_kernel_oplock: file %s, dev = %x, inode = %.0f file_id = %ul, has kernel \
-oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->dev,
-                        (double)fsp->inode, fsp->file_id, state );
+               int state = sys_fcntl_long(fsp->fh->fd, F_OPLKACK, -1);
+               dbgtext("irix_release_kernel_oplock: file %s, file_id = %s"
+                       "gen_id = %ul, has kernel oplock state "
+                       "of %x.\n", fsp->fsp_name, file_id_static_string(&fsp->file_id),
+                        fsp->fh->gen_id, state );
        }
 
        /*
         * Remove the kernel oplock on this file.
         */
-       if(sys_fcntl_long(fsp->fd, F_OPLKACK, OP_REVOKE) < 0) {
+       if(sys_fcntl_long(fsp->fh->fd, F_OPLKACK, OP_REVOKE) < 0) {
                if( DEBUGLVL( 0 )) {
-                       dbgtext("irix_release_kernel_oplock: Error when removing kernel oplock on file " );
-                       dbgtext("%s, dev = %x, inode = %.0f, file_id = %ul. Error was %s\n",
-                               fsp->fsp_name, (unsigned int)fsp->dev, 
-                               (double)fsp->inode, fsp->file_id, strerror(errno) );
+                       dbgtext("irix_release_kernel_oplock: Error when "
+                               "removing kernel oplock on file " );
+                       dbgtext("%s, file_id = %s gen_id = %ul. "
+                               "Error was %s\n",
+                               fsp->fsp_name, file_id_static_string(&fsp->file_id),
+                               fsp->fh->gen_id,
+                               strerror(errno) );
                }
        }
 }
 
 /****************************************************************************
- Parse a kernel oplock message.
+ See if there is a message waiting in this fd set.
+ Note that fds MAY BE NULL ! If so we must do our own select.
 ****************************************************************************/
 
-static BOOL irix_kernel_oplock_parse(char *msg_start, int msg_len,
-               SMB_INO_T *inode, SMB_DEV_T *dev, unsigned long *file_id)
+static BOOL irix_oplock_msg_waiting(fd_set *fds)
 {
-       /* Ensure that the msg length is correct. */
-       if(msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN) {
-               DEBUG(0,("incorrect length for KERNEL_OPLOCK_BREAK_CMD (was %d, should be %d).\n", 
-                        msg_len, KERNEL_OPLOCK_BREAK_MSG_LEN));
-               return False;
-       }
-
-       memcpy((char *)inode, msg_start+KERNEL_OPLOCK_BREAK_INODE_OFFSET, sizeof(*inode));
-       memcpy((char *)dev, msg_start+KERNEL_OPLOCK_BREAK_DEV_OFFSET, sizeof(*dev));
-       memcpy((char *)file_id, msg_start+KERNEL_OPLOCK_BREAK_FILEID_OFFSET, sizeof(*file_id));
+       int selrtn;
+       fd_set myfds;
+       struct timeval to;
 
-       DEBUG(5,("kernel oplock break request for file dev = %x, inode = %.0f, file_id = %ul\n", 
-               (unsigned int)*dev, (double)*inode, *file_id));
+       if (oplock_pipe_read == -1)
+               return False;
 
-       return True;
-}
+       if (fds) {
+               return FD_ISSET(oplock_pipe_read, fds);
+       }
 
-/****************************************************************************
- Set *maxfd to include oplock read pipe.
-****************************************************************************/
+       /* Do a zero-time select. We just need to find out if there
+        * are any outstanding messages. We use sys_select_intr as
+        * we need to ignore any signals. */
 
-static BOOL irix_oplock_msg_waiting(fd_set *fds)
-{
-       if (oplock_pipe_read == -1)
-               return False;
+       FD_ZERO(&myfds);
+       FD_SET(oplock_pipe_read, &myfds);
 
-       return FD_ISSET(oplock_pipe_read,fds);
+       to = timeval_set(0, 0);
+       selrtn = sys_select_intr(oplock_pipe_read+1,&myfds,NULL,NULL,&to);
+       return (selrtn == 1) ? True : False;
 }
 
 /****************************************************************************
@@ -263,8 +267,8 @@ struct kernel_oplocks *irix_init_kernel_oplocks(void)
                return NULL;
 
        if(pipe(pfd) != 0) {
-               DEBUG(0,("setup_kernel_oplock_pipe: Unable to create pipe. Error was %s\n",
-                        strerror(errno) ));
+               DEBUG(0,("setup_kernel_oplock_pipe: Unable to create pipe. "
+                        "Error was %s\n", strerror(errno) ));
                return False;
        }
 
@@ -274,12 +278,12 @@ struct kernel_oplocks *irix_init_kernel_oplocks(void)
        koplocks.receive_message = irix_oplock_receive_message;
        koplocks.set_oplock = irix_set_kernel_oplock;
        koplocks.release_oplock = irix_release_kernel_oplock;
-       koplocks.parse_message = irix_kernel_oplock_parse;
        koplocks.msg_waiting = irix_oplock_msg_waiting;
        koplocks.notification_fd = oplock_pipe_read;
 
        return &koplocks;
 }
 #else
+ void oplock_irix_dummy(void);
  void oplock_irix_dummy(void) {}
 #endif /* HAVE_KERNEL_OPLOCKS_IRIX */