s3 oplocks: Add capabilites flags field to the kernel_oplocks struct
[samba.git] / source3 / 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 3 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, see <http://www.gnu.org/licenses/>.
20 */
21
22 #define DBGC_CLASS DBGC_LOCKING
23 #include "includes.h"
24 #include "smbd/globals.h"
25
26 /****************************************************************************
27  Get the number of current exclusive oplocks.
28 ****************************************************************************/
29
30 int32 get_number_of_exclusive_open_oplocks(void)
31 {
32   return exclusive_oplocks_open;
33 }
34
35 /*
36  * helper function used by the kernel oplock backends to post the break message
37  */
38 void break_kernel_oplock(struct messaging_context *msg_ctx, files_struct *fsp)
39 {
40         uint8_t msg[MSG_SMB_KERNEL_BREAK_SIZE];
41
42         /* Put the kernel break info into the message. */
43         push_file_id_16((char *)msg, &fsp->file_id);
44         SIVAL(msg,16,fsp->fh->gen_id);
45
46         /* Don't need to be root here as we're only ever
47            sending to ourselves. */
48
49         messaging_send_buf(msg_ctx, procid_self(),
50                            MSG_SMB_KERNEL_BREAK,
51                            msg, MSG_SMB_KERNEL_BREAK_SIZE);
52 }
53
54 /****************************************************************************
55  Attempt to set an oplock on a file. Always succeeds if kernel oplocks are
56  disabled (just sets flags). Returns True if oplock set.
57 ****************************************************************************/
58
59 bool set_file_oplock(files_struct *fsp, int oplock_type)
60 {
61         if ((fsp->oplock_type != NO_OPLOCK) &&
62             (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK) &&
63             koplocks &&
64             !koplocks->ops->set_oplock(koplocks, fsp, oplock_type)) {
65                 return False;
66         }
67
68         fsp->oplock_type = oplock_type;
69         fsp->sent_oplock_break = NO_BREAK_SENT;
70         if (oplock_type == LEVEL_II_OPLOCK) {
71                 level_II_oplocks_open++;
72         } else if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
73                 exclusive_oplocks_open++;
74         }
75
76         DEBUG(5,("set_file_oplock: granted oplock on file %s, %s/%lu, "
77                     "tv_sec = %x, tv_usec = %x\n",
78                  fsp->fsp_name, file_id_string_tos(&fsp->file_id),
79                  fsp->fh->gen_id, (int)fsp->open_time.tv_sec,
80                  (int)fsp->open_time.tv_usec ));
81
82         return True;
83 }
84
85 /****************************************************************************
86  Attempt to release an oplock on a file. Decrements oplock count.
87 ****************************************************************************/
88
89 void release_file_oplock(files_struct *fsp)
90 {
91         if ((fsp->oplock_type != NO_OPLOCK) &&
92             (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK) &&
93             koplocks) {
94                 koplocks->ops->release_oplock(koplocks, fsp, NO_OPLOCK);
95         }
96
97         if (fsp->oplock_type == LEVEL_II_OPLOCK) {
98                 level_II_oplocks_open--;
99         } else if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
100                 exclusive_oplocks_open--;
101         }
102
103         SMB_ASSERT(exclusive_oplocks_open>=0);
104         SMB_ASSERT(level_II_oplocks_open>=0);
105
106         if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
107                 /* This doesn't matter for close. */
108                 fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
109         } else {
110                 fsp->oplock_type = NO_OPLOCK;
111         }
112         fsp->sent_oplock_break = NO_BREAK_SENT;
113
114         flush_write_cache(fsp, OPLOCK_RELEASE_FLUSH);
115
116         TALLOC_FREE(fsp->oplock_timeout);
117 }
118
119 /****************************************************************************
120  Attempt to downgrade an oplock on a file. Doesn't decrement oplock count.
121 ****************************************************************************/
122
123 static void downgrade_file_oplock(files_struct *fsp)
124 {
125         if (koplocks) {
126                 koplocks->ops->release_oplock(koplocks, fsp, LEVEL_II_OPLOCK);
127         }
128         fsp->oplock_type = LEVEL_II_OPLOCK;
129         exclusive_oplocks_open--;
130         level_II_oplocks_open++;
131         fsp->sent_oplock_break = NO_BREAK_SENT;
132 }
133
134 /****************************************************************************
135  Remove a file oplock. Copes with level II and exclusive.
136  Locks then unlocks the share mode lock. Client can decide to go directly
137  to none even if a "break-to-level II" was sent.
138 ****************************************************************************/
139
140 bool remove_oplock(files_struct *fsp)
141 {
142         bool ret;
143         struct share_mode_lock *lck;
144
145         /* Remove the oplock flag from the sharemode. */
146         lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
147                                   NULL);
148         if (lck == NULL) {
149                 DEBUG(0,("remove_oplock: failed to lock share entry for "
150                          "file %s\n", fsp->fsp_name ));
151                 return False;
152         }
153         ret = remove_share_oplock(lck, fsp);
154         if (!ret) {
155                 DEBUG(0,("remove_oplock: failed to remove share oplock for "
156                          "file %s fnum %d, %s\n",
157                          fsp->fsp_name, fsp->fnum, file_id_string_tos(&fsp->file_id)));
158         }
159         release_file_oplock(fsp);
160         TALLOC_FREE(lck);
161         return ret;
162 }
163
164 /*
165  * Deal with a reply when a break-to-level II was sent.
166  */
167 bool downgrade_oplock(files_struct *fsp)
168 {
169         bool ret;
170         struct share_mode_lock *lck;
171
172         lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
173                                   NULL);
174         if (lck == NULL) {
175                 DEBUG(0,("downgrade_oplock: failed to lock share entry for "
176                          "file %s\n", fsp->fsp_name ));
177                 return False;
178         }
179         ret = downgrade_share_oplock(lck, fsp);
180         if (!ret) {
181                 DEBUG(0,("downgrade_oplock: failed to downgrade share oplock "
182                          "for file %s fnum %d, file_id %s\n",
183                          fsp->fsp_name, fsp->fnum, file_id_string_tos(&fsp->file_id)));
184         }
185
186         downgrade_file_oplock(fsp);
187         TALLOC_FREE(lck);
188         return ret;
189 }
190
191 /*
192  * Some kernel oplock implementations handle the notification themselves.
193  */
194 bool should_notify_deferred_opens()
195 {
196         return !(koplocks &&
197                 (koplocks->flags & KOPLOCKS_DEFERRED_OPEN_NOTIFICATION));
198 }
199
200 /****************************************************************************
201  Set up an oplock break message.
202 ****************************************************************************/
203
204 static char *new_break_smb_message(TALLOC_CTX *mem_ctx,
205                                    files_struct *fsp, uint8 cmd)
206 {
207         char *result = TALLOC_ARRAY(mem_ctx, char, smb_size + 8*2 + 0);
208
209         if (result == NULL) {
210                 DEBUG(0, ("talloc failed\n"));
211                 return NULL;
212         }
213
214         memset(result,'\0',smb_size);
215         srv_set_message(result,8,0,true);
216         SCVAL(result,smb_com,SMBlockingX);
217         SSVAL(result,smb_tid,fsp->conn->cnum);
218         SSVAL(result,smb_pid,0xFFFF);
219         SSVAL(result,smb_uid,0);
220         SSVAL(result,smb_mid,0xFFFF);
221         SCVAL(result,smb_vwv0,0xFF);
222         SSVAL(result,smb_vwv2,fsp->fnum);
223         SCVAL(result,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE);
224         SCVAL(result,smb_vwv3+1,cmd);
225         return result;
226 }
227
228 /****************************************************************************
229  Function to do the waiting before sending a local break.
230 ****************************************************************************/
231
232 static void wait_before_sending_break(void)
233 {
234         long wait_time = (long)lp_oplock_break_wait_time();
235
236         if (wait_time) {
237                 smb_msleep(wait_time);
238         }
239 }
240
241 /****************************************************************************
242  Ensure that we have a valid oplock.
243 ****************************************************************************/
244
245 static files_struct *initial_break_processing(struct file_id id, unsigned long file_id)
246 {
247         files_struct *fsp = NULL;
248
249         if( DEBUGLVL( 3 ) ) {
250                 dbgtext( "initial_break_processing: called for %s/%u\n",
251                          file_id_string_tos(&id), (int)file_id);
252                 dbgtext( "Current oplocks_open (exclusive = %d, levelII = %d)\n",
253                         exclusive_oplocks_open, level_II_oplocks_open );
254         }
255
256         /*
257          * We need to search the file open table for the
258          * entry containing this dev and inode, and ensure
259          * we have an oplock on it.
260          */
261
262         fsp = file_find_dif(id, file_id);
263
264         if(fsp == NULL) {
265                 /* The file could have been closed in the meantime - return success. */
266                 if( DEBUGLVL( 3 ) ) {
267                         dbgtext( "initial_break_processing: cannot find open file with " );
268                         dbgtext( "file_id %s gen_id = %lu", file_id_string_tos(&id), file_id);
269                         dbgtext( "allowing break to succeed.\n" );
270                 }
271                 return NULL;
272         }
273
274         /* Ensure we have an oplock on the file */
275
276         /*
277          * There is a potential race condition in that an oplock could
278          * have been broken due to another udp request, and yet there are
279          * still oplock break messages being sent in the udp message
280          * queue for this file. So return true if we don't have an oplock,
281          * as we may have just freed it.
282          */
283
284         if(fsp->oplock_type == NO_OPLOCK) {
285                 if( DEBUGLVL( 3 ) ) {
286                         dbgtext( "initial_break_processing: file %s ", fsp->fsp_name );
287                         dbgtext( "(file_id = %s gen_id = %lu) has no oplock.\n",
288                                  file_id_string_tos(&id), fsp->fh->gen_id );
289                         dbgtext( "Allowing break to succeed regardless.\n" );
290                 }
291                 return NULL;
292         }
293
294         return fsp;
295 }
296
297 static void oplock_timeout_handler(struct event_context *ctx,
298                                    struct timed_event *te,
299                                    struct timeval now,
300                                    void *private_data)
301 {
302         files_struct *fsp = (files_struct *)private_data;
303
304         /* Remove the timed event handler. */
305         TALLOC_FREE(fsp->oplock_timeout);
306         DEBUG(0, ("Oplock break failed for file %s -- replying anyway\n", fsp->fsp_name));
307         global_client_failed_oplock_break = True;
308         remove_oplock(fsp);
309         reply_to_oplock_break_requests(fsp);
310 }
311
312 /*******************************************************************
313  Add a timeout handler waiting for the client reply.
314 *******************************************************************/
315
316 static void add_oplock_timeout_handler(files_struct *fsp)
317 {
318         /*
319          * If kernel oplocks already notifies smbds when an oplock break times
320          * out, just return.
321          */
322         if (koplocks &&
323             (koplocks->flags & KOPLOCKS_TIMEOUT_NOTIFICATION)) {
324                 return;
325         }
326
327         if (fsp->oplock_timeout != NULL) {
328                 DEBUG(0, ("Logic problem -- have an oplock event hanging "
329                           "around\n"));
330         }
331
332         fsp->oplock_timeout =
333                 event_add_timed(smbd_event_context(), NULL,
334                                 timeval_current_ofs(OPLOCK_BREAK_TIMEOUT, 0),
335                                 oplock_timeout_handler, fsp);
336
337         if (fsp->oplock_timeout == NULL) {
338                 DEBUG(0, ("Could not add oplock timeout handler\n"));
339         }
340 }
341
342 /*******************************************************************
343  This handles the case of a write triggering a break to none
344  message on a level2 oplock.
345  When we get this message we may be in any of three states :
346  NO_OPLOCK, LEVEL_II, FAKE_LEVEL2. We only send a message to
347  the client for LEVEL2.
348 *******************************************************************/
349
350 void process_oplock_async_level2_break_message(struct messaging_context *msg_ctx,
351                                                       void *private_data,
352                                                       uint32_t msg_type,
353                                                       struct server_id src,
354                                                       DATA_BLOB *data)
355 {
356         struct share_mode_entry msg;
357         files_struct *fsp;
358         char *break_msg;
359         bool sign_state;
360
361         if (data->data == NULL) {
362                 DEBUG(0, ("Got NULL buffer\n"));
363                 return;
364         }
365
366         if (data->length != MSG_SMB_SHARE_MODE_ENTRY_SIZE) {
367                 DEBUG(0, ("Got invalid msg len %d\n", (int)data->length));
368                 return;
369         }
370
371         /* De-linearize incoming message. */
372         message_to_share_mode_entry(&msg, (char *)data->data);
373
374         DEBUG(10, ("Got oplock async level 2 break message from pid %d: %s/%lu\n",
375                    (int)procid_to_pid(&src), file_id_string_tos(&msg.id), msg.share_file_id));
376
377         fsp = initial_break_processing(msg.id, msg.share_file_id);
378
379         if (fsp == NULL) {
380                 /* We hit a race here. Break messages are sent, and before we
381                  * get to process this message, we have closed the file. 
382                  * No need to reply as this is an async message. */
383                 DEBUG(3, ("process_oplock_async_level2_break_message: Did not find fsp, ignoring\n"));
384                 return;
385         }
386
387         if (fsp->oplock_type == NO_OPLOCK) {
388                 /* We already got a "break to none" message and we've handled it.
389                  * just ignore. */
390                 DEBUG(3, ("process_oplock_async_level2_break_message: already broken to none, ignoring.\n"));
391                 return;
392         }
393
394         if (fsp->oplock_type == FAKE_LEVEL_II_OPLOCK) {
395                 /* Don't tell the client, just downgrade. */
396                 DEBUG(3, ("process_oplock_async_level2_break_message: downgrading fake level 2 oplock.\n"));
397                 remove_oplock(fsp);
398                 return;
399         }
400
401         /* Ensure we're really at level2 state. */
402         SMB_ASSERT(fsp->oplock_type == LEVEL_II_OPLOCK);
403
404         DEBUG(10,("process_oplock_async_level2_break_message: sending break to "
405                 "none message for fid %d, file %s\n",
406                 fsp->fnum,
407                 fsp->fsp_name));
408
409         /* Now send a break to none message to our client. */
410
411         break_msg = new_break_smb_message(NULL, fsp, OPLOCKLEVEL_NONE);
412         if (break_msg == NULL) {
413                 exit_server("Could not talloc break_msg\n");
414         }
415
416         /* Need to wait before sending a break message if we sent ourselves this message. */
417         if (procid_to_pid(&src) == sys_getpid()) {
418                 wait_before_sending_break();
419         }
420
421         /* Save the server smb signing state. */
422         sign_state = srv_oplock_set_signing(False);
423
424         show_msg(break_msg);
425         if (!srv_send_smb(smbd_server_fd(),
426                         break_msg,
427                         IS_CONN_ENCRYPTED(fsp->conn),
428                         NULL)) {
429                 exit_server_cleanly("oplock_break: srv_send_smb failed.");
430         }
431
432         /* Restore the sign state to what it was. */
433         srv_oplock_set_signing(sign_state);
434
435         TALLOC_FREE(break_msg);
436
437         /* Async level2 request, don't send a reply, just remove the oplock. */
438         remove_oplock(fsp);
439 }
440
441 /*******************************************************************
442  This handles the generic oplock break message from another smbd.
443 *******************************************************************/
444
445 static void process_oplock_break_message(struct messaging_context *msg_ctx,
446                                          void *private_data,
447                                          uint32_t msg_type,
448                                          struct server_id src,
449                                          DATA_BLOB *data)
450 {
451         struct share_mode_entry msg;
452         files_struct *fsp;
453         char *break_msg;
454         bool break_to_level2 = False;
455         bool sign_state;
456
457         if (data->data == NULL) {
458                 DEBUG(0, ("Got NULL buffer\n"));
459                 return;
460         }
461
462         if (data->length != MSG_SMB_SHARE_MODE_ENTRY_SIZE) {
463                 DEBUG(0, ("Got invalid msg len %d\n", (int)data->length));
464                 return;
465         }
466
467         /* De-linearize incoming message. */
468         message_to_share_mode_entry(&msg, (char *)data->data);
469
470         DEBUG(10, ("Got oplock break message from pid %d: %s/%lu\n",
471                    (int)procid_to_pid(&src), file_id_string_tos(&msg.id), msg.share_file_id));
472
473         fsp = initial_break_processing(msg.id, msg.share_file_id);
474
475         if (fsp == NULL) {
476                 /* a We hit race here. Break messages are sent, and before we
477                  * get to process this message, we have closed the file. Reply
478                  * with 'ok, oplock broken' */
479                 DEBUG(3, ("Did not find fsp\n"));
480
481                 /* We just send the same message back. */
482                 messaging_send_buf(msg_ctx, src, MSG_SMB_BREAK_RESPONSE,
483                                    (uint8 *)data->data,
484                                    MSG_SMB_SHARE_MODE_ENTRY_SIZE);
485                 return;
486         }
487
488         if (fsp->sent_oplock_break != NO_BREAK_SENT) {
489                 /* Remember we have to inform the requesting PID when the
490                  * client replies */
491                 msg.pid = src;
492                 ADD_TO_ARRAY(NULL, struct share_mode_entry, msg,
493                              &fsp->pending_break_messages,
494                              &fsp->num_pending_break_messages);
495                 return;
496         }
497
498         if (EXCLUSIVE_OPLOCK_TYPE(msg.op_type) &&
499             !EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
500                 DEBUG(3, ("Already downgraded oplock on %s: %s\n",
501                           file_id_string_tos(&fsp->file_id),
502                           fsp->fsp_name));
503                 /* We just send the same message back. */
504                 messaging_send_buf(msg_ctx, src, MSG_SMB_BREAK_RESPONSE,
505                                    (uint8 *)data->data,
506                                    MSG_SMB_SHARE_MODE_ENTRY_SIZE);
507                 return;
508         }
509
510         if ((global_client_caps & CAP_LEVEL_II_OPLOCKS) && 
511             !(msg.op_type & FORCE_OPLOCK_BREAK_TO_NONE) &&
512             !(koplocks && !(koplocks->flags & KOPLOCKS_LEVEL2_SUPPORTED)) &&
513             lp_level2_oplocks(SNUM(fsp->conn))) {
514                 break_to_level2 = True;
515         }
516
517         break_msg = new_break_smb_message(NULL, fsp, break_to_level2 ?
518                                           OPLOCKLEVEL_II : OPLOCKLEVEL_NONE);
519         if (break_msg == NULL) {
520                 exit_server("Could not talloc break_msg\n");
521         }
522
523         /* Need to wait before sending a break message if we sent ourselves this message. */
524         if (procid_to_pid(&src) == sys_getpid()) {
525                 wait_before_sending_break();
526         }
527
528         /* Save the server smb signing state. */
529         sign_state = srv_oplock_set_signing(False);
530
531         show_msg(break_msg);
532         if (!srv_send_smb(smbd_server_fd(),
533                         break_msg,
534                         IS_CONN_ENCRYPTED(fsp->conn),
535                         NULL)) {
536                 exit_server_cleanly("oplock_break: srv_send_smb failed.");
537         }
538
539         /* Restore the sign state to what it was. */
540         srv_oplock_set_signing(sign_state);
541
542         TALLOC_FREE(break_msg);
543
544         fsp->sent_oplock_break = break_to_level2 ? LEVEL_II_BREAK_SENT:BREAK_TO_NONE_SENT;
545
546         msg.pid = src;
547         ADD_TO_ARRAY(NULL, struct share_mode_entry, msg,
548                      &fsp->pending_break_messages,
549                      &fsp->num_pending_break_messages);
550
551         add_oplock_timeout_handler(fsp);
552 }
553
554 /*******************************************************************
555  This handles the kernel oplock break message.
556 *******************************************************************/
557
558 static void process_kernel_oplock_break(struct messaging_context *msg_ctx,
559                                         void *private_data,
560                                         uint32_t msg_type,
561                                         struct server_id src,
562                                         DATA_BLOB *data)
563 {
564         struct file_id id;
565         unsigned long file_id;
566         files_struct *fsp;
567         char *break_msg;
568         bool sign_state;
569
570         if (data->data == NULL) {
571                 DEBUG(0, ("Got NULL buffer\n"));
572                 return;
573         }
574
575         if (data->length != MSG_SMB_KERNEL_BREAK_SIZE) {
576                 DEBUG(0, ("Got invalid msg len %d\n", (int)data->length));
577                 return;
578         }
579
580         /* Pull the data from the message. */
581         pull_file_id_16((char *)data->data, &id);
582         file_id = (unsigned long)IVAL(data->data, 16);
583
584         DEBUG(10, ("Got kernel oplock break message from pid %d: %s/%u\n",
585                    (int)procid_to_pid(&src), file_id_string_tos(&id),
586                    (unsigned int)file_id));
587
588         fsp = initial_break_processing(id, file_id);
589
590         if (fsp == NULL) {
591                 DEBUG(3, ("Got a kernel oplock break message for a file "
592                           "I don't know about\n"));
593                 return;
594         }
595
596         if (fsp->sent_oplock_break != NO_BREAK_SENT) {
597                 /* This is ok, kernel oplocks come in completely async */
598                 DEBUG(3, ("Got a kernel oplock request while waiting for a "
599                           "break reply\n"));
600                 return;
601         }
602
603         break_msg = new_break_smb_message(NULL, fsp, OPLOCKLEVEL_NONE);
604         if (break_msg == NULL) {
605                 exit_server("Could not talloc break_msg\n");
606         }
607
608         /* Save the server smb signing state. */
609         sign_state = srv_oplock_set_signing(False);
610
611         show_msg(break_msg);
612         if (!srv_send_smb(smbd_server_fd(),
613                         break_msg,
614                         IS_CONN_ENCRYPTED(fsp->conn),
615                         NULL)) {
616                 exit_server_cleanly("oplock_break: srv_send_smb failed.");
617         }
618
619         /* Restore the sign state to what it was. */
620         srv_oplock_set_signing(sign_state);
621
622         TALLOC_FREE(break_msg);
623
624         fsp->sent_oplock_break = BREAK_TO_NONE_SENT;
625
626         add_oplock_timeout_handler(fsp);
627 }
628
629 void reply_to_oplock_break_requests(files_struct *fsp)
630 {
631         int i;
632
633         /*
634          * If kernel oplocks already notifies smbds when oplocks are
635          * broken/removed, just return.
636          */
637         if (koplocks &&
638             (koplocks->flags & KOPLOCKS_OPLOCK_BROKEN_NOTIFICATION)) {
639                 return;
640         }
641
642         for (i=0; i<fsp->num_pending_break_messages; i++) {
643                 struct share_mode_entry *e = &fsp->pending_break_messages[i];
644                 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
645
646                 share_mode_entry_to_message(msg, e);
647
648                 messaging_send_buf(smbd_messaging_context(), e->pid,
649                                    MSG_SMB_BREAK_RESPONSE,
650                                    (uint8 *)msg,
651                                    MSG_SMB_SHARE_MODE_ENTRY_SIZE);
652         }
653
654         SAFE_FREE(fsp->pending_break_messages);
655         fsp->num_pending_break_messages = 0;
656         if (fsp->oplock_timeout != NULL) {
657                 /* Remove the timed event handler. */
658                 TALLOC_FREE(fsp->oplock_timeout);
659                 fsp->oplock_timeout = NULL;
660         }
661         return;
662 }
663
664 static void process_oplock_break_response(struct messaging_context *msg_ctx,
665                                           void *private_data,
666                                           uint32_t msg_type,
667                                           struct server_id src,
668                                           DATA_BLOB *data)
669 {
670         struct share_mode_entry msg;
671
672         if (data->data == NULL) {
673                 DEBUG(0, ("Got NULL buffer\n"));
674                 return;
675         }
676
677         if (data->length != MSG_SMB_SHARE_MODE_ENTRY_SIZE) {
678                 DEBUG(0, ("Got invalid msg len %u\n",
679                           (unsigned int)data->length));
680                 return;
681         }
682
683         /* De-linearize incoming message. */
684         message_to_share_mode_entry(&msg, (char *)data->data);
685
686         DEBUG(10, ("Got oplock break response from pid %d: %s/%lu mid %u\n",
687                    (int)procid_to_pid(&src), file_id_string_tos(&msg.id), msg.share_file_id,
688                    (unsigned int)msg.op_mid));
689
690         /* Here's the hack from open.c, store the mid in the 'port' field */
691         schedule_deferred_open_smb_message(msg.op_mid);
692 }
693
694 static void process_open_retry_message(struct messaging_context *msg_ctx,
695                                        void *private_data,
696                                        uint32_t msg_type,
697                                        struct server_id src,
698                                        DATA_BLOB *data)
699 {
700         struct share_mode_entry msg;
701         
702         if (data->data == NULL) {
703                 DEBUG(0, ("Got NULL buffer\n"));
704                 return;
705         }
706
707         if (data->length != MSG_SMB_SHARE_MODE_ENTRY_SIZE) {
708                 DEBUG(0, ("Got invalid msg len %d\n", (int)data->length));
709                 return;
710         }
711
712         /* De-linearize incoming message. */
713         message_to_share_mode_entry(&msg, (char *)data->data);
714
715         DEBUG(10, ("Got open retry msg from pid %d: %s mid %u\n",
716                    (int)procid_to_pid(&src), file_id_string_tos(&msg.id),
717                    (unsigned int)msg.op_mid));
718
719         schedule_deferred_open_smb_message(msg.op_mid);
720 }
721
722 /****************************************************************************
723  This function is called on any file modification or lock request. If a file
724  is level 2 oplocked then it must tell all other level 2 holders to break to
725  none.
726 ****************************************************************************/
727
728 static void contend_level2_oplocks_begin_default(files_struct *fsp,
729                                               enum level2_contention_type type)
730 {
731         int i;
732         struct share_mode_lock *lck;
733
734         /*
735          * If this file is level II oplocked then we need
736          * to grab the shared memory lock and inform all
737          * other files with a level II lock that they need
738          * to flush their read caches. We keep the lock over
739          * the shared memory area whilst doing this.
740          */
741
742         if (!LEVEL_II_OPLOCK_TYPE(fsp->oplock_type))
743                 return;
744
745         lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
746                                   NULL);
747         if (lck == NULL) {
748                 DEBUG(0,("release_level_2_oplocks_on_change: failed to lock "
749                          "share mode entry for file %s.\n", fsp->fsp_name ));
750                 return;
751         }
752
753         DEBUG(10,("release_level_2_oplocks_on_change: num_share_modes = %d\n", 
754                   lck->num_share_modes ));
755
756         for(i = 0; i < lck->num_share_modes; i++) {
757                 struct share_mode_entry *share_entry = &lck->share_modes[i];
758                 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
759
760                 if (!is_valid_share_mode_entry(share_entry)) {
761                         continue;
762                 }
763
764                 /*
765                  * As there could have been multiple writes waiting at the
766                  * lock_share_entry gate we may not be the first to
767                  * enter. Hence the state of the op_types in the share mode
768                  * entries may be partly NO_OPLOCK and partly LEVEL_II or FAKE_LEVEL_II
769                  * oplock. It will do no harm to re-send break messages to
770                  * those smbd's that are still waiting their turn to remove
771                  * their LEVEL_II state, and also no harm to ignore existing
772                  * NO_OPLOCK states. JRA.
773                  */
774
775                 DEBUG(10,("release_level_2_oplocks_on_change: "
776                           "share_entry[%i]->op_type == %d\n",
777                           i, share_entry->op_type ));
778
779                 if (share_entry->op_type == NO_OPLOCK) {
780                         continue;
781                 }
782
783                 /* Paranoia .... */
784                 if (EXCLUSIVE_OPLOCK_TYPE(share_entry->op_type)) {
785                         DEBUG(0,("release_level_2_oplocks_on_change: PANIC. "
786                                  "share mode entry %d is an exlusive "
787                                  "oplock !\n", i ));
788                         TALLOC_FREE(lck);
789                         abort();
790                 }
791
792                 share_mode_entry_to_message(msg, share_entry);
793
794                 /*
795                  * Deal with a race condition when breaking level2
796                  * oplocks. Don't send all the messages and release
797                  * the lock, this allows someone else to come in and
798                  * get a level2 lock before any of the messages are
799                  * processed, and thus miss getting a break message.
800                  * Ensure at least one entry (the one we're breaking)
801                  * is processed immediately under the lock and becomes
802                  * set as NO_OPLOCK to stop any waiter getting a level2.
803                  * Bugid #5980.
804                  */
805
806                 if (procid_is_me(&share_entry->pid)) {
807                         DATA_BLOB blob = data_blob_const(msg,
808                                         MSG_SMB_SHARE_MODE_ENTRY_SIZE);
809                         process_oplock_async_level2_break_message(smbd_messaging_context(),
810                                                 NULL,
811                                                 MSG_SMB_ASYNC_LEVEL2_BREAK,
812                                                 share_entry->pid,
813                                                 &blob);
814                 } else {
815                         messaging_send_buf(smbd_messaging_context(),
816                                         share_entry->pid,
817                                         MSG_SMB_ASYNC_LEVEL2_BREAK,
818                                         (uint8 *)msg,
819                                         MSG_SMB_SHARE_MODE_ENTRY_SIZE);
820                 }
821         }
822
823         /* We let the message receivers handle removing the oplock state
824            in the share mode lock db. */
825
826         TALLOC_FREE(lck);
827 }
828
829 void contend_level2_oplocks_begin(files_struct *fsp,
830                                   enum level2_contention_type type)
831 {
832         if (koplocks && koplocks->ops->contend_level2_oplocks_begin) {
833                 koplocks->ops->contend_level2_oplocks_begin(fsp, type);
834                 return;
835         }
836
837         contend_level2_oplocks_begin_default(fsp, type);
838 }
839
840 void contend_level2_oplocks_end(files_struct *fsp,
841                                 enum level2_contention_type type)
842 {
843         /* Only kernel oplocks implement this so far */
844         if (koplocks && koplocks->ops->contend_level2_oplocks_end) {
845                 koplocks->ops->contend_level2_oplocks_end(fsp, type);
846         }
847 }
848
849 /****************************************************************************
850  Linearize a share mode entry struct to an internal oplock break message.
851 ****************************************************************************/
852
853 void share_mode_entry_to_message(char *msg, const struct share_mode_entry *e)
854 {
855         SIVAL(msg,0,(uint32)e->pid.pid);
856         SSVAL(msg,4,e->op_mid);
857         SSVAL(msg,6,e->op_type);
858         SIVAL(msg,8,e->access_mask);
859         SIVAL(msg,12,e->share_access);
860         SIVAL(msg,16,e->private_options);
861         SIVAL(msg,20,(uint32)e->time.tv_sec);
862         SIVAL(msg,24,(uint32)e->time.tv_usec);
863         push_file_id_16(msg+28, &e->id);
864         SIVAL(msg,44,e->share_file_id);
865         SIVAL(msg,48,e->uid);
866         SSVAL(msg,52,e->flags);
867 #ifdef CLUSTER_SUPPORT
868         SIVAL(msg,54,e->pid.vnn);
869 #endif
870 }
871
872 /****************************************************************************
873  De-linearize an internal oplock break message to a share mode entry struct.
874 ****************************************************************************/
875
876 void message_to_share_mode_entry(struct share_mode_entry *e, char *msg)
877 {
878         e->pid.pid = (pid_t)IVAL(msg,0);
879         e->op_mid = SVAL(msg,4);
880         e->op_type = SVAL(msg,6);
881         e->access_mask = IVAL(msg,8);
882         e->share_access = IVAL(msg,12);
883         e->private_options = IVAL(msg,16);
884         e->time.tv_sec = (time_t)IVAL(msg,20);
885         e->time.tv_usec = (int)IVAL(msg,24);
886         pull_file_id_16(msg+28, &e->id);
887         e->share_file_id = (unsigned long)IVAL(msg,44);
888         e->uid = (uint32)IVAL(msg,48);
889         e->flags = (uint16)SVAL(msg,52);
890 #ifdef CLUSTER_SUPPORT
891         e->pid.vnn = IVAL(msg,54);
892 #endif
893 }
894
895 /****************************************************************************
896  Setup oplocks for this process.
897 ****************************************************************************/
898
899 bool init_oplocks(struct messaging_context *msg_ctx)
900 {
901         DEBUG(3,("init_oplocks: initializing messages.\n"));
902
903         messaging_register(msg_ctx, NULL, MSG_SMB_BREAK_REQUEST,
904                            process_oplock_break_message);
905         messaging_register(msg_ctx, NULL, MSG_SMB_ASYNC_LEVEL2_BREAK,
906                            process_oplock_async_level2_break_message);
907         messaging_register(msg_ctx, NULL, MSG_SMB_BREAK_RESPONSE,
908                            process_oplock_break_response);
909         messaging_register(msg_ctx, NULL, MSG_SMB_KERNEL_BREAK,
910                            process_kernel_oplock_break);
911         messaging_register(msg_ctx, NULL, MSG_SMB_OPEN_RETRY,
912                            process_open_retry_message);
913
914         if (lp_kernel_oplocks()) {
915 #if HAVE_KERNEL_OPLOCKS_IRIX
916                 koplocks = irix_init_kernel_oplocks(talloc_autofree_context());
917 #elif HAVE_KERNEL_OPLOCKS_LINUX
918                 koplocks = linux_init_kernel_oplocks(talloc_autofree_context());
919 #endif
920         }
921
922         return True;
923 }