Makefile.in: Fixed bug with continuation line causing proto to fail.
[Samba/gebeck_regimport.git] / source / smbd / oplock.c
blob27d802c151421730e376383702d486bcdbd1a599
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 oplock processing
5 Copyright (C) Andrew Tridgell 1992-1998
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
24 extern int DEBUGLEVEL;
26 /* Oplock ipc UDP socket. */
27 static int oplock_sock = -1;
28 uint16 global_oplock_port = 0;
29 #if defined(HAVE_KERNEL_OPLOCKS)
30 static int oplock_pipe_read = -1;
31 static int oplock_pipe_write = -1;
32 #endif /* HAVE_KERNEL_OPLOCKS */
34 /* Current number of oplocks we have outstanding. */
35 int32 global_oplocks_open = 0;
36 BOOL global_oplock_break = False;
38 extern int smb_read_error;
40 static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval);
42 /****************************************************************************
43 open the oplock IPC socket communication
44 ****************************************************************************/
45 BOOL open_oplock_ipc(void)
47 struct sockaddr_in sock_name;
48 int len = sizeof(sock_name);
50 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
52 /* Open a lookback UDP socket on a random port. */
53 oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
54 if (oplock_sock == -1)
56 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
57 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
58 global_oplock_port = 0;
59 return(False);
62 /* Find out the transient UDP port we have been allocated. */
63 if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
65 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
66 strerror(errno)));
67 close(oplock_sock);
68 oplock_sock = -1;
69 global_oplock_port = 0;
70 return False;
72 global_oplock_port = ntohs(sock_name.sin_port);
74 DEBUG(3,("open_oplock ipc: pid = %d, global_oplock_port = %u\n",
75 (int)getpid(), global_oplock_port));
77 return True;
80 /****************************************************************************
81 Read an oplock break message from the either the oplock UDP fd
82 or the kernel oplock pipe fd (if kernel oplocks are supported).
84 If timeout is zero then *fds contains the file descriptors that
85 are ready to be read and acted upon. If timeout is non-zero then
86 *fds contains the file descriptors to be selected on for read.
87 The timeout is in milliseconds
89 ****************************************************************************/
91 BOOL receive_local_message(fd_set *fds, char *buffer, int buffer_len, int timeout)
93 struct sockaddr_in from;
94 int fromlen = sizeof(from);
95 int32 msg_len = 0;
97 smb_read_error = 0;
99 if(timeout != 0) {
100 struct timeval to;
101 int selrtn;
102 int maxfd = oplock_sock;
104 #if defined(HAVE_KERNEL_OPLOCKS)
105 if(lp_kernel_oplocks())
106 maxfd = MAX(maxfd, oplock_pipe_read);
107 #endif /* HAVE_KERNEL_OPLOCKS */
109 to.tv_sec = timeout / 1000;
110 to.tv_usec = (timeout % 1000) * 1000;
112 selrtn = sys_select(maxfd+1,fds,&to);
114 /* Check if error */
115 if(selrtn == -1) {
116 /* something is wrong. Maybe the socket is dead? */
117 smb_read_error = READ_ERROR;
118 return False;
121 /* Did we timeout ? */
122 if (selrtn == 0) {
123 smb_read_error = READ_TIMEOUT;
124 return False;
128 #if defined(HAVE_KERNEL_OPLOCKS)
129 if(FD_ISSET(oplock_pipe_read,fds)) {
131 * Deal with the kernel <--> smbd
132 * oplock break protocol.
135 oplock_stat_t os;
136 SMB_DEV_T dev;
137 SMB_INO_T inode;
138 char dummy;
141 * Read one byte of zero to clear the
142 * kernel break notify message.
145 if(read(oplock_pipe_read, &dummy, 1) != 1) {
146 DEBUG(0,("receive_local_message: read of kernel notification failed. \
147 Error was %s.\n", strerror(errno) ));
148 smb_read_error = READ_ERROR;
149 return False;
153 * Do a query to get the
154 * device and inode of the file that has the break
155 * request outstanding.
158 if(fcntl(oplock_pipe_read, F_OPLKSTAT, &os) < 0) {
159 DEBUG(0,("receive_local_message: fcntl of kernel notification failed. \
160 Error was %s.\n", strerror(errno) ));
161 smb_read_error = READ_ERROR;
162 return False;
165 dev = (SMB_DEV_T)os.os_dev;
166 inode = (SMB_DEV_T)os.os_ino;
168 DEBUG(5,("receive_local_message: kernel oplock break request received for \
169 dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode ));
172 * Create a kernel oplock break message.
175 /* Setup the message header */
176 SIVAL(buffer,OPBRK_CMD_LEN_OFFSET,KERNEL_OPLOCK_BREAK_MSG_LEN);
177 SSVAL(buffer,OPBRK_CMD_PORT_OFFSET,0);
179 buffer += OPBRK_CMD_HEADER_LEN;
181 SSVAL(buffer,OPBRK_MESSAGE_CMD_OFFSET,KERNEL_OPLOCK_BREAK_CMD);
182 SIVAL(buffer,KERNEL_OPLOCK_BREAK_DEV_OFFSET,dev);
184 #ifdef LARGE_SMB_INO_T
185 SIVAL(buffer,KERNEL_OPLOCK_BREAK_INODE_OFFSET,inode & 0xFFFFFFFF);
186 SIVAL(buffer,KERNEL_OPLOCK_BREAK_INODE_OFFSET+4, (inode >> 32 ) & 0xFFFFFFFF );
187 #else /* LARGE_SMB_INO_T */
188 SIVAL(buffer,KERNEL_OPLOCK_BREAK_INODE_OFFSET,inode);
189 #endif /* LARGE_SMB_INO_T */
191 return True;
193 #endif /* HAVE_KERNEL_OPLOCKS */
196 * From here down we deal with the smbd <--> smbd
197 * oplock break protocol only.
201 * Read a loopback udp message.
203 msg_len = recvfrom(oplock_sock, &buffer[OPBRK_CMD_HEADER_LEN],
204 buffer_len - OPBRK_CMD_HEADER_LEN, 0,
205 (struct sockaddr *)&from, &fromlen);
207 if(msg_len < 0) {
208 DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
209 return False;
212 /* Validate message length. */
213 if(msg_len > (buffer_len - OPBRK_CMD_HEADER_LEN)) {
214 DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
215 msg_len,
216 buffer_len - OPBRK_CMD_HEADER_LEN));
217 return False;
220 /* Validate message from address (must be localhost). */
221 if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) {
222 DEBUG(0,("receive_local_message: invalid 'from' address \
223 (was %x should be 127.0.0.1\n", from.sin_addr.s_addr));
224 return False;
227 /* Setup the message header */
228 SIVAL(buffer,OPBRK_CMD_LEN_OFFSET,msg_len);
229 SSVAL(buffer,OPBRK_CMD_PORT_OFFSET,ntohs(from.sin_port));
231 return True;
234 /****************************************************************************
235 Attempt to set an oplock on a file. Always succeeds if kernel oplocks are
236 disabled (just sets flags). Returns True if oplock set.
237 ****************************************************************************/
239 BOOL set_file_oplock(files_struct *fsp)
241 #if defined(HAVE_KERNEL_OPLOCKS)
242 if(lp_kernel_oplocks()) {
244 if(fcntl(fsp->fd_ptr->fd, F_OPLKREG, oplock_pipe_write) < 0 ) {
245 if(errno != EAGAIN) {
246 DEBUG(0,("set_file_oplock: Unable to get kernel oplock on file %s, dev = %x, \
247 inode = %.0f. Error was %s\n",
248 fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode,
249 strerror(errno) ));
250 } else {
251 DEBUG(5,("set_file_oplock: Refused oplock on file %s, fd = %d, dev = %x, \
252 inode = %.0f. Another process had the file open.\n",
253 fsp->fsp_name, fsp->fd_ptr->fd, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode ));
255 return False;
258 DEBUG(10,("set_file_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f\n",
259 fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode));
262 #endif /* HAVE_KERNEL_OPLOCKS */
264 DEBUG(5,("set_file_oplock: granted oplock on file %s, dev = %x, inode = %.0f\n",
265 fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode));
267 fsp->granted_oplock = True;
268 fsp->sent_oplock_break = False;
269 global_oplocks_open++;
271 return True;
274 /****************************************************************************
275 Attempt to release an oplock on a file. Always succeeds if kernel oplocks are
276 disabled (just clears flags).
277 ****************************************************************************/
279 static void release_file_oplock(files_struct *fsp)
281 #if defined(HAVE_KERNEL_OPLOCKS)
283 if(lp_kernel_oplocks())
285 if( DEBUGLVL( 10 ))
288 * Check and print out the current kernel
289 * oplock state of this file.
291 int state = fcntl(fsp->fd_ptr->fd, F_OPLKACK, -1);
292 dbgtext("release_file_oplock: file %s, dev = %x, inode = %.0f has kernel \
293 oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev,
294 (double)fsp->fd_ptr->inode, state );
298 * Remote the kernel oplock on this file.
301 if(fcntl(fsp->fd_ptr->fd, F_OPLKACK, OP_REVOKE) < 0)
303 if( DEBUGLVL( 0 ))
305 dbgtext("release_file_oplock: Error when removing kernel oplock on file " );
306 dbgtext("%s, dev = %x, inode = %.0f. Error was %s\n",
307 fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev,
308 (double)fsp->fd_ptr->inode, strerror(errno) );
312 #endif /* HAVE_KERNEL_OPLOCKS */
314 fsp->granted_oplock = False;
315 fsp->sent_oplock_break = False;
316 global_oplocks_open--;
319 /****************************************************************************
320 Setup the listening set of file descriptors for an oplock break
321 message either from the UDP socket or from the kernel. Returns the maximum
322 fd used.
323 ****************************************************************************/
325 int setup_oplock_select_set( fd_set *fds)
327 int maxfd = oplock_sock;
328 FD_SET(oplock_sock,fds);
330 #if defined(HAVE_KERNEL_OPLOCKS)
331 if(lp_kernel_oplocks()) {
332 FD_SET(oplock_pipe_read,fds);
333 maxfd = MAX(maxfd,oplock_pipe_read);
335 #endif /* HAVE_KERNEL_OPLOCKS */
337 return maxfd;
340 /****************************************************************************
341 Process an oplock break message - whether it came from the UDP socket
342 or from the kernel.
343 ****************************************************************************/
345 BOOL process_local_message(char *buffer, int buf_size)
347 int32 msg_len;
348 uint16 from_port;
349 char *msg_start;
350 SMB_DEV_T dev;
351 SMB_INO_T inode;
352 uint32 remotepid;
353 struct timeval tval;
354 struct timeval *ptval = NULL;
356 msg_len = IVAL(buffer,OPBRK_CMD_LEN_OFFSET);
357 from_port = SVAL(buffer,OPBRK_CMD_PORT_OFFSET);
359 msg_start = &buffer[OPBRK_CMD_HEADER_LEN];
361 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
362 msg_len, from_port));
365 * Pull the info out of the requesting packet.
368 switch(SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET))
370 #if defined(HAVE_KERNEL_OPLOCKS)
371 case KERNEL_OPLOCK_BREAK_CMD:
372 /* Ensure that the msg length is correct. */
373 if(msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN)
375 DEBUG(0,("process_local_message: incorrect length for KERNEL_OPLOCK_BREAK_CMD (was %d, \
376 should be %d).\n", msg_len, KERNEL_OPLOCK_BREAK_MSG_LEN));
377 return False;
381 * Warning - beware of SMB_INO_T <> 4 bytes. !!
383 #ifdef LARGE_SMB_INO_T
384 SMB_INO_T inode_low = IVAL(msg_start, KERNEL_OPLOCK_BREAK_INODE_OFFSET);
385 SMB_INO_T inode_high = IVAL(msg_start, KERNEL_OPLOCK_BREAK_INODE_OFFSET + 4);
386 inode = inode_low | (inode_high << 32);
387 #else /* LARGE_SMB_INO_T */
388 inode = IVAL(msg_start, KERNEL_OPLOCK_BREAK_INODE_OFFSET);
389 #endif /* LARGE_SMB_INO_T */
391 dev = IVAL(msg_start,KERNEL_OPLOCK_BREAK_DEV_OFFSET);
393 ptval = NULL;
395 DEBUG(5,("process_local_message: kernel oplock break request for \
396 file dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode));
398 break;
399 #endif /* HAVE_KERNEL_OPLOCKS */
401 case OPLOCK_BREAK_CMD:
402 /* Ensure that the msg length is correct. */
403 if(msg_len != OPLOCK_BREAK_MSG_LEN)
405 DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
406 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
407 return False;
411 * Warning - beware of SMB_INO_T <> 4 bytes. !!
413 #ifdef LARGE_SMB_INO_T
414 SMB_INO_T inode_low = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
415 SMB_INO_T inode_high = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET + 4);
416 inode = inode_low | (inode_high << 32);
417 #else /* LARGE_SMB_INO_T */
418 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
419 #endif /* LARGE_SMB_INO_T */
421 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
423 tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
424 tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
426 ptval = &tval;
428 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
430 DEBUG(5,("process_local_message: oplock break request from \
431 pid %d, port %d, dev = %x, inode = %.0f\n", remotepid, from_port, (unsigned int)dev, (double)inode));
433 break;
436 * Keep this as a debug case - eventually we can remove it.
438 case 0x8001:
439 DEBUG(0,("process_local_message: Received unsolicited break \
440 reply - dumping info.\n"));
442 if(msg_len != OPLOCK_BREAK_MSG_LEN)
444 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
445 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
446 return False;
451 * Warning - beware of SMB_INO_T <> 4 bytes. !!
453 #ifdef LARGE_SMB_INO_T
454 SMB_INO_T inode_low = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
455 SMB_INO_T inode_high = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET + 4);
456 inode = inode_low | (inode_high << 32);
457 #else /* LARGE_SMB_INO_T */
458 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
459 #endif /* LARGE_SMB_INO_T */
461 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
462 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
464 DEBUG(0,("process_local_message: unsolicited oplock break reply from \
465 pid %d, port %d, dev = %x, inode = %.0f\n", remotepid, from_port, (unsigned int)dev, (double)inode));
468 return False;
470 default:
471 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
472 (unsigned int)SVAL(msg_start,0)));
473 return False;
477 * Now actually process the break request.
480 if(global_oplocks_open != 0)
482 if(oplock_break(dev, inode, ptval) == False)
484 DEBUG(0,("process_local_message: oplock break failed.\n"));
485 return False;
488 else
491 * If we have no record of any currently open oplocks,
492 * it's not an error, as a close command may have
493 * just been issued on the file that was oplocked.
494 * Just log a message and return success in this case.
496 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
497 oplocks. Returning success.\n"));
501 * Do the appropriate reply - none in the kernel case.
504 if(SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET) == OPLOCK_BREAK_CMD)
506 struct sockaddr_in toaddr;
508 /* Send the message back after OR'ing in the 'REPLY' bit. */
509 SSVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
511 bzero((char *)&toaddr,sizeof(toaddr));
512 toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
513 toaddr.sin_port = htons(from_port);
514 toaddr.sin_family = AF_INET;
516 if(sendto( oplock_sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
517 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
519 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
520 remotepid, strerror(errno)));
521 return False;
524 DEBUG(5,("process_local_message: oplock break reply sent to \
525 pid %d, port %d, for file dev = %x, inode = %.0f\n",
526 remotepid, from_port, (unsigned int)dev, (double)inode));
529 return True;
532 /****************************************************************************
533 Process an oplock break directly.
534 ****************************************************************************/
536 static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
538 extern struct current_user current_user;
539 extern int Client;
540 char *inbuf = NULL;
541 char *outbuf = NULL;
542 files_struct *fsp = NULL;
543 time_t start_time;
544 BOOL shutdown_server = False;
545 connection_struct *saved_conn;
546 int saved_vuid;
547 pstring saved_dir;
549 if( DEBUGLVL( 3 ) )
551 dbgtext( "oplock_break: called for dev = %x, inode = %.0f.\n", (unsigned int)dev, (double)inode );
552 dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
555 /* We need to search the file open table for the
556 entry containing this dev and inode, and ensure
557 we have an oplock on it. */
558 fsp = file_find_dit(dev, inode, tval);
560 if(fsp == NULL)
562 /* The file could have been closed in the meantime - return success. */
563 if( DEBUGLVL( 0 ) )
565 dbgtext( "oplock_break: cannot find open file with " );
566 dbgtext( "dev = %x, inode = %.0f ", (unsigned int)dev, (double)inode);
567 dbgtext( "allowing break to succeed.\n" );
569 return True;
572 /* Ensure we have an oplock on the file */
574 /* There is a potential race condition in that an oplock could
575 have been broken due to another udp request, and yet there are
576 still oplock break messages being sent in the udp message
577 queue for this file. So return true if we don't have an oplock,
578 as we may have just freed it.
581 if(!fsp->granted_oplock)
583 if( DEBUGLVL( 0 ) )
585 dbgtext( "oplock_break: file %s ", fsp->fsp_name );
586 dbgtext( "(dev = %x, inode = %.0f) has no oplock.\n", (unsigned int)dev, (double)inode );
587 dbgtext( "Allowing break to succeed regardless.\n" );
589 return True;
592 /* mark the oplock break as sent - we don't want to send twice! */
593 if (fsp->sent_oplock_break)
595 if( DEBUGLVL( 0 ) )
597 dbgtext( "oplock_break: ERROR: oplock_break already sent for " );
598 dbgtext( "file %s ", fsp->fsp_name);
599 dbgtext( "(dev = %x, inode = %.0f)\n", (unsigned int)dev, (double)inode );
602 /* We have to fail the open here as we cannot send another oplock break on
603 this file whilst we are awaiting a response from the client - neither
604 can we allow another open to succeed while we are waiting for the
605 client.
607 return False;
610 /* Now comes the horrid part. We must send an oplock break to the client,
611 and then process incoming messages until we get a close or oplock release.
612 At this point we know we need a new inbuf/outbuf buffer pair.
613 We cannot use these staticaly as we may recurse into here due to
614 messages crossing on the wire.
617 if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
619 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
620 return False;
623 if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
625 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
626 free(inbuf);
627 inbuf = NULL;
628 return False;
631 /* Prepare the SMBlockingX message. */
632 bzero(outbuf,smb_size);
633 set_message(outbuf,8,0,True);
635 SCVAL(outbuf,smb_com,SMBlockingX);
636 SSVAL(outbuf,smb_tid,fsp->conn->cnum);
637 SSVAL(outbuf,smb_pid,0xFFFF);
638 SSVAL(outbuf,smb_uid,0);
639 SSVAL(outbuf,smb_mid,0xFFFF);
640 SCVAL(outbuf,smb_vwv0,0xFF);
641 SSVAL(outbuf,smb_vwv2,fsp->fnum);
642 SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
643 /* Change this when we have level II oplocks. */
644 SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
646 send_smb(Client, outbuf);
648 /* Remember we just sent an oplock break on this file. */
649 fsp->sent_oplock_break = True;
651 /* We need this in case a readraw crosses on the wire. */
652 global_oplock_break = True;
654 /* Process incoming messages. */
656 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
657 seconds we should just die.... */
659 start_time = time(NULL);
662 * Save the information we need to re-become the
663 * user, then unbecome the user whilst we're doing this.
665 saved_conn = fsp->conn;
666 saved_vuid = current_user.vuid;
667 GetWd(saved_dir);
668 unbecome_user();
669 /* Save the chain fnum. */
670 file_chain_save();
672 while(OPEN_FSP(fsp) && fsp->granted_oplock)
674 if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
677 * Die if we got an error.
680 if (smb_read_error == READ_EOF)
681 DEBUG( 0, ( "oplock_break: end of file from client\n" ) );
683 if (smb_read_error == READ_ERROR)
684 DEBUG( 0, ("oplock_break: receive_smb error (%s)\n", strerror(errno)) );
686 if (smb_read_error == READ_TIMEOUT)
687 DEBUG( 0, ( "oplock_break: receive_smb timed out after %d seconds.\n",
688 OPLOCK_BREAK_TIMEOUT ) );
690 DEBUGADD( 0, ( "oplock_break failed for file %s ", fsp->fsp_name ) );
691 DEBUGADD( 0, ( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode));
693 shutdown_server = True;
694 break;
698 * There are certain SMB requests that we shouldn't allow
699 * to recurse. opens, renames and deletes are the obvious
700 * ones. This is handled in the switch_message() function.
701 * If global_oplock_break is set they will push the packet onto
702 * the pending smb queue and return -1 (no reply).
703 * JRA.
706 process_smb(inbuf, outbuf);
709 * Die if we go over the time limit.
712 if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
714 if( DEBUGLVL( 0 ) )
716 dbgtext( "oplock_break: no break received from client " );
717 dbgtext( "within %d seconds.\n", OPLOCK_BREAK_TIMEOUT );
718 dbgtext( "oplock_break failed for file %s ", fsp->fsp_name );
719 dbgtext( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode );
721 shutdown_server = True;
722 break;
727 * Go back to being the user who requested the oplock
728 * break.
730 if(!become_user(saved_conn, saved_vuid))
732 DEBUG( 0, ( "oplock_break: unable to re-become user!" ) );
733 DEBUGADD( 0, ( "Shutting down server\n" ) );
734 close_sockets();
735 close(oplock_sock);
736 exit_server("unable to re-become user");
738 /* Including the directory. */
739 ChDir(saved_dir);
741 /* Restore the chain fnum. */
742 file_chain_restore();
744 /* Free the buffers we've been using to recurse. */
745 free(inbuf);
746 free(outbuf);
748 /* We need this in case a readraw crossed on the wire. */
749 if(global_oplock_break)
750 global_oplock_break = False;
753 * If the client did not respond we must die.
756 if(shutdown_server)
758 DEBUG( 0, ( "oplock_break: client failure in break - " ) );
759 DEBUGADD( 0, ( "shutting down this smbd.\n" ) );
760 close_sockets();
761 close(oplock_sock);
762 exit_server("oplock break failure");
765 if(OPEN_FSP(fsp))
767 /* The lockingX reply will have removed the oplock flag
768 from the sharemode. */
769 release_file_oplock(fsp);
772 /* Santity check - remove this later. JRA */
773 if(global_oplocks_open < 0)
775 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
776 global_oplocks_open));
777 exit_server("oplock_break: global_oplocks_open < 0");
781 if( DEBUGLVL( 3 ) )
783 dbgtext( "oplock_break: returning success for " );
784 dbgtext( "dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
785 dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
788 return True;
791 /****************************************************************************
792 Send an oplock break message to another smbd process. If the oplock is held
793 by the local smbd then call the oplock break function directly.
794 ****************************************************************************/
796 BOOL request_oplock_break(share_mode_entry *share_entry,
797 SMB_DEV_T dev, SMB_INO_T inode)
799 char op_break_msg[OPLOCK_BREAK_MSG_LEN];
800 struct sockaddr_in addr_out;
801 int pid = getpid();
802 time_t start_time;
803 int time_left;
805 if(pid == share_entry->pid)
807 /* We are breaking our own oplock, make sure it's us. */
808 if(share_entry->op_port != global_oplock_port)
810 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
811 should be %d\n", pid, share_entry->op_port, global_oplock_port));
812 return False;
815 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
817 /* Call oplock break direct. */
818 return oplock_break(dev, inode, &share_entry->time);
821 /* We need to send a OPLOCK_BREAK_CMD message to the
822 port in the share mode entry. */
824 SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
825 SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
826 SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
827 SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
828 SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
830 * WARNING - beware of SMB_INO_T <> 4 bytes.
832 #ifdef LARGE_SMB_INO_T
833 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,(inode & 0xFFFFFFFFL));
834 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET+4,((inode >> 32) & 0xFFFFFFFFL));
835 #else /* LARGE_SMB_INO_T */
836 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
837 #endif /* LARGE_SMB_INO_T */
839 /* set the address and port */
840 bzero((char *)&addr_out,sizeof(addr_out));
841 addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
842 addr_out.sin_port = htons( share_entry->op_port );
843 addr_out.sin_family = AF_INET;
845 if( DEBUGLVL( 3 ) )
847 dbgtext( "request_oplock_break: sending a oplock break message to " );
848 dbgtext( "pid %d on port %d ", share_entry->pid, share_entry->op_port );
849 dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
852 if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
853 (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
855 if( DEBUGLVL( 0 ) )
857 dbgtext( "request_oplock_break: failed when sending a oplock " );
858 dbgtext( "break message to pid %d ", share_entry->pid );
859 dbgtext( "on port %d ", share_entry->op_port );
860 dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
861 dbgtext( "Error was %s\n", strerror(errno) );
863 return False;
867 * Now we must await the oplock broken message coming back
868 * from the target smbd process. Timeout if it fails to
869 * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
870 * While we get messages that aren't ours, loop.
873 start_time = time(NULL);
874 time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
876 while(time_left >= 0)
878 char op_break_reply[OPBRK_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
879 int32 reply_msg_len;
880 uint16 reply_from_port;
881 char *reply_msg_start;
882 fd_set fds;
884 FD_ZERO(&fds);
885 FD_SET(oplock_sock,&fds);
886 #if defined(HAVE_KERNEL_OPLOCKS)
887 if(lp_kernel_oplocks())
888 FD_SET(oplock_pipe_read,&fds);
889 #endif /* HAVE_KERNEL_OPLOCKS */
891 if(receive_local_message(&fds, op_break_reply, sizeof(op_break_reply),
892 time_left ? time_left * 1000 : 1) == False)
894 if(smb_read_error == READ_TIMEOUT)
896 if( DEBUGLVL( 0 ) )
898 dbgtext( "request_oplock_break: no response received to oplock " );
899 dbgtext( "break request to pid %d ", share_entry->pid );
900 dbgtext( "on port %d ", share_entry->op_port );
901 dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
905 * This is a hack to make handling of failing clients more robust.
906 * If a oplock break response message is not received in the timeout
907 * period we may assume that the smbd servicing that client holding
908 * the oplock has died and the client changes were lost anyway, so
909 * we should continue to try and open the file.
911 break;
913 else
914 if( DEBUGLVL( 0 ) )
916 dbgtext( "request_oplock_break: error in response received " );
917 dbgtext( "to oplock break request to pid %d ", share_entry->pid );
918 dbgtext( "on port %d ", share_entry->op_port );
919 dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
920 dbgtext( "Error was (%s).\n", strerror(errno) );
922 return False;
925 reply_msg_len = IVAL(op_break_reply,OPBRK_CMD_LEN_OFFSET);
926 reply_from_port = SVAL(op_break_reply,OPBRK_CMD_PORT_OFFSET);
928 reply_msg_start = &op_break_reply[OPBRK_CMD_HEADER_LEN];
931 #if defined(HAVE_KERNEL_OPLOCKS)
932 if((reply_msg_len != OPLOCK_BREAK_MSG_LEN) && (reply_msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN))
933 #else
934 if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
935 #endif
937 /* Ignore it. */
938 DEBUG( 0, ( "request_oplock_break: invalid message length (%d) received.", reply_msg_len ) );
939 DEBUGADD( 0, ( " Ignoring.\n" ) );
940 continue;
944 * Test to see if this is the reply we are awaiting.
947 if((SVAL(reply_msg_start,OPBRK_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
948 ((SVAL(reply_msg_start,OPBRK_MESSAGE_CMD_OFFSET) & ~CMD_REPLY) == OPLOCK_BREAK_CMD) &&
949 (reply_from_port == share_entry->op_port) &&
950 (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
951 &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
952 OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
955 * This is the reply we've been waiting for.
957 break;
959 else
962 * This is another message - a break request.
963 * Note that both kernel oplock break requests
964 * and UDP inter-smbd oplock break requests will
965 * be processed here.
967 * Process it to prevent potential deadlock.
968 * Note that the code in switch_message() prevents
969 * us from recursing into here as any SMB requests
970 * we might process that would cause another oplock
971 * break request to be made will be queued.
972 * JRA.
975 process_local_message(op_break_reply, sizeof(op_break_reply));
978 time_left -= (time(NULL) - start_time);
981 DEBUG(3,("request_oplock_break: broke oplock.\n"));
983 return True;
986 /****************************************************************************
987 Attempt to break an oplock on a file (if oplocked).
988 Returns True if the file was closed as a result of
989 the oplock break, False otherwise.
990 Used as a last ditch attempt to free a space in the
991 file table when we have run out.
992 ****************************************************************************/
993 BOOL attempt_close_oplocked_file(files_struct *fsp)
996 DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name));
998 if (fsp->open && fsp->granted_oplock && !fsp->sent_oplock_break) {
1000 /* Try and break the oplock. */
1001 file_fd_struct *fd_ptr = fsp->fd_ptr;
1002 if(oplock_break( fd_ptr->dev, fd_ptr->inode, &fsp->open_time)) {
1003 if(!fsp->open) /* Did the oplock break close the file ? */
1004 return True;
1008 return False;
1011 /****************************************************************************
1012 Init function to check if kernel level oplocks are available.
1013 ****************************************************************************/
1015 void check_kernel_oplocks(void)
1017 static BOOL done;
1020 * We only do this check once on startup.
1023 if(done)
1024 return;
1026 done = True;
1027 lp_set_kernel_oplocks(False);
1029 #if defined(HAVE_KERNEL_OPLOCKS)
1031 int fd;
1032 int pfd[2];
1033 pstring tmpname;
1035 set_process_capability(KERNEL_OPLOCK_CAPABILITY,True);
1036 set_inherited_process_capability(KERNEL_OPLOCK_CAPABILITY,True);
1038 slprintf( tmpname, sizeof(tmpname)-1, "/tmp/ot.%d.XXXXXX", (unsigned int)getpid());
1039 mktemp(tmpname);
1041 if(pipe(pfd) != 0) {
1042 DEBUG(0,("check_kernel_oplocks: Unable to create pipe. Error was %s\n",
1043 strerror(errno) ));
1044 return;
1047 if((fd = open(tmpname, O_RDWR|O_CREAT|O_TRUNC, 0600)) < 0) {
1048 DEBUG(0,("check_kernel_oplocks: Unable to open temp test file %s. Error was %s\n",
1049 tmpname, strerror(errno) ));
1050 unlink( tmpname );
1051 close(pfd[0]);
1052 close(pfd[1]);
1053 return;
1056 unlink( tmpname );
1058 if(fcntl(fd, F_OPLKREG, pfd[1]) == -1) {
1059 DEBUG(0,("check_kernel_oplocks: Kernel oplocks are not available on this machine. \
1060 Disabling kernel oplock support.\n" ));
1061 close(pfd[0]);
1062 close(pfd[1]);
1063 close(fd);
1064 return;
1067 if(fcntl(fd, F_OPLKACK, OP_REVOKE) < 0 ) {
1068 DEBUG(0,("check_kernel_oplocks: Error when removing kernel oplock. Error was %s. \
1069 Disabling kernel oplock support.\n", strerror(errno) ));
1070 close(pfd[0]);
1071 close(pfd[1]);
1072 close(fd);
1073 return;
1076 oplock_pipe_read = pfd[0];
1077 oplock_pipe_write = pfd[1];
1078 close(fd);
1080 DEBUG(3,("check_kernel_oplocks: Kernel oplocks enabled.\n"));
1082 lp_set_kernel_oplocks(True);
1084 #endif /* HAVE_KERNEL_OPLOCKS */