2 Unix SMB/Netbios implementation.
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.
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()) {
62 DEBUG(0,("setup_kernel_oplock_pipe: Unable to create pipe. Error was %s\n",
67 oplock_pipe_read
= pfd
[0];
68 oplock_pipe_write
= pfd
[1];
70 #endif /* HAVE_KERNEL_OPLOCKS */
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;
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",
101 global_oplock_port
= 0;
104 global_oplock_port
= ntohs(sock_name
.sin_port
);
106 if(!setup_kernel_oplock_pipe())
109 DEBUG(3,("open_oplock ipc: pid = %d, global_oplock_port = %u\n",
110 (int)getpid(), global_oplock_port
));
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
);
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
);
151 /* something is wrong. Maybe the socket is dead? */
152 smb_read_error
= READ_ERROR
;
156 /* Did we timeout ? */
158 smb_read_error
= READ_TIMEOUT
;
163 #if defined(HAVE_KERNEL_OPLOCKS)
164 if(FD_ISSET(oplock_pipe_read
,fds
)) {
166 * Deal with the kernel <--> smbd
167 * oplock break protocol.
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
;
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
);
203 smb_read_error
= READ_ERROR
;
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 */
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
);
250 DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno
)));
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",
258 buffer_len
- OPBRK_CMD_HEADER_LEN
));
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
));
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
));
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
,
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
));
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
++;
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())
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)
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
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)
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 */
386 /****************************************************************************
387 Process an oplock break message - whether it came from the UDP socket
389 ****************************************************************************/
391 BOOL
process_local_message(char *buffer
, int buf_size
)
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
));
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
);
441 DEBUG(5,("process_local_message: kernel oplock break request for \
442 file dev = %x, inode = %.0f\n", (unsigned int)dev
, (double)inode
));
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
));
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
);
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
));
482 * Keep this as a debug case - eventually we can remove it.
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
));
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
));
517 DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
518 (unsigned int)SVAL(msg_start
,0)));
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"));
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
)));
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
));
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
;
609 files_struct
*fsp
= NULL
;
611 BOOL shutdown_server
= False
;
612 connection_struct
*saved_conn
;
615 int break_counter
= OPLOCK_BREAK_RESENDS
;
616 int timeout
= (OPLOCK_BREAK_TIMEOUT
/OPLOCK_BREAK_RESENDS
) * 1000;
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
);
633 /* The file could have been closed in the meantime - return success. */
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" );
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
)
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" );
663 /* mark the oplock break as sent - we don't want to send twice! */
664 if (fsp
->sent_oplock_break
)
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
681 if(global_oplock_break
) {
682 DEBUG(0,("ABORT : ABORT : recursion in oplock_break !!!!!\n"));
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"));
699 if((outbuf
= (char *)malloc(BUFFER_SIZE
+ SAFETY_MARGIN
))==NULL
)
701 DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
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.
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);
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
)
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
);
759 /* Save the chain fnum. */
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);
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
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
)
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
;
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).
824 process_smb(inbuf
, outbuf
);
827 * Die if we go over the time limit.
830 if((time(NULL
) - start_time
) > OPLOCK_BREAK_TIMEOUT
)
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
;
845 * Go back to being the user who requested the oplock
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" ) );
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. */
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.
876 DEBUG( 0, ( "oplock_break: client failure in break - " ) );
877 DEBUGADD( 0, ( "shutting down this smbd.\n" ) );
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");
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
);
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
;
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
));
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
;
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)
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
) );
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
];
996 uint16 reply_from_port
;
997 char *reply_msg_start
;
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
)
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.
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
) );
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
))
1055 if(reply_msg_len
!= OPLOCK_BREAK_MSG_LEN
)
1059 DEBUG( 0, ( "request_oplock_break: invalid message length (%d) received.", reply_msg_len
) );
1060 DEBUGADD( 0, ( " Ignoring.\n" ) );
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.
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.
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"));
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 ? */
1132 /****************************************************************************
1133 Init function to check if kernel level oplocks are available.
1134 ****************************************************************************/
1136 void check_kernel_oplocks(void)
1141 * We only do this check once on startup.
1148 lp_set_kernel_oplocks(False
);
1150 #if defined(HAVE_KERNEL_OPLOCKS)
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",
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
) ));
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" ));
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
) ));
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 */