Added "oplock break wait time" parameter to help with Win9x oplock related
[Samba/ekacnet.git] / source / smbd / oplock.c
blob0000baa0d6749eaa0981ddd7127d509b38db0465
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 static 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, BOOL local);
42 /****************************************************************************
43 Get the number of current oplocks.
44 ****************************************************************************/
46 int32 get_number_of_open_oplocks(void)
48 return global_oplocks_open;
51 /****************************************************************************
52 Setup the kernel level oplock backchannel for this process.
53 ****************************************************************************/
55 BOOL setup_kernel_oplock_pipe(void)
57 #if defined(HAVE_KERNEL_OPLOCKS)
58 if(lp_kernel_oplocks()) {
59 int pfd[2];
61 if(pipe(pfd) != 0) {
62 DEBUG(0,("setup_kernel_oplock_pipe: Unable to create pipe. Error was %s\n",
63 strerror(errno) ));
64 return False;
67 oplock_pipe_read = pfd[0];
68 oplock_pipe_write = pfd[1];
70 #endif /* HAVE_KERNEL_OPLOCKS */
71 return True;
74 /****************************************************************************
75 open the oplock IPC socket communication
76 ****************************************************************************/
77 BOOL open_oplock_ipc(void)
79 struct sockaddr_in sock_name;
80 int len = sizeof(sock_name);
82 DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
84 /* Open a lookback UDP socket on a random port. */
85 oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK),False);
86 if (oplock_sock == -1)
88 DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
89 address %lx. Error was %s\n", (long)htonl(INADDR_LOOPBACK), strerror(errno)));
90 global_oplock_port = 0;
91 return(False);
94 /* Find out the transient UDP port we have been allocated. */
95 if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
97 DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
98 strerror(errno)));
99 close(oplock_sock);
100 oplock_sock = -1;
101 global_oplock_port = 0;
102 return False;
104 global_oplock_port = ntohs(sock_name.sin_port);
106 if(!setup_kernel_oplock_pipe())
107 return False;
109 DEBUG(3,("open_oplock ipc: pid = %d, global_oplock_port = %u\n",
110 (int)getpid(), global_oplock_port));
112 return True;
115 /****************************************************************************
116 Read an oplock break message from the either the oplock UDP fd
117 or the kernel oplock pipe fd (if kernel oplocks are supported).
119 If timeout is zero then *fds contains the file descriptors that
120 are ready to be read and acted upon. If timeout is non-zero then
121 *fds contains the file descriptors to be selected on for read.
122 The timeout is in milliseconds
124 ****************************************************************************/
126 BOOL receive_local_message(fd_set *fds, char *buffer, int buffer_len, int timeout)
128 struct sockaddr_in from;
129 int fromlen = sizeof(from);
130 int32 msg_len = 0;
132 smb_read_error = 0;
134 if(timeout != 0) {
135 struct timeval to;
136 int selrtn;
137 int maxfd = oplock_sock;
139 #if defined(HAVE_KERNEL_OPLOCKS)
140 if(lp_kernel_oplocks())
141 maxfd = MAX(maxfd, oplock_pipe_read);
142 #endif /* HAVE_KERNEL_OPLOCKS */
144 to.tv_sec = timeout / 1000;
145 to.tv_usec = (timeout % 1000) * 1000;
147 selrtn = sys_select(maxfd+1,fds,&to);
149 /* Check if error */
150 if(selrtn == -1) {
151 /* something is wrong. Maybe the socket is dead? */
152 smb_read_error = READ_ERROR;
153 return False;
156 /* Did we timeout ? */
157 if (selrtn == 0) {
158 smb_read_error = READ_TIMEOUT;
159 return False;
163 #if defined(HAVE_KERNEL_OPLOCKS)
164 if(FD_ISSET(oplock_pipe_read,fds)) {
166 * Deal with the kernel <--> smbd
167 * oplock break protocol.
170 oplock_stat_t os;
171 SMB_DEV_T dev;
172 SMB_INO_T inode;
173 char dummy;
176 * Read one byte of zero to clear the
177 * kernel break notify message.
180 if(read(oplock_pipe_read, &dummy, 1) != 1) {
181 DEBUG(0,("receive_local_message: read of kernel notification failed. \
182 Error was %s.\n", strerror(errno) ));
183 smb_read_error = READ_ERROR;
184 return False;
188 * Do a query to get the
189 * device and inode of the file that has the break
190 * request outstanding.
193 if(fcntl(oplock_pipe_read, F_OPLKSTAT, &os) < 0) {
194 DEBUG(0,("receive_local_message: fcntl of kernel notification failed. \
195 Error was %s.\n", strerror(errno) ));
196 if(errno == EAGAIN) {
198 * Duplicate kernel break message - ignore.
200 memset(buffer, '\0', KERNEL_OPLOCK_BREAK_MSG_LEN);
201 return True;
203 smb_read_error = READ_ERROR;
204 return False;
207 dev = (SMB_DEV_T)os.os_dev;
208 inode = (SMB_DEV_T)os.os_ino;
210 DEBUG(5,("receive_local_message: kernel oplock break request received for \
211 dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode ));
214 * Create a kernel oplock break message.
217 /* Setup the message header */
218 SIVAL(buffer,OPBRK_CMD_LEN_OFFSET,KERNEL_OPLOCK_BREAK_MSG_LEN);
219 SSVAL(buffer,OPBRK_CMD_PORT_OFFSET,0);
221 buffer += OPBRK_CMD_HEADER_LEN;
223 SSVAL(buffer,OPBRK_MESSAGE_CMD_OFFSET,KERNEL_OPLOCK_BREAK_CMD);
224 SIVAL(buffer,KERNEL_OPLOCK_BREAK_DEV_OFFSET,dev);
226 #ifdef LARGE_SMB_INO_T
227 SIVAL(buffer,KERNEL_OPLOCK_BREAK_INODE_OFFSET,inode & 0xFFFFFFFF);
228 SIVAL(buffer,KERNEL_OPLOCK_BREAK_INODE_OFFSET+4, (inode >> 32 ) & 0xFFFFFFFF );
229 #else /* LARGE_SMB_INO_T */
230 SIVAL(buffer,KERNEL_OPLOCK_BREAK_INODE_OFFSET,inode);
231 #endif /* LARGE_SMB_INO_T */
233 return True;
235 #endif /* HAVE_KERNEL_OPLOCKS */
238 * From here down we deal with the smbd <--> smbd
239 * oplock break protocol only.
243 * Read a loopback udp message.
245 msg_len = recvfrom(oplock_sock, &buffer[OPBRK_CMD_HEADER_LEN],
246 buffer_len - OPBRK_CMD_HEADER_LEN, 0,
247 (struct sockaddr *)&from, &fromlen);
249 if(msg_len < 0) {
250 DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno)));
251 return False;
254 /* Validate message length. */
255 if(msg_len > (buffer_len - OPBRK_CMD_HEADER_LEN)) {
256 DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n",
257 msg_len,
258 buffer_len - OPBRK_CMD_HEADER_LEN));
259 return False;
262 /* Validate message from address (must be localhost). */
263 if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) {
264 DEBUG(0,("receive_local_message: invalid 'from' address \
265 (was %lx should be 127.0.0.1\n", (long)from.sin_addr.s_addr));
266 return False;
269 /* Setup the message header */
270 SIVAL(buffer,OPBRK_CMD_LEN_OFFSET,msg_len);
271 SSVAL(buffer,OPBRK_CMD_PORT_OFFSET,ntohs(from.sin_port));
273 return True;
276 /****************************************************************************
277 Attempt to set an oplock on a file. Always succeeds if kernel oplocks are
278 disabled (just sets flags). Returns True if oplock set.
279 ****************************************************************************/
281 BOOL set_file_oplock(files_struct *fsp)
283 #if defined(HAVE_KERNEL_OPLOCKS)
284 if(lp_kernel_oplocks()) {
286 if(fcntl(fsp->fd_ptr->fd, F_OPLKREG, oplock_pipe_write) < 0 ) {
287 if(errno != EAGAIN) {
288 DEBUG(0,("set_file_oplock: Unable to get kernel oplock on file %s, dev = %x, \
289 inode = %.0f. Error was %s\n",
290 fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode,
291 strerror(errno) ));
292 } else {
293 DEBUG(5,("set_file_oplock: Refused oplock on file %s, fd = %d, dev = %x, \
294 inode = %.0f. Another process had the file open.\n",
295 fsp->fsp_name, fsp->fd_ptr->fd, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode ));
297 return False;
300 DEBUG(10,("set_file_oplock: got kernel oplock on file %s, dev = %x, inode = %.0f\n",
301 fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode));
304 #endif /* HAVE_KERNEL_OPLOCKS */
306 DEBUG(5,("set_file_oplock: granted oplock on file %s, dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
307 fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev, (double)fsp->fd_ptr->inode,
308 (int)fsp->open_time.tv_sec, (int)fsp->open_time.tv_usec ));
310 fsp->granted_oplock = True;
311 fsp->sent_oplock_break = False;
312 global_oplocks_open++;
314 return True;
317 /****************************************************************************
318 Attempt to release an oplock on a file. Always succeeds if kernel oplocks are
319 disabled (just clears flags).
320 ****************************************************************************/
322 void release_file_oplock(files_struct *fsp)
324 #if defined(HAVE_KERNEL_OPLOCKS)
326 if(lp_kernel_oplocks())
328 if( DEBUGLVL( 10 ))
331 * Check and print out the current kernel
332 * oplock state of this file.
334 int state = fcntl(fsp->fd_ptr->fd, F_OPLKACK, -1);
335 dbgtext("release_file_oplock: file %s, dev = %x, inode = %.0f has kernel \
336 oplock state of %x.\n", fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev,
337 (double)fsp->fd_ptr->inode, state );
341 * Remote the kernel oplock on this file.
344 if(fcntl(fsp->fd_ptr->fd, F_OPLKACK, OP_REVOKE) < 0)
346 if( DEBUGLVL( 0 ))
348 dbgtext("release_file_oplock: Error when removing kernel oplock on file " );
349 dbgtext("%s, dev = %x, inode = %.0f. Error was %s\n",
350 fsp->fsp_name, (unsigned int)fsp->fd_ptr->dev,
351 (double)fsp->fd_ptr->inode, strerror(errno) );
355 #endif /* HAVE_KERNEL_OPLOCKS */
357 fsp->granted_oplock = False;
358 fsp->sent_oplock_break = False;
359 global_oplocks_open--;
362 /****************************************************************************
363 Setup the listening set of file descriptors for an oplock break
364 message either from the UDP socket or from the kernel. Returns the maximum
365 fd used.
366 ****************************************************************************/
368 int setup_oplock_select_set( fd_set *fds)
370 int maxfd = oplock_sock;
371 FD_SET(oplock_sock,fds);
373 if(oplock_sock == -1)
374 return 0;
376 #if defined(HAVE_KERNEL_OPLOCKS)
377 if(lp_kernel_oplocks()) {
378 FD_SET(oplock_pipe_read,fds);
379 maxfd = MAX(maxfd,oplock_pipe_read);
381 #endif /* HAVE_KERNEL_OPLOCKS */
383 return maxfd;
386 /****************************************************************************
387 Process an oplock break message - whether it came from the UDP socket
388 or from the kernel.
389 ****************************************************************************/
391 BOOL process_local_message(char *buffer, int buf_size)
393 int32 msg_len;
394 uint16 from_port;
395 char *msg_start;
396 SMB_DEV_T dev;
397 SMB_INO_T inode;
398 uint32 remotepid;
399 struct timeval tval;
400 struct timeval *ptval = NULL;
402 msg_len = IVAL(buffer,OPBRK_CMD_LEN_OFFSET);
403 from_port = SVAL(buffer,OPBRK_CMD_PORT_OFFSET);
405 msg_start = &buffer[OPBRK_CMD_HEADER_LEN];
407 DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n",
408 msg_len, from_port));
411 * Pull the info out of the requesting packet.
414 switch(SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET))
416 #if defined(HAVE_KERNEL_OPLOCKS)
417 case KERNEL_OPLOCK_BREAK_CMD:
418 /* Ensure that the msg length is correct. */
419 if(msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN)
421 DEBUG(0,("process_local_message: incorrect length for KERNEL_OPLOCK_BREAK_CMD (was %d, \
422 should be %d).\n", msg_len, KERNEL_OPLOCK_BREAK_MSG_LEN));
423 return False;
427 * Warning - beware of SMB_INO_T <> 4 bytes. !!
429 #ifdef LARGE_SMB_INO_T
430 SMB_INO_T inode_low = IVAL(msg_start, KERNEL_OPLOCK_BREAK_INODE_OFFSET);
431 SMB_INO_T inode_high = IVAL(msg_start, KERNEL_OPLOCK_BREAK_INODE_OFFSET + 4);
432 inode = inode_low | (inode_high << 32);
433 #else /* LARGE_SMB_INO_T */
434 inode = IVAL(msg_start, KERNEL_OPLOCK_BREAK_INODE_OFFSET);
435 #endif /* LARGE_SMB_INO_T */
437 dev = IVAL(msg_start,KERNEL_OPLOCK_BREAK_DEV_OFFSET);
439 ptval = NULL;
441 DEBUG(5,("process_local_message: kernel oplock break request for \
442 file dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode));
444 break;
445 #endif /* HAVE_KERNEL_OPLOCKS */
447 case OPLOCK_BREAK_CMD:
448 /* Ensure that the msg length is correct. */
449 if(msg_len != OPLOCK_BREAK_MSG_LEN)
451 DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
452 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
453 return False;
457 * Warning - beware of SMB_INO_T <> 4 bytes. !!
459 #ifdef LARGE_SMB_INO_T
460 SMB_INO_T inode_low = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
461 SMB_INO_T inode_high = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET + 4);
462 inode = inode_low | (inode_high << 32);
463 #else /* LARGE_SMB_INO_T */
464 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
465 #endif /* LARGE_SMB_INO_T */
467 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
469 tval.tv_sec = (time_t)IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
470 tval.tv_usec = (long)IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
472 ptval = &tval;
474 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
476 DEBUG(5,("process_local_message: oplock break request from \
477 pid %d, port %d, dev = %x, inode = %.0f\n", remotepid, from_port, (unsigned int)dev, (double)inode));
479 break;
482 * Keep this as a debug case - eventually we can remove it.
484 case 0x8001:
485 DEBUG(0,("process_local_message: Received unsolicited break \
486 reply - dumping info.\n"));
488 if(msg_len != OPLOCK_BREAK_MSG_LEN)
490 DEBUG(0,("process_local_message: ubr: incorrect length for reply \
491 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
492 return False;
497 * Warning - beware of SMB_INO_T <> 4 bytes. !!
499 #ifdef LARGE_SMB_INO_T
500 SMB_INO_T inode_low = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
501 SMB_INO_T inode_high = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET + 4);
502 inode = inode_low | (inode_high << 32);
503 #else /* LARGE_SMB_INO_T */
504 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
505 #endif /* LARGE_SMB_INO_T */
507 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
508 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
510 DEBUG(0,("process_local_message: unsolicited oplock break reply from \
511 pid %d, port %d, dev = %x, inode = %.0f\n", remotepid, from_port, (unsigned int)dev, (double)inode));
514 return False;
516 default:
517 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
518 (unsigned int)SVAL(msg_start,0)));
519 return False;
523 * Now actually process the break request.
526 if(global_oplocks_open != 0)
528 if(oplock_break(dev, inode, ptval, False) == False)
530 DEBUG(0,("process_local_message: oplock break failed.\n"));
531 return False;
534 else
537 * If we have no record of any currently open oplocks,
538 * it's not an error, as a close command may have
539 * just been issued on the file that was oplocked.
540 * Just log a message and return success in this case.
542 DEBUG(3,("process_local_message: oplock break requested with no outstanding \
543 oplocks. Returning success.\n"));
547 * Do the appropriate reply - none in the kernel case.
550 if(SVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET) == OPLOCK_BREAK_CMD)
552 struct sockaddr_in toaddr;
554 /* Send the message back after OR'ing in the 'REPLY' bit. */
555 SSVAL(msg_start,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
557 memset((char *)&toaddr,'\0',sizeof(toaddr));
558 toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
559 toaddr.sin_port = htons(from_port);
560 toaddr.sin_family = AF_INET;
562 if(sendto( oplock_sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
563 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0)
565 DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
566 remotepid, strerror(errno)));
567 return False;
570 DEBUG(5,("process_local_message: oplock break reply sent to \
571 pid %d, port %d, for file dev = %x, inode = %.0f\n",
572 remotepid, from_port, (unsigned int)dev, (double)inode));
575 return True;
578 /****************************************************************************
579 Set up an oplock break message.
580 ****************************************************************************/
582 static void prepare_break_message(char *outbuf, files_struct *fsp, BOOL level2)
584 memset(outbuf,'\0',smb_size);
585 set_message(outbuf,8,0,True);
587 SCVAL(outbuf,smb_com,SMBlockingX);
588 SSVAL(outbuf,smb_tid,fsp->conn->cnum);
589 SSVAL(outbuf,smb_pid,0xFFFF);
590 SSVAL(outbuf,smb_uid,0);
591 SSVAL(outbuf,smb_mid,0xFFFF);
592 SCVAL(outbuf,smb_vwv0,0xFF);
593 SSVAL(outbuf,smb_vwv2,fsp->fnum);
594 SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
595 SCVAL(outbuf,smb_vwv3+1,level2 ? OPLOCKLEVEL_II : OPLOCKLEVEL_NONE);
598 /****************************************************************************
599 Process an oplock break directly.
600 ****************************************************************************/
602 static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval, BOOL local_request)
604 extern struct current_user current_user;
605 extern struct timeval smb_last_time;
606 extern int Client;
607 char *inbuf = NULL;
608 char *outbuf = NULL;
609 files_struct *fsp = NULL;
610 time_t start_time;
611 BOOL shutdown_server = False;
612 connection_struct *saved_conn;
613 int saved_vuid;
614 pstring saved_dir;
615 int break_counter = OPLOCK_BREAK_RESENDS;
616 int timeout = (OPLOCK_BREAK_TIMEOUT/OPLOCK_BREAK_RESENDS) * 1000;
618 if( DEBUGLVL( 3 ) )
620 dbgtext( "oplock_break: called for dev = %x, inode = %.0f tv_sec = %x, tv_usec = %x.\n",
621 (unsigned int)dev, (double)inode, tval ? (int)tval->tv_sec : 0,
622 tval ? (int)tval->tv_usec : 0);
623 dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
626 /* We need to search the file open table for the
627 entry containing this dev and inode, and ensure
628 we have an oplock on it. */
629 fsp = file_find_dit(dev, inode, tval);
631 if(fsp == NULL)
633 /* The file could have been closed in the meantime - return success. */
634 if( DEBUGLVL( 0 ) )
636 dbgtext( "oplock_break: cannot find open file with " );
637 dbgtext( "dev = %x, inode = %.0f ", (unsigned int)dev, (double)inode);
638 dbgtext( "allowing break to succeed.\n" );
640 return True;
643 /* Ensure we have an oplock on the file */
645 /* There is a potential race condition in that an oplock could
646 have been broken due to another udp request, and yet there are
647 still oplock break messages being sent in the udp message
648 queue for this file. So return true if we don't have an oplock,
649 as we may have just freed it.
652 if(!fsp->granted_oplock)
654 if( DEBUGLVL( 0 ) )
656 dbgtext( "oplock_break: file %s ", fsp->fsp_name );
657 dbgtext( "(dev = %x, inode = %.0f) has no oplock.\n", (unsigned int)dev, (double)inode );
658 dbgtext( "Allowing break to succeed regardless.\n" );
660 return True;
663 /* mark the oplock break as sent - we don't want to send twice! */
664 if (fsp->sent_oplock_break)
666 if( DEBUGLVL( 0 ) )
668 dbgtext( "oplock_break: ERROR: oplock_break already sent for " );
669 dbgtext( "file %s ", fsp->fsp_name);
670 dbgtext( "(dev = %x, inode = %.0f)\n", (unsigned int)dev, (double)inode );
673 /* We have to fail the open here as we cannot send another oplock break on
674 this file whilst we are awaiting a response from the client - neither
675 can we allow another open to succeed while we are waiting for the
676 client.
678 return False;
681 if(global_oplock_break) {
682 DEBUG(0,("ABORT : ABORT : recursion in oplock_break !!!!!\n"));
683 abort();
686 /* Now comes the horrid part. We must send an oplock break to the client,
687 and then process incoming messages until we get a close or oplock release.
688 At this point we know we need a new inbuf/outbuf buffer pair.
689 We cannot use these staticaly as we may recurse into here due to
690 messages crossing on the wire.
693 if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
695 DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
696 return False;
699 if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
701 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
702 free(inbuf);
703 inbuf = NULL;
704 return False;
708 * If we are sending an oplock break due to an SMB sent
709 * by our own client we ensure that we wait at leat
710 * lp_oplock_break_wait_time() milliseconds before sending
711 * the packet. Sending the packet sooner can break Win9x
712 * and has reported to cause problems on NT. JRA.
715 if(local_request) {
716 struct timeval cur_tv;
717 long wait_left = (long)lp_oplock_break_wait_time();
719 GetTimeOfDay(&cur_tv);
721 wait_left -= ((cur_tv.tv_sec - smb_last_time.tv_sec)*1000) +
722 ((cur_tv.tv_usec - smb_last_time.tv_usec)/1000);
724 if(wait_left > 0) {
725 wait_left = MIN(wait_left, 1000);
726 sys_usleep(wait_left * 1000);
730 /* Prepare the SMBlockingX message. */
732 prepare_break_message( outbuf, fsp, False);
733 send_smb(Client, outbuf);
735 if(get_remote_arch() == RA_WIN95)
736 timeout = 200;
738 /* Remember we just sent an oplock break on this file. */
739 fsp->sent_oplock_break = True;
741 /* We need this in case a readraw crosses on the wire. */
742 global_oplock_break = True;
744 /* Process incoming messages. */
746 /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
747 seconds we should just die.... */
749 start_time = time(NULL);
752 * Save the information we need to re-become the
753 * user, then unbecome the user whilst we're doing this.
755 saved_conn = fsp->conn;
756 saved_vuid = current_user.vuid;
757 dos_GetWd(saved_dir);
758 unbecome_user();
759 /* Save the chain fnum. */
760 file_chain_save();
762 while(OPEN_FSP(fsp) && fsp->granted_oplock)
764 if(receive_smb(Client,inbuf, timeout) == False)
768 * Win95 specific oplock processing...
771 if (smb_read_error == READ_TIMEOUT && timeout == 200) {
772 send_null_session_msg(Client);
773 timeout = ((OPLOCK_BREAK_TIMEOUT/OPLOCK_BREAK_RESENDS) * 1000) -
774 ((OPLOCK_BREAK_RESENDS - break_counter)*200);
775 continue;
779 * Isaac suggestd that if a MS client doesn't respond to a
780 * oplock break request then we might try resending
781 * it. Certainly it's no worse than just dropping the
782 * socket!
785 if (smb_read_error == READ_TIMEOUT && break_counter--) {
786 DEBUG(0, ( "oplock_break resend\n" ) );
787 send_smb(Client, outbuf);
789 if(get_remote_arch() == RA_WIN95)
790 timeout = 200;
791 continue;
795 * Die if we got an error.
798 if (smb_read_error == READ_EOF)
799 DEBUG( 0, ( "oplock_break: end of file from client\n" ) );
801 if (smb_read_error == READ_ERROR)
802 DEBUG( 0, ("oplock_break: receive_smb error (%s)\n", strerror(errno)) );
804 if (smb_read_error == READ_TIMEOUT)
805 DEBUG( 0, ( "oplock_break: receive_smb timed out after %d seconds.\n",
806 OPLOCK_BREAK_TIMEOUT ) );
808 DEBUGADD( 0, ( "oplock_break failed for file %s ", fsp->fsp_name ) );
809 DEBUGADD( 0, ( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode));
811 shutdown_server = True;
812 break;
816 * There are certain SMB requests that we shouldn't allow
817 * to recurse. opens, renames and deletes are the obvious
818 * ones. This is handled in the switch_message() function.
819 * If global_oplock_break is set they will push the packet onto
820 * the pending smb queue and return -1 (no reply).
821 * JRA.
824 process_smb(inbuf, outbuf);
827 * Die if we go over the time limit.
830 if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
832 if( DEBUGLVL( 0 ) )
834 dbgtext( "oplock_break: no break received from client " );
835 dbgtext( "within %d seconds.\n", OPLOCK_BREAK_TIMEOUT );
836 dbgtext( "oplock_break failed for file %s ", fsp->fsp_name );
837 dbgtext( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode );
839 shutdown_server = True;
840 break;
845 * Go back to being the user who requested the oplock
846 * break.
848 if(!become_user(saved_conn, saved_vuid))
850 DEBUG( 0, ( "oplock_break: unable to re-become user!" ) );
851 DEBUGADD( 0, ( "Shutting down server\n" ) );
852 close_sockets();
853 close(oplock_sock);
854 exit_server("unable to re-become user");
856 /* Including the directory. */
857 dos_ChDir(saved_dir);
859 /* Restore the chain fnum. */
860 file_chain_restore();
862 /* Free the buffers we've been using to recurse. */
863 free(inbuf);
864 free(outbuf);
866 /* We need this in case a readraw crossed on the wire. */
867 if(global_oplock_break)
868 global_oplock_break = False;
871 * If the client did not respond we must die.
874 if(shutdown_server)
876 DEBUG( 0, ( "oplock_break: client failure in break - " ) );
877 DEBUGADD( 0, ( "shutting down this smbd.\n" ) );
878 close_sockets();
879 close(oplock_sock);
880 exit_server("oplock break failure");
883 /* Santity check - remove this later. JRA */
884 if(global_oplocks_open < 0)
886 DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
887 global_oplocks_open));
888 exit_server("oplock_break: global_oplocks_open < 0");
892 if( DEBUGLVL( 3 ) )
894 dbgtext( "oplock_break: returning success for " );
895 dbgtext( "dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
896 dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
899 return True;
902 /****************************************************************************
903 Send an oplock break message to another smbd process. If the oplock is held
904 by the local smbd then call the oplock break function directly.
905 ****************************************************************************/
907 BOOL request_oplock_break(share_mode_entry *share_entry,
908 SMB_DEV_T dev, SMB_INO_T inode)
910 char op_break_msg[OPLOCK_BREAK_MSG_LEN];
911 struct sockaddr_in addr_out;
912 int pid = getpid();
913 time_t start_time;
914 int time_left;
916 if(pid == share_entry->pid)
918 /* We are breaking our own oplock, make sure it's us. */
919 if(share_entry->op_port != global_oplock_port)
921 DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
922 should be %d\n", pid, share_entry->op_port, global_oplock_port));
923 return False;
926 DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
928 /* Call oplock break direct. */
929 return oplock_break(dev, inode, &share_entry->time, True);
932 /* We need to send a OPLOCK_BREAK_CMD message to the
933 port in the share mode entry. */
935 SSVAL(op_break_msg,OPBRK_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
936 SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
937 SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
938 SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
939 SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
941 * WARNING - beware of SMB_INO_T <> 4 bytes.
943 #ifdef LARGE_SMB_INO_T
944 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,(inode & 0xFFFFFFFFL));
945 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET+4,((inode >> 32) & 0xFFFFFFFFL));
946 #else /* LARGE_SMB_INO_T */
947 SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
948 #endif /* LARGE_SMB_INO_T */
950 /* set the address and port */
951 memset((char *)&addr_out,'\0',sizeof(addr_out));
952 addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
953 addr_out.sin_port = htons( share_entry->op_port );
954 addr_out.sin_family = AF_INET;
956 if( DEBUGLVL( 3 ) )
958 dbgtext( "request_oplock_break: sending a oplock break message to " );
959 dbgtext( "pid %d on port %d ", share_entry->pid, share_entry->op_port );
960 dbgtext( "for dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
961 (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
962 (int)share_entry->time.tv_usec );
966 if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
967 (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
969 if( DEBUGLVL( 0 ) )
971 dbgtext( "request_oplock_break: failed when sending a oplock " );
972 dbgtext( "break message to pid %d ", share_entry->pid );
973 dbgtext( "on port %d ", share_entry->op_port );
974 dbgtext( "for dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
975 (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
976 (int)share_entry->time.tv_usec );
977 dbgtext( "Error was %s\n", strerror(errno) );
979 return False;
983 * Now we must await the oplock broken message coming back
984 * from the target smbd process. Timeout if it fails to
985 * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
986 * While we get messages that aren't ours, loop.
989 start_time = time(NULL);
990 time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
992 while(time_left >= 0)
994 char op_break_reply[OPBRK_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
995 int32 reply_msg_len;
996 uint16 reply_from_port;
997 char *reply_msg_start;
998 fd_set fds;
1000 FD_ZERO(&fds);
1001 FD_SET(oplock_sock,&fds);
1002 #if defined(HAVE_KERNEL_OPLOCKS)
1003 if(lp_kernel_oplocks())
1004 FD_SET(oplock_pipe_read,&fds);
1005 #endif /* HAVE_KERNEL_OPLOCKS */
1007 if(receive_local_message(&fds, op_break_reply, sizeof(op_break_reply),
1008 time_left ? time_left * 1000 : 1) == False)
1010 if(smb_read_error == READ_TIMEOUT)
1012 if( DEBUGLVL( 0 ) )
1014 dbgtext( "request_oplock_break: no response received to oplock " );
1015 dbgtext( "break request to pid %d ", share_entry->pid );
1016 dbgtext( "on port %d ", share_entry->op_port );
1017 dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
1018 dbgtext( "for dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
1019 (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
1020 (int)share_entry->time.tv_usec );
1024 * This is a hack to make handling of failing clients more robust.
1025 * If a oplock break response message is not received in the timeout
1026 * period we may assume that the smbd servicing that client holding
1027 * the oplock has died and the client changes were lost anyway, so
1028 * we should continue to try and open the file.
1030 break;
1032 else
1033 if( DEBUGLVL( 0 ) )
1035 dbgtext( "request_oplock_break: error in response received " );
1036 dbgtext( "to oplock break request to pid %d ", share_entry->pid );
1037 dbgtext( "on port %d ", share_entry->op_port );
1038 dbgtext( "for dev = %x, inode = %.0f, tv_sec = %x, tv_usec = %x\n",
1039 (unsigned int)dev, (double)inode, (int)share_entry->time.tv_sec,
1040 (int)share_entry->time.tv_usec );
1041 dbgtext( "Error was (%s).\n", strerror(errno) );
1043 return False;
1046 reply_msg_len = IVAL(op_break_reply,OPBRK_CMD_LEN_OFFSET);
1047 reply_from_port = SVAL(op_break_reply,OPBRK_CMD_PORT_OFFSET);
1049 reply_msg_start = &op_break_reply[OPBRK_CMD_HEADER_LEN];
1052 #if defined(HAVE_KERNEL_OPLOCKS)
1053 if((reply_msg_len != OPLOCK_BREAK_MSG_LEN) && (reply_msg_len != KERNEL_OPLOCK_BREAK_MSG_LEN))
1054 #else
1055 if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
1056 #endif
1058 /* Ignore it. */
1059 DEBUG( 0, ( "request_oplock_break: invalid message length (%d) received.", reply_msg_len ) );
1060 DEBUGADD( 0, ( " Ignoring.\n" ) );
1061 continue;
1065 * Test to see if this is the reply we are awaiting.
1068 if((SVAL(reply_msg_start,OPBRK_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
1069 ((SVAL(reply_msg_start,OPBRK_MESSAGE_CMD_OFFSET) & ~CMD_REPLY) == OPLOCK_BREAK_CMD) &&
1070 (reply_from_port == share_entry->op_port) &&
1071 (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET],
1072 &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
1073 OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
1076 * This is the reply we've been waiting for.
1078 break;
1080 else
1083 * This is another message - a break request.
1084 * Note that both kernel oplock break requests
1085 * and UDP inter-smbd oplock break requests will
1086 * be processed here.
1088 * Process it to prevent potential deadlock.
1089 * Note that the code in switch_message() prevents
1090 * us from recursing into here as any SMB requests
1091 * we might process that would cause another oplock
1092 * break request to be made will be queued.
1093 * JRA.
1096 process_local_message(op_break_reply, sizeof(op_break_reply));
1099 time_left -= (time(NULL) - start_time);
1102 DEBUG(3,("request_oplock_break: broke oplock.\n"));
1104 return True;
1107 /****************************************************************************
1108 Attempt to break an oplock on a file (if oplocked).
1109 Returns True if the file was closed as a result of
1110 the oplock break, False otherwise.
1111 Used as a last ditch attempt to free a space in the
1112 file table when we have run out.
1113 ****************************************************************************/
1114 BOOL attempt_close_oplocked_file(files_struct *fsp)
1117 DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name));
1119 if (fsp->open && fsp->granted_oplock && !fsp->sent_oplock_break && (fsp->fd_ptr != NULL)) {
1121 /* Try and break the oplock. */
1122 file_fd_struct *fd_ptr = fsp->fd_ptr;
1123 if(oplock_break( fd_ptr->dev, fd_ptr->inode, &fsp->open_time, True)) {
1124 if(!fsp->open) /* Did the oplock break close the file ? */
1125 return True;
1129 return False;
1132 /****************************************************************************
1133 Init function to check if kernel level oplocks are available.
1134 ****************************************************************************/
1136 void check_kernel_oplocks(void)
1138 static BOOL done;
1141 * We only do this check once on startup.
1144 if(done)
1145 return;
1147 done = True;
1148 lp_set_kernel_oplocks(False);
1150 #if defined(HAVE_KERNEL_OPLOCKS)
1152 int fd;
1153 int pfd[2];
1154 pstring tmpname;
1156 set_process_capability(KERNEL_OPLOCK_CAPABILITY,True);
1157 set_inherited_process_capability(KERNEL_OPLOCK_CAPABILITY,True);
1159 slprintf(tmpname,sizeof(tmpname)-1, "%s/koplock.%d", lp_lockdir(), (int)getpid());
1161 if(pipe(pfd) != 0) {
1162 DEBUG(0,("check_kernel_oplocks: Unable to create pipe. Error was %s\n",
1163 strerror(errno) ));
1164 return;
1167 if((fd = sys_open(tmpname, O_RDWR|O_CREAT|O_EXCL|O_TRUNC, 0600)) < 0) {
1168 DEBUG(0,("check_kernel_oplocks: Unable to open temp test file %s. Error was %s\n",
1169 tmpname, strerror(errno) ));
1170 unlink( tmpname );
1171 close(pfd[0]);
1172 close(pfd[1]);
1173 return;
1176 unlink( tmpname );
1178 if(fcntl(fd, F_OPLKREG, pfd[1]) == -1) {
1179 DEBUG(0,("check_kernel_oplocks: Kernel oplocks are not available on this machine. \
1180 Disabling kernel oplock support.\n" ));
1181 close(pfd[0]);
1182 close(pfd[1]);
1183 close(fd);
1184 return;
1187 if(fcntl(fd, F_OPLKACK, OP_REVOKE) < 0 ) {
1188 DEBUG(0,("check_kernel_oplocks: Error when removing kernel oplock. Error was %s. \
1189 Disabling kernel oplock support.\n", strerror(errno) ));
1190 close(pfd[0]);
1191 close(pfd[1]);
1192 close(fd);
1193 return;
1196 close(pfd[0]);
1197 close(pfd[1]);
1198 close(fd);
1200 lp_set_kernel_oplocks(True);
1202 DEBUG(0,("check_kernel_oplocks: Kernel oplocks available and set to %s.\n",
1203 lp_kernel_oplocks() ? "True" : "False" ));
1206 #endif /* HAVE_KERNEL_OPLOCKS */