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