Added ssize_t to configure code.
[samba.git] / source / smbd / oplock.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    oplock processing
5    Copyright (C) Andrew Tridgell 1992-1998
6    
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.
11    
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.
16    
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.
20 */
21
22 #include "includes.h"
23
24 extern int DEBUGLEVEL;
25
26 /* Oplock ipc UDP socket. */
27 int oplock_sock = -1;
28 uint16 oplock_port = 0;
29
30 /* Current number of oplocks we have outstanding. */
31 int32 global_oplocks_open = 0;
32 BOOL global_oplock_break = False;
33
34
35 extern int smb_read_error;
36
37 static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval);
38
39
40 /****************************************************************************
41   open the oplock IPC socket communication
42 ****************************************************************************/
43 BOOL open_oplock_ipc(void)
44 {
45   struct sockaddr_in sock_name;
46   int len = sizeof(sock_name);
47
48   DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
49
50   /* Open a lookback UDP socket on a random port. */
51   oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK));
52   if (oplock_sock == -1)
53   {
54     DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \
55 address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno)));
56     oplock_port = 0;
57     return(False);
58   }
59
60   /* Find out the transient UDP port we have been allocated. */
61   if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &len)<0)
62   {
63     DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n",
64             strerror(errno)));
65     close(oplock_sock);
66     oplock_sock = -1;
67     oplock_port = 0;
68     return False;
69   }
70   oplock_port = ntohs(sock_name.sin_port);
71
72   DEBUG(3,("open_oplock ipc: pid = %d, oplock_port = %u\n", 
73             (int)getpid(), oplock_port));
74
75   return True;
76 }
77
78 /****************************************************************************
79   process an oplock break message.
80 ****************************************************************************/
81 BOOL process_local_message(int sock, char *buffer, int buf_size)
82 {
83   int32 msg_len;
84   uint16 from_port;
85   char *msg_start;
86
87   msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET);
88   from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET);
89
90   msg_start = &buffer[UDP_CMD_HEADER_LEN];
91
92   DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n", 
93             msg_len, from_port));
94
95   /* Switch on message command - currently OPLOCK_BREAK_CMD is the
96      only valid request. */
97
98   switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET))
99   {
100     case OPLOCK_BREAK_CMD:
101       /* Ensure that the msg length is correct. */
102       if(msg_len != OPLOCK_BREAK_MSG_LEN)
103       {
104         DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \
105 should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
106         return False;
107       }
108       {
109         uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
110         SMB_DEV_T dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
111         /*
112          * Warning - beware of SMB_INO_T <> 4 bytes. !!
113          */
114 #ifdef LARGE_SMB_INO_T
115         SMB_INO_T inode_low = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
116         SMB_INO_T inode_high = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET + 4);
117         SMB_INO_T inode = inode_low | (inode_high << 32);
118 #else /* LARGE_SMB_INO_T */
119         SMB_INO_T inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
120 #endif /* LARGE_SMB_INO_T */
121         struct timeval tval;
122         struct sockaddr_in toaddr;
123
124         tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET);
125         tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET);
126
127         DEBUG(5,("process_local_message: oplock break request from \
128 pid %d, port %d, dev = %x, inode = %.0f\n", remotepid, from_port, (unsigned int)dev, (double)inode));
129
130         /*
131          * If we have no record of any currently open oplocks,
132          * it's not an error, as a close command may have
133          * just been issued on the file that was oplocked.
134          * Just return success in this case.
135          */
136
137         if(global_oplocks_open != 0)
138         {
139           if(oplock_break(dev, inode, &tval) == False)
140           {
141             DEBUG(0,("process_local_message: oplock break failed - \
142 not returning udp message.\n"));
143             return False;
144           }
145         }
146         else
147         {
148           DEBUG(3,("process_local_message: oplock break requested with no outstanding \
149 oplocks. Returning success.\n"));
150         }
151
152         /* Send the message back after OR'ing in the 'REPLY' bit. */
153         SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY);
154   
155         bzero((char *)&toaddr,sizeof(toaddr));
156         toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
157         toaddr.sin_port = htons(from_port);
158         toaddr.sin_family = AF_INET;
159
160         if(sendto( sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0,
161                 (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0) 
162         {
163           DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n",
164                     remotepid, strerror(errno)));
165           return False;
166         }
167
168         DEBUG(5,("process_local_message: oplock break reply sent to \
169 pid %d, port %d, for file dev = %x, inode = %.0f\n",
170               remotepid, from_port, (unsigned int)dev, (double)inode));
171
172       }
173       break;
174     /* 
175      * Keep this as a debug case - eventually we can remove it.
176      */
177     case 0x8001:
178       DEBUG(0,("process_local_message: Received unsolicited break \
179 reply - dumping info.\n"));
180
181       if(msg_len != OPLOCK_BREAK_MSG_LEN)
182       {
183         DEBUG(0,("process_local_message: ubr: incorrect length for reply \
184 (was %d, should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN));
185         return False;
186       }
187
188       {
189         uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET);
190         SMB_DEV_T dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET);
191         /*
192          * Warning - beware of SMB_INO_T <> 4 bytes. !!
193          */
194 #ifdef LARGE_SMB_INO_T
195         SMB_INO_T inode_low = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
196         SMB_INO_T inode_high = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET + 4);
197         SMB_INO_T inode = inode_low | (inode_high << 32);
198 #else /* LARGE_SMB_INO_T */
199         SMB_INO_T inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET);
200 #endif /* LARGE_SMB_INO_T */
201
202         DEBUG(0,("process_local_message: unsolicited oplock break reply from \
203 pid %d, port %d, dev = %x, inode = %.0f\n", remotepid, from_port, (unsigned int)dev, (double)inode));
204
205        }
206        return False;
207
208     default:
209       DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n",
210                 (unsigned int)SVAL(msg_start,0)));
211       return False;
212   }
213   return True;
214 }
215
216 /****************************************************************************
217  Process an oplock break directly.
218 ****************************************************************************/
219 static BOOL oplock_break(SMB_DEV_T dev, SMB_INO_T inode, struct timeval *tval)
220 {
221   extern struct current_user current_user;
222   extern int Client;
223   char *inbuf = NULL;
224   char *outbuf = NULL;
225   files_struct *fsp = NULL;
226   time_t start_time;
227   BOOL shutdown_server = False;
228   connection_struct *saved_conn;
229   int saved_vuid;
230   pstring saved_dir; 
231
232   if( DEBUGLVL( 3 ) )
233     {
234     dbgtext( "oplock_break: called for dev = %x, inode = %.0f.\n", (unsigned int)dev, (double)inode );
235     dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
236     }
237
238   /* We need to search the file open table for the
239      entry containing this dev and inode, and ensure
240      we have an oplock on it. */
241   fsp = file_find_dit(dev, inode, tval);
242
243   if(fsp == NULL)
244   {
245     /* The file could have been closed in the meantime - return success. */
246     if( DEBUGLVL( 0 ) )
247       {
248       dbgtext( "oplock_break: cannot find open file with " );
249       dbgtext( "dev = %x, inode = %.0f ", (unsigned int)dev, (double)inode);
250       dbgtext( "allowing break to succeed.\n" );
251       }
252     return True;
253   }
254
255   /* Ensure we have an oplock on the file */
256
257   /* There is a potential race condition in that an oplock could
258      have been broken due to another udp request, and yet there are
259      still oplock break messages being sent in the udp message
260      queue for this file. So return true if we don't have an oplock,
261      as we may have just freed it.
262    */
263
264   if(!fsp->granted_oplock)
265   {
266     if( DEBUGLVL( 0 ) )
267       {
268       dbgtext( "oplock_break: file %s ", fsp->fsp_name );
269       dbgtext( "(dev = %x, inode = %.0f) has no oplock.\n", (unsigned int)dev, (double)inode );
270       dbgtext( "Allowing break to succeed regardless.\n" );
271       }
272     return True;
273   }
274
275   /* mark the oplock break as sent - we don't want to send twice! */
276   if (fsp->sent_oplock_break)
277   {
278     if( DEBUGLVL( 0 ) )
279       {
280       dbgtext( "oplock_break: ERROR: oplock_break already sent for " );
281       dbgtext( "file %s ", fsp->fsp_name);
282       dbgtext( "(dev = %x, inode = %.0f)\n", (unsigned int)dev, (double)inode );
283       }
284
285     /* We have to fail the open here as we cannot send another oplock break on
286        this file whilst we are awaiting a response from the client - neither
287        can we allow another open to succeed while we are waiting for the
288        client.
289      */
290     return False;
291   }
292
293   /* Now comes the horrid part. We must send an oplock break to the client,
294      and then process incoming messages until we get a close or oplock release.
295      At this point we know we need a new inbuf/outbuf buffer pair.
296      We cannot use these staticaly as we may recurse into here due to
297      messages crossing on the wire.
298    */
299
300   if((inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
301   {
302     DEBUG(0,("oplock_break: malloc fail for input buffer.\n"));
303     return False;
304   }
305
306   if((outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN))==NULL)
307   {
308     DEBUG(0,("oplock_break: malloc fail for output buffer.\n"));
309     free(inbuf);
310     inbuf = NULL;
311     return False;
312   }
313
314   /* Prepare the SMBlockingX message. */
315   bzero(outbuf,smb_size);
316   set_message(outbuf,8,0,True);
317
318   SCVAL(outbuf,smb_com,SMBlockingX);
319   SSVAL(outbuf,smb_tid,fsp->conn->cnum);
320   SSVAL(outbuf,smb_pid,0xFFFF);
321   SSVAL(outbuf,smb_uid,0);
322   SSVAL(outbuf,smb_mid,0xFFFF);
323   SCVAL(outbuf,smb_vwv0,0xFF);
324   SSVAL(outbuf,smb_vwv2,fsp->fnum);
325   SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
326   /* Change this when we have level II oplocks. */
327   SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE);
328  
329   send_smb(Client, outbuf);
330
331   /* Remember we just sent an oplock break on this file. */
332   fsp->sent_oplock_break = True;
333
334   /* We need this in case a readraw crosses on the wire. */
335   global_oplock_break = True;
336  
337   /* Process incoming messages. */
338
339   /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT
340      seconds we should just die.... */
341
342   start_time = time(NULL);
343
344   /*
345    * Save the information we need to re-become the
346    * user, then unbecome the user whilst we're doing this.
347    */
348   saved_conn = fsp->conn;
349   saved_vuid = current_user.vuid;
350   GetWd(saved_dir);
351   unbecome_user();
352   /* Save the chain fnum. */
353   file_chain_save();
354
355   while(OPEN_FSP(fsp) && fsp->granted_oplock)
356   {
357     if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False)
358     {
359       /*
360        * Die if we got an error.
361        */
362
363       if (smb_read_error == READ_EOF)
364         DEBUG( 0, ( "oplock_break: end of file from client\n" ) );
365  
366       if (smb_read_error == READ_ERROR)
367         DEBUG( 0, ("oplock_break: receive_smb error (%s)\n", strerror(errno)) );
368
369       if (smb_read_error == READ_TIMEOUT)
370         DEBUG( 0, ( "oplock_break: receive_smb timed out after %d seconds.\n",
371                      OPLOCK_BREAK_TIMEOUT ) );
372
373       DEBUGADD( 0, ( "oplock_break failed for file %s ", fsp->fsp_name ) );
374       DEBUGADD( 0, ( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode));
375
376       shutdown_server = True;
377       break;
378     }
379
380     /*
381      * There are certain SMB requests that we shouldn't allow
382      * to recurse. opens, renames and deletes are the obvious
383      * ones. This is handled in the switch_message() function.
384      * If global_oplock_break is set they will push the packet onto
385      * the pending smb queue and return -1 (no reply).
386      * JRA.
387      */
388
389     process_smb(inbuf, outbuf);
390
391     /*
392      * Die if we go over the time limit.
393      */
394
395     if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT)
396     {
397       if( DEBUGLVL( 0 ) )
398         {
399         dbgtext( "oplock_break: no break received from client " );
400         dbgtext( "within %d seconds.\n", OPLOCK_BREAK_TIMEOUT );
401         dbgtext( "oplock_break failed for file %s ", fsp->fsp_name );
402         dbgtext( "(dev = %x, inode = %.0f).\n", (unsigned int)dev, (double)inode );
403
404         }
405       shutdown_server = True;
406       break;
407     }
408   }
409
410   /*
411    * Go back to being the user who requested the oplock
412    * break.
413    */
414   if(!become_user(saved_conn, saved_vuid))
415   {
416     DEBUG( 0, ( "oplock_break: unable to re-become user!" ) );
417     DEBUGADD( 0, ( "Shutting down server\n" ) );
418     close_sockets();
419     close(oplock_sock);
420     exit_server("unable to re-become user");
421   }
422   /* Including the directory. */
423   ChDir(saved_dir);
424
425   /* Restore the chain fnum. */
426   file_chain_restore();
427
428   /* Free the buffers we've been using to recurse. */
429   free(inbuf);
430   free(outbuf);
431
432   /* We need this in case a readraw crossed on the wire. */
433   if(global_oplock_break)
434     global_oplock_break = False;
435
436   /*
437    * If the client did not respond we must die.
438    */
439
440   if(shutdown_server)
441   {
442     DEBUG( 0, ( "oplock_break: client failure in break - " ) );
443     DEBUGADD( 0, ( "shutting down this smbd.\n" ) );
444     close_sockets();
445     close(oplock_sock);
446     exit_server("oplock break failure");
447   }
448
449   if(OPEN_FSP(fsp))
450   {
451     /* The lockingX reply will have removed the oplock flag 
452        from the sharemode. */
453     /* Paranoia.... */
454     fsp->granted_oplock = False;
455     fsp->sent_oplock_break = False;
456     global_oplocks_open--;
457   }
458
459   /* Santity check - remove this later. JRA */
460   if(global_oplocks_open < 0)
461   {
462     DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n",
463               global_oplocks_open));
464     exit_server("oplock_break: global_oplocks_open < 0");
465   }
466
467   if( DEBUGLVL( 3 ) )
468     {
469     dbgtext( "oplock_break: returning success for " );
470     dbgtext( "dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
471     dbgtext( "Current global_oplocks_open = %d\n", global_oplocks_open );
472     }
473
474   return True;
475 }
476
477 /****************************************************************************
478 Send an oplock break message to another smbd process. If the oplock is held 
479 by the local smbd then call the oplock break function directly.
480 ****************************************************************************/
481
482 BOOL request_oplock_break(share_mode_entry *share_entry, 
483                           SMB_DEV_T dev, SMB_INO_T inode)
484 {
485   char op_break_msg[OPLOCK_BREAK_MSG_LEN];
486   struct sockaddr_in addr_out;
487   int pid = getpid();
488   time_t start_time;
489   int time_left;
490
491   if(pid == share_entry->pid)
492   {
493     /* We are breaking our own oplock, make sure it's us. */
494     if(share_entry->op_port != oplock_port)
495     {
496       DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \
497 should be %d\n", pid, share_entry->op_port, oplock_port));
498       return False;
499     }
500
501     DEBUG(5,("request_oplock_break: breaking our own oplock\n"));
502
503     /* Call oplock break direct. */
504     return oplock_break(dev, inode, &share_entry->time);
505   }
506
507   /* We need to send a OPLOCK_BREAK_CMD message to the
508      port in the share mode entry. */
509
510   SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD);
511   SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid);
512   SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec);
513   SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec);
514   SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev);
515   /*
516    * WARNING - beware of SMB_INO_T <> 4 bytes.
517    */
518 #ifdef LARGE_SMB_INO_T
519   SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,(inode & 0xFFFFFFFFL));
520   SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET+4,((inode >> 32) & 0xFFFFFFFFL));
521 #else /* LARGE_SMB_INO_T */
522   SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode);
523 #endif /* LARGE_SMB_INO_T */
524
525   /* set the address and port */
526   bzero((char *)&addr_out,sizeof(addr_out));
527   addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
528   addr_out.sin_port = htons( share_entry->op_port );
529   addr_out.sin_family = AF_INET;
530    
531   if( DEBUGLVL( 3 ) )
532     {
533     dbgtext( "request_oplock_break: sending a oplock break message to " );
534     dbgtext( "pid %d on port %d ", share_entry->pid, share_entry->op_port );
535     dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
536
537     }
538
539   if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0,
540          (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0)
541   {
542     if( DEBUGLVL( 0 ) )
543       {
544       dbgtext( "request_oplock_break: failed when sending a oplock " );
545       dbgtext( "break message to pid %d ", share_entry->pid );
546       dbgtext( "on port %d ", share_entry->op_port );
547       dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
548       dbgtext( "Error was %s\n", strerror(errno) );
549       }
550     return False;
551   }
552
553   /*
554    * Now we must await the oplock broken message coming back
555    * from the target smbd process. Timeout if it fails to
556    * return in (OPLOCK_BREAK_TIMEOUT + OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR) seconds.
557    * While we get messages that aren't ours, loop.
558    */
559
560   start_time = time(NULL);
561   time_left = OPLOCK_BREAK_TIMEOUT+OPLOCK_BREAK_TIMEOUT_FUDGEFACTOR;
562
563   while(time_left >= 0)
564   {
565     char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN];
566     int32 reply_msg_len;
567     uint16 reply_from_port;
568     char *reply_msg_start;
569
570     if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply),
571                time_left ? time_left * 1000 : 1) == False)
572     {
573       if(smb_read_error == READ_TIMEOUT)
574       {
575         if( DEBUGLVL( 0 ) )
576           {
577           dbgtext( "request_oplock_break: no response received to oplock " );
578           dbgtext( "break request to pid %d ", share_entry->pid );
579           dbgtext( "on port %d ", share_entry->op_port );
580           dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
581
582           }
583         /*
584          * This is a hack to make handling of failing clients more robust.
585          * If a oplock break response message is not received in the timeout
586          * period we may assume that the smbd servicing that client holding
587          * the oplock has died and the client changes were lost anyway, so
588          * we should continue to try and open the file.
589          */
590         break;
591       }
592       else
593         if( DEBUGLVL( 0 ) )
594           {
595           dbgtext( "request_oplock_break: error in response received " );
596           dbgtext( "to oplock break request to pid %d ", share_entry->pid );
597           dbgtext( "on port %d ", share_entry->op_port );
598           dbgtext( "for dev = %x, inode = %.0f\n", (unsigned int)dev, (double)inode );
599           dbgtext( "Error was (%s).\n", strerror(errno) );
600           }
601       return False;
602     }
603
604     reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET);
605     reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET);
606
607     reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN];
608
609     if(reply_msg_len != OPLOCK_BREAK_MSG_LEN)
610     {
611       /* Ignore it. */
612       DEBUG( 0, ( "request_oplock_break: invalid message length received." ) );
613       DEBUGADD( 0, ( "  Ignoring.\n" ) );
614       continue;
615     }
616
617     /*
618      * Test to see if this is the reply we are awaiting.
619      */
620
621     if((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) &&
622        (reply_from_port == share_entry->op_port) && 
623        (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET], 
624                &op_break_msg[OPLOCK_BREAK_PID_OFFSET],
625                OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) == 0))
626     {
627       /*
628        * This is the reply we've been waiting for.
629        */
630       break;
631     }
632     else
633     {
634       /*
635        * This is another message - probably a break request.
636        * Process it to prevent potential deadlock.
637        * Note that the code in switch_message() prevents
638        * us from recursing into here as any SMB requests
639        * we might process that would cause another oplock
640        * break request to be made will be queued.
641        * JRA.
642        */
643
644       process_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply));
645     }
646
647     time_left -= (time(NULL) - start_time);
648   }
649
650   DEBUG(3,("request_oplock_break: broke oplock.\n"));
651
652   return True;
653 }
654
655
656 /****************************************************************************
657   Attempt to break an oplock on a file (if oplocked).
658   Returns True if the file was closed as a result of
659   the oplock break, False otherwise.
660   Used as a last ditch attempt to free a space in the 
661   file table when we have run out.
662 ****************************************************************************/
663 BOOL attempt_close_oplocked_file(files_struct *fsp)
664 {
665
666   DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fsp->fsp_name));
667
668   if (fsp->open && fsp->granted_oplock && !fsp->sent_oplock_break) {
669
670     /* Try and break the oplock. */
671     file_fd_struct *fd_ptr = fsp->fd_ptr;
672     if(oplock_break( fd_ptr->dev, fd_ptr->inode, &fsp->open_time)) {
673       if(!fsp->open) /* Did the oplock break close the file ? */
674         return True;
675     }
676   }
677
678   return False;
679 }
680