r13192: Fix up alignment issues when printing share mode
[samba.git] / source / smbd / oplock.c
1 /* 
2    Unix SMB/CIFS implementation.
3    oplock processing
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Jeremy Allison 1998 - 2001
6    Copyright (C) Volker Lendecke 2005
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24
25 /* Current number of oplocks we have outstanding. */
26 static int32 exclusive_oplocks_open = 0;
27 static int32 level_II_oplocks_open = 0;
28 BOOL global_client_failed_oplock_break = False;
29
30 extern struct timeval smb_last_time;
31 extern uint32 global_client_caps;
32 extern int smb_read_error;
33
34 static struct kernel_oplocks *koplocks;
35
36 /****************************************************************************
37  Get the number of current exclusive oplocks.
38 ****************************************************************************/
39
40 int32 get_number_of_exclusive_open_oplocks(void)
41 {
42   return exclusive_oplocks_open;
43 }
44
45 /****************************************************************************
46  Return True if an oplock message is pending.
47 ****************************************************************************/
48
49 BOOL oplock_message_waiting(fd_set *fds)
50 {
51         if (koplocks && koplocks->msg_waiting(fds)) {
52                 return True;
53         }
54
55         return False;
56 }
57
58 /****************************************************************************
59  Read an oplock break message from either the oplock UDP fd or the
60  kernel (if kernel oplocks are supported).
61
62  If timeout is zero then *fds contains the file descriptors that
63  are ready to be read and acted upon. If timeout is non-zero then
64  *fds contains the file descriptors to be selected on for read.
65  The timeout is in milliseconds
66
67 ****************************************************************************/
68
69 void process_kernel_oplocks(void)
70 {
71         fd_set fds;
72
73         FD_ZERO(&fds);
74         smb_read_error = 0;
75
76         /*
77          * We need to check for kernel oplocks before going into the select
78          * here, as the EINTR generated by the linux kernel oplock may have
79          * already been eaten. JRA.
80          */
81
82         if (!koplocks) {
83                 return;
84         }
85
86         while (koplocks->msg_waiting(&fds)) { 
87                 files_struct *fsp;
88                 char msg[MSG_SMB_KERNEL_BREAK_SIZE];
89
90                 fsp = koplocks->receive_message(&fds);
91
92                 if (fsp == NULL) {
93                         DEBUG(3, ("Kernel oplock message announced, but none "
94                                   "received\n"));
95                         return;
96                 }
97
98                 /* Put the kernel break info into the message. */
99                 SDEV_T_VAL(msg,0,fsp->dev);
100                 SINO_T_VAL(msg,8,fsp->inode);
101                 SIVAL(msg,16,fsp->file_id);
102
103                 /* Don't need to be root here as we're only ever
104                    sending to ourselves. */
105
106                 message_send_pid(pid_to_procid(sys_getpid()),
107                                  MSG_SMB_KERNEL_BREAK,
108                                  &msg, MSG_SMB_KERNEL_BREAK_SIZE, True);
109         }
110 }
111
112 /****************************************************************************
113  Attempt to set an oplock on a file. Always succeeds if kernel oplocks are
114  disabled (just sets flags). Returns True if oplock set.
115 ****************************************************************************/
116
117 BOOL set_file_oplock(files_struct *fsp, int oplock_type)
118 {
119         if (koplocks && !koplocks->set_oplock(fsp, oplock_type)) {
120                 return False;
121         }
122
123         fsp->oplock_type = oplock_type;
124         fsp->sent_oplock_break = NO_BREAK_SENT;
125         if (oplock_type == LEVEL_II_OPLOCK) {
126                 level_II_oplocks_open++;
127         } else {
128                 exclusive_oplocks_open++;
129         }
130
131         DEBUG(5,("set_file_oplock: granted oplock on file %s, dev = %x, inode = %.0f, file_id = %lu, \
132 tv_sec = %x, tv_usec = %x\n",
133                  fsp->fsp_name, (unsigned int)fsp->dev, (double)fsp->inode, fsp->file_id,
134                  (int)fsp->open_time.tv_sec, (int)fsp->open_time.tv_usec ));
135
136         return True;
137 }
138
139 /****************************************************************************
140  Attempt to release an oplock on a file. Decrements oplock count.
141 ****************************************************************************/
142
143 void release_file_oplock(files_struct *fsp)
144 {
145         if ((fsp->oplock_type != NO_OPLOCK) &&
146             (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK) &&
147             koplocks) {
148                 koplocks->release_oplock(fsp);
149         }
150
151         if (fsp->oplock_type == LEVEL_II_OPLOCK) {
152                 level_II_oplocks_open--;
153         } else if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
154                 exclusive_oplocks_open--;
155         }
156
157         SMB_ASSERT(exclusive_oplocks_open>=0);
158         SMB_ASSERT(level_II_oplocks_open>=0);
159         
160         fsp->oplock_type = NO_OPLOCK;
161         fsp->sent_oplock_break = NO_BREAK_SENT;
162         
163         flush_write_cache(fsp, OPLOCK_RELEASE_FLUSH);
164 }
165
166 /****************************************************************************
167  Attempt to downgrade an oplock on a file. Doesn't decrement oplock count.
168 ****************************************************************************/
169
170 static void downgrade_file_oplock(files_struct *fsp)
171 {
172         if (koplocks) {
173                 koplocks->release_oplock(fsp);
174         }
175         fsp->oplock_type = LEVEL_II_OPLOCK;
176         exclusive_oplocks_open--;
177         level_II_oplocks_open++;
178         fsp->sent_oplock_break = NO_BREAK_SENT;
179 }
180
181 /****************************************************************************
182  Remove a file oplock. Copes with level II and exclusive.
183  Locks then unlocks the share mode lock. Client can decide to go directly
184  to none even if a "break-to-level II" was sent.
185 ****************************************************************************/
186
187 BOOL remove_oplock(files_struct *fsp)
188 {
189         SMB_DEV_T dev = fsp->dev;
190         SMB_INO_T inode = fsp->inode;
191         BOOL ret;
192         struct share_mode_lock *lck;
193
194         /* Remove the oplock flag from the sharemode. */
195         lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
196         if (lck == NULL) {
197                 DEBUG(0,("remove_oplock: failed to lock share entry for "
198                          "file %s\n", fsp->fsp_name ));
199                 return False;
200         }
201         ret = remove_share_oplock(lck, fsp);
202         if (!ret) {
203                 DEBUG(0,("remove_oplock: failed to remove share oplock for "
204                          "file %s fnum %d, dev = %x, inode = %.0f\n",
205                          fsp->fsp_name, fsp->fnum, (unsigned int)dev,
206                          (double)inode));
207         }
208         release_file_oplock(fsp);
209         talloc_free(lck);
210         return ret;
211 }
212
213 /*
214  * Deal with a reply when a break-to-level II was sent.
215  */
216 BOOL downgrade_oplock(files_struct *fsp)
217 {
218         SMB_DEV_T dev = fsp->dev;
219         SMB_INO_T inode = fsp->inode;
220         BOOL ret;
221         struct share_mode_lock *lck;
222
223         lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
224         if (lck == NULL) {
225                 DEBUG(0,("downgrade_oplock: failed to lock share entry for "
226                          "file %s\n", fsp->fsp_name ));
227                 return False;
228         }
229         ret = downgrade_share_oplock(lck, fsp);
230         if (!ret) {
231                 DEBUG(0,("downgrade_oplock: failed to downgrade share oplock "
232                          "for file %s fnum %d, dev = %x, inode = %.0f\n",
233                          fsp->fsp_name, fsp->fnum, (unsigned int)dev,
234                          (double)inode));
235         }
236
237         downgrade_file_oplock(fsp);
238         talloc_free(lck);
239         return ret;
240 }
241
242 /****************************************************************************
243  Setup the listening set of file descriptors for an oplock break
244  message either from the UDP socket or from the kernel. Returns the maximum
245  fd used.
246 ****************************************************************************/
247
248 int setup_oplock_select_set( fd_set *fds)
249 {
250         int maxfd = 0;
251
252         if (koplocks && koplocks->notification_fd != -1) {
253                 FD_SET(koplocks->notification_fd, fds);
254                 maxfd = MAX(maxfd, koplocks->notification_fd);
255         }
256
257         return maxfd;
258 }
259
260 /****************************************************************************
261  Set up an oplock break message.
262 ****************************************************************************/
263
264 static char *new_break_smb_message(TALLOC_CTX *mem_ctx,
265                                    files_struct *fsp, uint8 cmd)
266 {
267         char *result = TALLOC_ARRAY(mem_ctx, char, smb_size + 8*2 + 0);
268
269         if (result == NULL) {
270                 DEBUG(0, ("talloc failed\n"));
271                 return NULL;
272         }
273
274         memset(result,'\0',smb_size);
275         set_message(result,8,0,True);
276         SCVAL(result,smb_com,SMBlockingX);
277         SSVAL(result,smb_tid,fsp->conn->cnum);
278         SSVAL(result,smb_pid,0xFFFF);
279         SSVAL(result,smb_uid,0);
280         SSVAL(result,smb_mid,0xFFFF);
281         SCVAL(result,smb_vwv0,0xFF);
282         SSVAL(result,smb_vwv2,fsp->fnum);
283         SCVAL(result,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
284         SCVAL(result,smb_vwv3+1,cmd);
285         return result;
286 }
287
288 /****************************************************************************
289  Function to do the waiting before sending a local break.
290 ****************************************************************************/
291
292 static void wait_before_sending_break(void)
293 {
294         struct timeval cur_tv;
295         long wait_left = (long)lp_oplock_break_wait_time();
296
297         if (wait_left == 0) {
298                 return;
299         }
300
301         GetTimeOfDay(&cur_tv);
302
303         wait_left -= ((cur_tv.tv_sec - smb_last_time.tv_sec)*1000) +
304                 ((cur_tv.tv_usec - smb_last_time.tv_usec)/1000);
305
306         if(wait_left > 0) {
307                 wait_left = MIN(wait_left, 1000);
308                 sys_usleep(wait_left * 1000);
309         }
310 }
311
312 /****************************************************************************
313  Ensure that we have a valid oplock.
314 ****************************************************************************/
315
316 static files_struct *initial_break_processing(SMB_DEV_T dev, SMB_INO_T inode, unsigned long file_id)
317 {
318         files_struct *fsp = NULL;
319
320         if( DEBUGLVL( 3 ) ) {
321                 dbgtext( "initial_break_processing: called for dev = 0x%x, inode = %.0f file_id = %lu\n",
322                         (unsigned int)dev, (double)inode, file_id);
323                 dbgtext( "Current oplocks_open (exclusive = %d, levelII = %d)\n",
324                         exclusive_oplocks_open, level_II_oplocks_open );
325         }
326
327         /*
328          * We need to search the file open table for the
329          * entry containing this dev and inode, and ensure
330          * we have an oplock on it.
331          */
332
333         fsp = file_find_dif(dev, inode, file_id);
334
335         if(fsp == NULL) {
336                 /* The file could have been closed in the meantime - return success. */
337                 if( DEBUGLVL( 3 ) ) {
338                         dbgtext( "initial_break_processing: cannot find open file with " );
339                         dbgtext( "dev = 0x%x, inode = %.0f file_id = %lu", (unsigned int)dev,
340                                 (double)inode, file_id);
341                         dbgtext( "allowing break to succeed.\n" );
342                 }
343                 return NULL;
344         }
345
346         /* Ensure we have an oplock on the file */
347
348         /*
349          * There is a potential race condition in that an oplock could
350          * have been broken due to another udp request, and yet there are
351          * still oplock break messages being sent in the udp message
352          * queue for this file. So return true if we don't have an oplock,
353          * as we may have just freed it.
354          */
355
356         if(fsp->oplock_type == NO_OPLOCK) {
357                 if( DEBUGLVL( 3 ) ) {
358                         dbgtext( "initial_break_processing: file %s ", fsp->fsp_name );
359                         dbgtext( "(dev = %x, inode = %.0f, file_id = %lu) has no oplock.\n",
360                                 (unsigned int)dev, (double)inode, fsp->file_id );
361                         dbgtext( "Allowing break to succeed regardless.\n" );
362                 }
363                 return NULL;
364         }
365
366         return fsp;
367 }
368
369 static void oplock_timeout_handler(struct timed_event *te,
370                                    const struct timeval *now,
371                                    void *private_data)
372 {
373         files_struct *fsp = private_data;
374
375         DEBUG(0, ("Oplock break failed -- replying anyway\n"));
376         global_client_failed_oplock_break = True;
377         remove_oplock(fsp);
378         reply_to_oplock_break_requests(fsp);
379 }
380
381 static void process_oplock_break_message(int msg_type, struct process_id src,
382                                          void *buf, size_t len)
383 {
384         struct share_mode_entry msg;
385         files_struct *fsp;
386         char *break_msg;
387         BOOL break_to_level2 = False;
388         BOOL sign_state;
389
390         if (buf == NULL) {
391                 DEBUG(0, ("Got NULL buffer\n"));
392                 return;
393         }
394
395         if (len != MSG_SMB_SHARE_MODE_ENTRY_SIZE) {
396                 DEBUG(0, ("Got invalid msg len %d\n", (int)len));
397                 return;
398         }
399
400         /* De-linearize incoming message. */
401         message_to_share_mode_entry(&msg, buf);
402
403         DEBUG(10, ("Got oplock break message from pid %d: 0x%x/%.0f/%d\n",
404                    (int)procid_to_pid(&src), (unsigned int)msg.dev, (double)msg.inode,
405                    (int)msg.share_file_id));
406
407         fsp = initial_break_processing(msg.dev, msg.inode,
408                                        msg.share_file_id);
409
410         if (fsp == NULL) {
411                 /* We hit race here. Break messages are sent, and before we
412                  * get to process this message, we have closed the file. Reply
413                  * with 'ok, oplock broken' */
414                 DEBUG(3, ("Did not find fsp\n"));
415                 become_root();
416
417                 /* We just send the same message back. */
418                 message_send_pid(src, MSG_SMB_BREAK_RESPONSE,
419                                  buf, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True);
420
421                 unbecome_root();
422                 return;
423         }
424
425         if (fsp->sent_oplock_break != NO_BREAK_SENT) {
426                 /* Remember we have to inform the requesting PID when the
427                  * client replies */
428                 msg.pid = src;
429                 ADD_TO_ARRAY(NULL, struct share_mode_entry, msg,
430                              &fsp->pending_break_messages,
431                              &fsp->num_pending_break_messages);
432                 return;
433         }
434
435         if (EXCLUSIVE_OPLOCK_TYPE(msg.op_type) &&
436             !EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
437                 DEBUG(3, ("Already downgraded oplock on 0x%x/%.0f: %s\n",
438                           (unsigned int)fsp->dev, (double)fsp->inode,
439                           fsp->fsp_name));
440                 become_root();
441
442                 /* We just send the same message back. */
443                 message_send_pid(src, MSG_SMB_BREAK_RESPONSE,
444                                  buf, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True);
445
446                 unbecome_root();
447                 return;
448         }
449
450         if ((msg_type == MSG_SMB_BREAK_REQUEST) &&
451             (global_client_caps & CAP_LEVEL_II_OPLOCKS) && 
452             !koplocks && /* NOTE: we force levelII off for kernel oplocks -
453                           * this will change when it is supported */
454             lp_level2_oplocks(SNUM(fsp->conn))) {
455                 break_to_level2 = True;
456         }
457
458         break_msg = new_break_smb_message(NULL, fsp, break_to_level2 ?
459                                           OPLOCKLEVEL_II : OPLOCKLEVEL_NONE);
460         if (break_msg == NULL) {
461                 exit_server("Could not talloc break_msg\n");
462         }
463
464         /* Need to wait before sending a break message to a file of our own */
465         if (procid_to_pid(&src) == sys_getpid()) {
466                 wait_before_sending_break();
467         }
468
469         /* Save the server smb signing state. */
470         sign_state = srv_oplock_set_signing(False);
471
472         show_msg(break_msg);
473         if (!send_smb(smbd_server_fd(), break_msg)) {
474                 exit_server("oplock_break: send_smb failed.");
475         }
476
477         /* Restore the sign state to what it was. */
478         srv_oplock_set_signing(sign_state);
479
480         talloc_free(break_msg);
481
482         if (msg_type == MSG_SMB_BREAK_REQUEST) {
483                 fsp->sent_oplock_break = break_to_level2 ?
484                         LEVEL_II_BREAK_SENT:BREAK_TO_NONE_SENT;
485         } else {
486                 /* Async level2 request, don't send a reply */
487                 fsp->sent_oplock_break = ASYNC_LEVEL_II_BREAK_SENT;
488         }
489         msg.pid = src;
490         ADD_TO_ARRAY(NULL, struct share_mode_entry, msg,
491                      &fsp->pending_break_messages,
492                      &fsp->num_pending_break_messages);
493
494         if (fsp->oplock_timeout != NULL) {
495                 DEBUG(0, ("Logic problem -- have an oplock event hanging "
496                           "around\n"));
497         }
498
499         fsp->oplock_timeout =
500                 add_timed_event(NULL,
501                                 timeval_current_ofs(OPLOCK_BREAK_TIMEOUT, 0),
502                                 "oplock_timeout_handler",
503                                 oplock_timeout_handler, fsp);
504
505         if (fsp->oplock_timeout == NULL) {
506                 DEBUG(0, ("Could not add oplock timeout handler\n"));
507         }
508 }
509
510 static void process_kernel_oplock_break(int msg_type, struct process_id src,
511                                         void *buf, size_t len)
512 {
513         SMB_DEV_T dev;
514         SMB_INO_T inode;
515         unsigned long file_id;
516         files_struct *fsp;
517         char *break_msg;
518         BOOL sign_state;
519
520         if (buf == NULL) {
521                 DEBUG(0, ("Got NULL buffer\n"));
522                 return;
523         }
524
525         if (len != MSG_SMB_KERNEL_BREAK_SIZE) {
526                 DEBUG(0, ("Got invalid msg len %d\n", (int)len));
527                 return;
528         }
529
530         /* Pull the data from the message. */
531         dev = DEV_T_VAL(buf, 0);
532         inode = INO_T_VAL(buf, 8);
533         file_id = (unsigned long)IVAL(buf, 16);
534
535         DEBUG(10, ("Got kernel oplock break message from pid %d: 0x%x/%.0f/%u\n",
536                    (int)procid_to_pid(&src), (unsigned int)dev, (double)inode,
537                    (unsigned int)file_id));
538
539         fsp = initial_break_processing(dev, inode, file_id);
540
541         if (fsp == NULL) {
542                 DEBUG(3, ("Got a kernel oplock break message for a file "
543                           "I don't know about\n"));
544                 return;
545         }
546
547         if (fsp->sent_oplock_break != NO_BREAK_SENT) {
548                 /* This is ok, kernel oplocks come in completely async */
549                 DEBUG(3, ("Got a kernel oplock request while waiting for a "
550                           "break reply\n"));
551                 return;
552         }
553
554         break_msg = new_break_smb_message(NULL, fsp, OPLOCKLEVEL_NONE);
555         if (break_msg == NULL) {
556                 exit_server("Could not talloc break_msg\n");
557         }
558
559         /* Save the server smb signing state. */
560         sign_state = srv_oplock_set_signing(False);
561
562         show_msg(break_msg);
563         if (!send_smb(smbd_server_fd(), break_msg)) {
564                 exit_server("oplock_break: send_smb failed.");
565         }
566
567         /* Restore the sign state to what it was. */
568         srv_oplock_set_signing(sign_state);
569
570         talloc_free(break_msg);
571
572         fsp->sent_oplock_break = BREAK_TO_NONE_SENT;
573 }
574
575 void reply_to_oplock_break_requests(files_struct *fsp)
576 {
577         int i;
578
579         become_root();
580         for (i=0; i<fsp->num_pending_break_messages; i++) {
581                 struct share_mode_entry *e = &fsp->pending_break_messages[i];
582                 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
583
584                 share_mode_entry_to_message(msg, e);
585
586                 message_send_pid(e->pid, MSG_SMB_BREAK_RESPONSE,
587                                  msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True);
588         }
589         unbecome_root();
590
591         SAFE_FREE(fsp->pending_break_messages);
592         fsp->num_pending_break_messages = 0;
593         if (fsp->oplock_timeout != NULL) {
594                 talloc_free(fsp->oplock_timeout);
595                 fsp->oplock_timeout = NULL;
596         }
597         return;
598 }
599
600 static void process_oplock_break_response(int msg_type, struct process_id src,
601                                           void *buf, size_t len)
602 {
603         struct share_mode_entry msg;
604
605         if (buf == NULL) {
606                 DEBUG(0, ("Got NULL buffer\n"));
607                 return;
608         }
609
610         if (len != MSG_SMB_SHARE_MODE_ENTRY_SIZE) {
611                 DEBUG(0, ("Got invalid msg len %u\n", (unsigned int)len));
612                 return;
613         }
614
615         /* De-linearize incoming message. */
616         message_to_share_mode_entry(&msg, buf);
617
618         DEBUG(10, ("Got oplock break response from pid %d: 0x%x/%.0f/%u mid %u\n",
619                    (int)procid_to_pid(&src), (unsigned int)msg.dev, (double)msg.inode,
620                    (unsigned int)msg.share_file_id, (unsigned int)msg.op_mid));
621
622         /* Here's the hack from open.c, store the mid in the 'port' field */
623         schedule_deferred_open_smb_message(msg.op_mid);
624 }
625
626 static void process_open_retry_message(int msg_type, struct process_id src,
627                                        void *buf, size_t len)
628 {
629         struct share_mode_entry msg;
630         
631         if (buf == NULL) {
632                 DEBUG(0, ("Got NULL buffer\n"));
633                 return;
634         }
635
636         if (len != MSG_SMB_SHARE_MODE_ENTRY_SIZE) {
637                 DEBUG(0, ("Got invalid msg len %d\n", (int)len));
638                 return;
639         }
640
641         /* De-linearize incoming message. */
642         message_to_share_mode_entry(&msg, buf);
643
644         DEBUG(10, ("Got open retry msg from pid %d: 0x%x/%.0f mid %u\n",
645                    (int)procid_to_pid(&src), (unsigned int)msg.dev, (double)msg.inode,
646                    (unsigned int)msg.op_mid));
647
648         schedule_deferred_open_smb_message(msg.op_mid);
649 }
650
651 /****************************************************************************
652  This function is called on any file modification or lock request. If a file
653  is level 2 oplocked then it must tell all other level 2 holders to break to
654  none.
655 ****************************************************************************/
656
657 void release_level_2_oplocks_on_change(files_struct *fsp)
658 {
659         int i;
660         struct share_mode_lock *lck;
661
662         /*
663          * If this file is level II oplocked then we need
664          * to grab the shared memory lock and inform all
665          * other files with a level II lock that they need
666          * to flush their read caches. We keep the lock over
667          * the shared memory area whilst doing this.
668          */
669
670         if (!LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
671                 return;
672
673         lck = get_share_mode_lock(NULL, fsp->dev, fsp->inode, NULL, NULL);
674         if (lck == NULL) {
675                 DEBUG(0,("release_level_2_oplocks_on_change: failed to lock "
676                          "share mode entry for file %s.\n", fsp->fsp_name ));
677         }
678
679         DEBUG(10,("release_level_2_oplocks_on_change: num_share_modes = %d\n", 
680                   lck->num_share_modes ));
681
682         if (fsp->oplock_type == FAKE_LEVEL_II_OPLOCK) {
683                 /* See if someone else has already downgraded us, then we
684                    don't have to do anything */
685                 for (i=0; i<lck->num_share_modes; i++) {
686                         struct share_mode_entry *e = &lck->share_modes[i];
687
688                         if (!is_valid_share_mode_entry(e)) {
689                                 continue;
690                         }
691
692                         if ((e->op_type == NO_OPLOCK) &&
693                             (e->share_file_id == fsp->file_id) &&
694                             (e->dev == fsp->dev) &&
695                             (e->inode == fsp->inode) &&
696                             (procid_is_me(&e->pid))) {
697                                 /* We're done */
698                                 fsp->oplock_type = NO_OPLOCK;
699                                 talloc_free(lck);
700                                 return;
701                         }
702                 }
703         }
704
705         for(i = 0; i < lck->num_share_modes; i++) {
706                 struct share_mode_entry *share_entry = &lck->share_modes[i];
707                 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
708
709                 if (!is_valid_share_mode_entry(share_entry)) {
710                         continue;
711                 }
712
713                 /*
714                  * As there could have been multiple writes waiting at the
715                  * lock_share_entry gate we may not be the first to
716                  * enter. Hence the state of the op_types in the share mode
717                  * entries may be partly NO_OPLOCK and partly LEVEL_II
718                  * oplock. It will do no harm to re-send break messages to
719                  * those smbd's that are still waiting their turn to remove
720                  * their LEVEL_II state, and also no harm to ignore existing
721                  * NO_OPLOCK states. JRA.
722                  */
723
724                 DEBUG(10,("release_level_2_oplocks_on_change: "
725                           "share_entry[%i]->op_type == %d\n",
726                           i, share_entry->op_type ));
727
728                 if ((share_entry->op_type == NO_OPLOCK) ||
729                     (share_entry->op_type == FAKE_LEVEL_II_OPLOCK)) {
730                         continue;
731                 }
732
733                 /* Paranoia .... */
734                 if (EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) {
735                         DEBUG(0,("release_level_2_oplocks_on_change: PANIC. "
736                                  "share mode entry %d is an exlusive "
737                                  "oplock !\n", i ));
738                         talloc_free(lck);
739                         abort();
740                 }
741
742                 share_mode_entry_to_message(msg, share_entry);
743
744                 become_root();
745                 message_send_pid(share_entry->pid, MSG_SMB_ASYNC_LEVEL2_BREAK,
746                                  msg, MSG_SMB_SHARE_MODE_ENTRY_SIZE, True);
747                 unbecome_root();
748         }
749
750         remove_all_share_oplocks(lck, fsp);
751         talloc_free(lck);
752 }
753
754 /****************************************************************************
755  Linearize a share mode entry struct to an internal oplock break message.
756 ****************************************************************************/
757
758 void share_mode_entry_to_message(char *msg, struct share_mode_entry *e)
759 {
760         SIVAL(msg,0,(uint32)e->pid.pid);
761         SSVAL(msg,4,e->op_mid);
762         SSVAL(msg,6,e->op_type);
763         SIVAL(msg,8,e->access_mask);
764         SIVAL(msg,12,e->share_access);
765         SIVAL(msg,16,e->private_options);
766         SIVAL(msg,20,(uint32)e->time.tv_sec);
767         SIVAL(msg,24,(uint32)e->time.tv_usec);
768         SDEV_T_VAL(msg,28,e->dev);
769         SINO_T_VAL(msg,36,e->inode);
770         SIVAL(msg,44,e->share_file_id);
771 }
772
773 /****************************************************************************
774  De-linearize an internal oplock break message to a share mode entry struct.
775 ****************************************************************************/
776
777 void message_to_share_mode_entry(struct share_mode_entry *e, char *msg)
778 {
779         e->pid.pid = (pid_t)IVAL(msg,0);
780         e->op_mid = SVAL(msg,4);
781         e->op_type = SVAL(msg,6);
782         e->access_mask = IVAL(msg,8);
783         e->share_access = IVAL(msg,12);
784         e->private_options = IVAL(msg,16);
785         e->time.tv_sec = (time_t)IVAL(msg,20);
786         e->time.tv_usec = (int)IVAL(msg,24);
787         e->dev = DEV_T_VAL(msg,28);
788         e->inode = INO_T_VAL(msg,36);
789         e->share_file_id = (unsigned long)IVAL(msg,44);
790 }
791
792 /****************************************************************************
793  Setup oplocks for this process.
794 ****************************************************************************/
795
796 BOOL init_oplocks(void)
797 {
798         DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n"));
799
800         message_register(MSG_SMB_BREAK_REQUEST,
801                          process_oplock_break_message);
802         message_register(MSG_SMB_ASYNC_LEVEL2_BREAK,
803                          process_oplock_break_message);
804         message_register(MSG_SMB_BREAK_RESPONSE,
805                          process_oplock_break_response);
806         message_register(MSG_SMB_KERNEL_BREAK,
807                          process_kernel_oplock_break);
808         message_register(MSG_SMB_OPEN_RETRY,
809                          process_open_retry_message);
810
811         if (lp_kernel_oplocks()) {
812 #if HAVE_KERNEL_OPLOCKS_IRIX
813                 koplocks = irix_init_kernel_oplocks();
814 #elif HAVE_KERNEL_OPLOCKS_LINUX
815                 koplocks = linux_init_kernel_oplocks();
816 #endif
817         }
818
819         return True;
820 }