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