Revert "smbd: explain that/why we use the raw tevent_context for lease_timeout_handler()"
[garming/samba-autobuild/.git] / source3 / smbd / blocking.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Blocking Locking functions
4    Copyright (C) Jeremy Allison 1998-2003
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21 #include "smbd/smbd.h"
22 #include "smbd/globals.h"
23 #include "messages.h"
24
25 #undef DBGC_CLASS
26 #define DBGC_CLASS DBGC_LOCKING
27
28 static void received_unlock_msg(struct messaging_context *msg,
29                                 void *private_data,
30                                 uint32_t msg_type,
31                                 struct server_id server_id,
32                                 DATA_BLOB *data);
33
34 void brl_timeout_fn(struct tevent_context *event_ctx,
35                            struct tevent_timer *te,
36                            struct timeval now,
37                            void *private_data)
38 {
39         struct smbd_server_connection *sconn = talloc_get_type_abort(
40                 private_data, struct smbd_server_connection);
41
42         if (sconn->using_smb2) {
43                 SMB_ASSERT(sconn->smb2.locks.brl_timeout == te);
44                 TALLOC_FREE(sconn->smb2.locks.brl_timeout);
45         } else {
46                 SMB_ASSERT(sconn->smb1.locks.brl_timeout == te);
47                 TALLOC_FREE(sconn->smb1.locks.brl_timeout);
48         }
49
50         change_to_root_user();  /* TODO: Possibly run all timed events as
51                                  * root */
52
53         process_blocking_lock_queue(sconn);
54 }
55
56 /****************************************************************************
57  We need a version of timeval_min that treats zero timval as infinite.
58 ****************************************************************************/
59
60 struct timeval timeval_brl_min(const struct timeval *tv1,
61                                         const struct timeval *tv2)
62 {
63         if (timeval_is_zero(tv1)) {
64                 return *tv2;
65         }
66         if (timeval_is_zero(tv2)) {
67                 return *tv1;
68         }
69         return timeval_min(tv1, tv2);
70 }
71
72 /****************************************************************************
73  After a change to blocking_lock_queue, recalculate the timed_event for the
74  next processing.
75 ****************************************************************************/
76
77 static bool recalc_brl_timeout(struct smbd_server_connection *sconn)
78 {
79         struct blocking_lock_record *blr;
80         struct timeval next_timeout;
81         int max_brl_timeout = lp_parm_int(-1, "brl", "recalctime", 5);
82
83         TALLOC_FREE(sconn->smb1.locks.brl_timeout);
84
85         next_timeout = timeval_zero();
86
87         for (blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = blr->next) {
88                 if (timeval_is_zero(&blr->expire_time)) {
89                         /*
90                          * If we're blocked on pid 0xFFFFFFFFFFFFFFFFLL this is
91                          * a POSIX lock, so calculate a timeout of
92                          * 10 seconds into the future.
93                          */
94                         if (blr->blocking_smblctx == 0xFFFFFFFFFFFFFFFFLL) {
95                                 struct timeval psx_to = timeval_current_ofs(10, 0);
96                                 next_timeout = timeval_brl_min(&next_timeout, &psx_to);
97                         }
98
99                         continue;
100                 }
101
102                 next_timeout = timeval_brl_min(&next_timeout, &blr->expire_time);
103         }
104
105         if (timeval_is_zero(&next_timeout)) {
106                 DEBUG(10, ("Next timeout = Infinite.\n"));
107                 return True;
108         }
109
110         /*
111          to account for unclean shutdowns by clients we need a
112          maximum timeout that we use for checking pending locks. If
113          we have any pending locks at all, then check if the pending
114          lock can continue at least every brl:recalctime seconds
115          (default 5 seconds).
116
117          This saves us needing to do a message_send_all() in the
118          SIGCHLD handler in the parent daemon. That
119          message_send_all() caused O(n^2) work to be done when IP
120          failovers happened in clustered Samba, which could make the
121          entire system unusable for many minutes.
122         */
123
124         if (max_brl_timeout > 0) {
125                 struct timeval min_to = timeval_current_ofs(max_brl_timeout, 0);
126                 next_timeout = timeval_min(&next_timeout, &min_to);
127         }
128
129         if (DEBUGLVL(10)) {
130                 struct timeval cur, from_now;
131
132                 cur = timeval_current();
133                 from_now = timeval_until(&cur, &next_timeout);
134                 DEBUG(10, ("Next timeout = %d.%d seconds from now.\n",
135                     (int)from_now.tv_sec, (int)from_now.tv_usec));
136         }
137
138         sconn->smb1.locks.brl_timeout = tevent_add_timer(sconn->ev_ctx,
139                                                          NULL, next_timeout,
140                                                          brl_timeout_fn, sconn);
141         if (sconn->smb1.locks.brl_timeout == NULL) {
142                 return False;
143         }
144
145         return True;
146 }
147
148
149 /****************************************************************************
150  Function to push a blocking lock request onto the lock queue.
151 ****************************************************************************/
152
153 bool push_blocking_lock_request( struct byte_range_lock *br_lck,
154                 struct smb_request *req,
155                 files_struct *fsp,
156                 int lock_timeout,
157                 int lock_num,
158                 uint64_t smblctx,
159                 enum brl_type lock_type,
160                 enum brl_flavour lock_flav,
161                 uint64_t offset,
162                 uint64_t count,
163                 uint64_t blocking_smblctx)
164 {
165         struct smbd_server_connection *sconn = req->sconn;
166         struct blocking_lock_record *blr;
167         NTSTATUS status;
168
169         if (req->smb2req) {
170                 return push_blocking_lock_request_smb2(br_lck,
171                                 req,
172                                 fsp,
173                                 lock_timeout,
174                                 lock_num,
175                                 smblctx,
176                                 lock_type,
177                                 lock_flav,
178                                 offset,
179                                 count,
180                                 blocking_smblctx);
181         }
182
183         if(req_is_in_chain(req)) {
184                 DEBUG(0,("push_blocking_lock_request: cannot queue a chained request (currently).\n"));
185                 return False;
186         }
187
188         /*
189          * Now queue an entry on the blocking lock queue. We setup
190          * the expiration time here.
191          */
192
193         blr = talloc(NULL, struct blocking_lock_record);
194         if (blr == NULL) {
195                 DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" ));
196                 return False;
197         }
198
199         blr->next = NULL;
200         blr->prev = NULL;
201
202         blr->fsp = fsp;
203         if (lock_timeout == -1) {
204                 blr->expire_time.tv_sec = 0;
205                 blr->expire_time.tv_usec = 0; /* Never expire. */
206         } else {
207                 blr->expire_time = timeval_current_ofs_msec(lock_timeout);
208         }
209         blr->lock_num = lock_num;
210         blr->smblctx = smblctx;
211         blr->blocking_smblctx = blocking_smblctx;
212         blr->lock_flav = lock_flav;
213         blr->lock_type = lock_type;
214         blr->offset = offset;
215         blr->count = count;
216
217         /* Specific brl_lock() implementations can fill this in. */
218         blr->blr_private = NULL;
219
220         /* Add a pending lock record for this. */
221         status = brl_lock(req->sconn->msg_ctx,
222                         br_lck,
223                         smblctx,
224                         messaging_server_id(req->sconn->msg_ctx),
225                         offset,
226                         count,
227                         lock_type == READ_LOCK ? PENDING_READ_LOCK : PENDING_WRITE_LOCK,
228                         blr->lock_flav,
229                         True,
230                         NULL);
231
232         if (!NT_STATUS_IS_OK(status)) {
233                 DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n"));
234                 TALLOC_FREE(blr);
235                 return False;
236         }
237
238         SMB_PERFCOUNT_DEFER_OP(&req->pcd, &req->pcd);
239         blr->req = talloc_move(blr, &req);
240
241         DLIST_ADD_END(sconn->smb1.locks.blocking_lock_queue, blr);
242         recalc_brl_timeout(sconn);
243
244         /* Ensure we'll receive messages when this is unlocked. */
245         if (!sconn->smb1.locks.blocking_lock_unlock_state) {
246                 messaging_register(sconn->msg_ctx, sconn,
247                                    MSG_SMB_UNLOCK, received_unlock_msg);
248                 sconn->smb1.locks.blocking_lock_unlock_state = true;
249         }
250
251         DEBUG(3,("push_blocking_lock_request: lock request blocked with "
252                 "expiry time (%u sec. %u usec) (+%d msec) for %s, name = %s\n",
253                 (unsigned int)blr->expire_time.tv_sec,
254                 (unsigned int)blr->expire_time.tv_usec, lock_timeout,
255                 fsp_fnum_dbg(blr->fsp), fsp_str_dbg(blr->fsp)));
256
257         return True;
258 }
259
260 /****************************************************************************
261  Return a lockingX success SMB.
262 *****************************************************************************/
263
264 static void reply_lockingX_success(struct blocking_lock_record *blr)
265 {
266         struct smb_request *req = blr->req;
267
268         reply_outbuf(req, 2, 0);
269         SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */
270         SSVAL(req->outbuf, smb_vwv1, 0);    /* no andx offset */
271
272         /*
273          * As this message is a lockingX call we must handle
274          * any following chained message correctly.
275          * This is normally handled in construct_reply(),
276          * but as that calls switch_message, we can't use
277          * that here and must set up the chain info manually.
278          */
279
280         if (!srv_send_smb(req->xconn,
281                         (char *)req->outbuf,
282                         true, req->seqnum+1,
283                         IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
284                         &req->pcd)) {
285                 exit_server_cleanly("construct_reply: srv_send_smb failed.");
286         }
287
288         TALLOC_FREE(req->outbuf);
289 }
290
291 /****************************************************************************
292  Return a generic lock fail error blocking call.
293 *****************************************************************************/
294
295 static void generic_blocking_lock_error(struct blocking_lock_record *blr, NTSTATUS status)
296 {
297         /* whenever a timeout is given w2k maps LOCK_NOT_GRANTED to
298            FILE_LOCK_CONFLICT! (tridge) */
299         if (NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED)) {
300                 status = NT_STATUS_FILE_LOCK_CONFLICT;
301         }
302
303         if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
304                 /* Store the last lock error. */
305                 files_struct *fsp = blr->fsp;
306
307                 if (fsp) {
308                         fsp->last_lock_failure.context.smblctx = blr->smblctx;
309                         fsp->last_lock_failure.context.tid = fsp->conn->cnum;
310                         fsp->last_lock_failure.context.pid =
311                                 messaging_server_id(fsp->conn->sconn->msg_ctx);
312                         fsp->last_lock_failure.start = blr->offset;
313                         fsp->last_lock_failure.size = blr->count;
314                         fsp->last_lock_failure.fnum = fsp->fnum;
315                         fsp->last_lock_failure.lock_type = READ_LOCK; /* Don't care. */
316                         fsp->last_lock_failure.lock_flav = blr->lock_flav;
317                 }
318         }
319
320         reply_nterror(blr->req, status);
321         if (!srv_send_smb(blr->req->xconn, (char *)blr->req->outbuf,
322                           true, blr->req->seqnum+1,
323                           blr->req->encrypted, NULL)) {
324                 exit_server_cleanly("generic_blocking_lock_error: srv_send_smb failed.");
325         }
326         TALLOC_FREE(blr->req->outbuf);
327 }
328
329 /****************************************************************************
330  Return a lock fail error for a lockingX call. Undo all the locks we have
331  obtained first.
332 *****************************************************************************/
333
334 static void undo_locks_obtained(struct blocking_lock_record *blr)
335 {
336         files_struct *fsp = blr->fsp;
337         uint16_t num_ulocks = SVAL(blr->req->vwv+6, 0);
338         uint64_t count = (uint64_t)0, offset = (uint64_t) 0;
339         uint64_t smblctx;
340         unsigned char locktype = CVAL(blr->req->vwv+3, 0);
341         bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
342         uint8_t *data;
343         int i;
344
345         data = discard_const_p(uint8_t, blr->req->buf)
346                 + ((large_file_format ? 20 : 10)*num_ulocks);
347
348         /*
349          * Data now points at the beginning of the list
350          * of smb_lkrng structs.
351          */
352
353         /*
354          * Ensure we don't do a remove on the lock that just failed,
355          * as under POSIX rules, if we have a lock already there, we
356          * will delete it (and we shouldn't) .....
357          */
358
359         for(i = blr->lock_num - 1; i >= 0; i--) {
360
361                 smblctx = get_lock_pid( data, i, large_file_format);
362                 count = get_lock_count( data, i, large_file_format);
363                 offset = get_lock_offset( data, i, large_file_format);
364
365                 /*
366                  * We know err cannot be set as if it was the lock
367                  * request would never have been queued. JRA.
368                  */
369
370                 do_unlock(fsp->conn->sconn->msg_ctx,
371                         fsp,
372                         smblctx,
373                         count,
374                         offset,
375                         WINDOWS_LOCK);
376         }
377 }
378
379 /****************************************************************************
380  Return a lock fail error.
381 *****************************************************************************/
382
383 static void blocking_lock_reply_error(struct blocking_lock_record *blr, NTSTATUS status)
384 {
385         DEBUG(10, ("Replying with error=%s. BLR = %p\n", nt_errstr(status), blr));
386
387         switch(blr->req->cmd) {
388         case SMBlockingX:
389                 /*
390                  * This code can be called during the rundown of a
391                  * file after it was already closed. In that case,
392                  * blr->fsp==NULL and we do not need to undo any
393                  * locks, they are already gone.
394                  */
395                 if (blr->fsp != NULL) {
396                         undo_locks_obtained(blr);
397                 }
398                 generic_blocking_lock_error(blr, status);
399                 break;
400         case SMBtrans2:
401         case SMBtranss2:
402                 reply_nterror(blr->req, status);
403
404                 /*
405                  * construct_reply_common has done us the favor to pre-fill
406                  * the command field with SMBtranss2 which is wrong :-)
407                  */
408                 SCVAL(blr->req->outbuf,smb_com,SMBtrans2);
409
410                 if (!srv_send_smb(blr->req->xconn,
411                                   (char *)blr->req->outbuf,
412                                   true, blr->req->seqnum+1,
413                                   IS_CONN_ENCRYPTED(blr->fsp->conn),
414                                   NULL)) {
415                         exit_server_cleanly("blocking_lock_reply_error: "
416                                             "srv_send_smb failed.");
417                 }
418                 TALLOC_FREE(blr->req->outbuf);
419                 break;
420         default:
421                 DEBUG(0,("blocking_lock_reply_error: PANIC - unknown type on blocking lock queue - exiting.!\n"));
422                 exit_server("PANIC - unknown type on blocking lock queue");
423         }
424 }
425
426 /****************************************************************************
427  Utility function that returns true if a lock timed out.
428 *****************************************************************************/
429
430 static bool lock_timed_out(const struct blocking_lock_record *blr)
431 {
432         struct timeval tv_curr;
433
434         if (timeval_is_zero(&blr->expire_time)) {
435                 return false; /* Never times out. */
436         }
437
438         tv_curr = timeval_current();
439         if (timeval_compare(&blr->expire_time, &tv_curr) <= 0) {
440                 return true;
441         }
442         return false;
443 }
444
445 /****************************************************************************
446  Attempt to finish off getting all pending blocking locks for a lockingX call.
447  Returns True if we want to be removed from the list.
448 *****************************************************************************/
449
450 static bool process_lockingX(struct blocking_lock_record *blr)
451 {
452         unsigned char locktype = CVAL(blr->req->vwv+3, 0);
453         files_struct *fsp = blr->fsp;
454         uint16_t num_ulocks = SVAL(blr->req->vwv+6, 0);
455         uint16_t num_locks = SVAL(blr->req->vwv+7, 0);
456         bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
457         uint8_t *data;
458         NTSTATUS status = NT_STATUS_OK;
459         bool lock_timeout = lock_timed_out(blr);
460
461         data = discard_const_p(uint8_t, blr->req->buf)
462                 + ((large_file_format ? 20 : 10)*num_ulocks);
463
464         /*
465          * Data now points at the beginning of the list
466          * of smb_lkrng structs.
467          */
468
469         for(; blr->lock_num < num_locks; blr->lock_num++) {
470                 struct byte_range_lock *br_lck = NULL;
471
472                 /*
473                  * Ensure the blr record gets updated with
474                  * any lock we might end up blocked on.
475                  */
476
477                 blr->smblctx = get_lock_pid( data, blr->lock_num, large_file_format);
478                 blr->count = get_lock_count( data, blr->lock_num, large_file_format);
479                 blr->offset = get_lock_offset( data, blr->lock_num, large_file_format);
480
481                 /*
482                  * We know err cannot be set as if it was the lock
483                  * request would never have been queued. JRA.
484                  */
485                 errno = 0;
486                 br_lck = do_lock(fsp->conn->sconn->msg_ctx,
487                                 fsp,
488                                 blr->smblctx,
489                                 blr->count,
490                                 blr->offset,
491                                 ((locktype & LOCKING_ANDX_SHARED_LOCK) ?
492                                         READ_LOCK : WRITE_LOCK),
493                                 WINDOWS_LOCK,
494                                 True,
495                                 &status,
496                                 &blr->blocking_smblctx);
497
498                 if (ERROR_WAS_LOCK_DENIED(status) && !lock_timeout) {
499                         /*
500                          * If we didn't timeout, but still need to wait,
501                          * re-add the pending lock entry whilst holding
502                          * the brlock db lock.
503                          */
504                         NTSTATUS status1 =
505                                 brl_lock(blr->fsp->conn->sconn->msg_ctx,
506                                         br_lck,
507                                         blr->smblctx,
508                                         messaging_server_id(
509                                                 blr->fsp->conn->sconn->msg_ctx),
510                                         blr->offset,
511                                         blr->count,
512                                         blr->lock_type == READ_LOCK ?
513                                                 PENDING_READ_LOCK :
514                                                 PENDING_WRITE_LOCK,
515                                                 blr->lock_flav,
516                                         true, /* Blocking lock. */
517                                         NULL);
518
519                         if (!NT_STATUS_IS_OK(status1)) {
520                                 DEBUG(0,("failed to add PENDING_LOCK "
521                                         "record.\n"));
522                         }
523                 }
524
525                 TALLOC_FREE(br_lck);
526
527                 if (NT_STATUS_IS_ERR(status)) {
528                         break;
529                 }
530         }
531
532         if(blr->lock_num == num_locks) {
533                 /*
534                  * Success - we got all the locks.
535                  */
536
537                 DEBUG(3,("process_lockingX file = %s, %s, type=%d "
538                          "num_locks=%d\n", fsp_str_dbg(fsp), fsp_fnum_dbg(fsp),
539                          (unsigned int)locktype, num_locks));
540
541                 reply_lockingX_success(blr);
542                 return True;
543         }
544
545         if (!ERROR_WAS_LOCK_DENIED(status)) {
546                 /*
547                  * We have other than a "can't get lock"
548                  * error. Free any locks we had and return an error.
549                  * Return True so we get dequeued.
550                  */
551                 blocking_lock_reply_error(blr, status);
552                 return True;
553         }
554
555         /*
556          * Return an error to the client if we timed out.
557          */
558         if (lock_timeout) {
559                 blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
560                 return true;
561         }
562
563         /*
564          * Still can't get all the locks - keep waiting.
565          */
566
567         DEBUG(10, ("process_lockingX: only got %d locks of %d needed for "
568                    "file %s, %s. Waiting....\n",
569                    blr->lock_num, num_locks, fsp_str_dbg(fsp),
570                    fsp_fnum_dbg(fsp)));
571
572         return False;
573 }
574
575 /****************************************************************************
576  Attempt to get the posix lock request from a SMBtrans2 call.
577  Returns True if we want to be removed from the list.
578 *****************************************************************************/
579
580 static bool process_trans2(struct blocking_lock_record *blr)
581 {
582         char params[2];
583         NTSTATUS status;
584         bool lock_timeout = lock_timed_out(blr);
585
586         struct byte_range_lock *br_lck = do_lock(
587                                                 blr->fsp->conn->sconn->msg_ctx,
588                                                 blr->fsp,
589                                                 blr->smblctx,
590                                                 blr->count,
591                                                 blr->offset,
592                                                 blr->lock_type,
593                                                 blr->lock_flav,
594                                                 True,
595                                                 &status,
596                                                 &blr->blocking_smblctx);
597         if (ERROR_WAS_LOCK_DENIED(status) && !lock_timeout) {
598                 /*
599                  * If we didn't timeout, but still need to wait,
600                  * re-add the pending lock entry whilst holding
601                  * the brlock db lock.
602                  */
603                 NTSTATUS status1 =
604                         brl_lock(blr->fsp->conn->sconn->msg_ctx,
605                                 br_lck,
606                                 blr->smblctx,
607                                 messaging_server_id(
608                                         blr->fsp->conn->sconn->msg_ctx),
609                                 blr->offset,
610                                 blr->count,
611                                 blr->lock_type == READ_LOCK ?
612                                         PENDING_READ_LOCK :
613                                         PENDING_WRITE_LOCK,
614                                 blr->lock_flav,
615                                 true, /* Blocking lock. */
616                                 NULL);
617
618                 if (!NT_STATUS_IS_OK(status1)) {
619                         DEBUG(0,("failed to add PENDING_LOCK record.\n"));
620                 }
621         }
622
623         TALLOC_FREE(br_lck);
624
625         if (!NT_STATUS_IS_OK(status)) {
626                 if (ERROR_WAS_LOCK_DENIED(status)) {
627                         if (lock_timeout) {
628                                 /*
629                                  * Return an error if we timed out
630                                  * and return true to get dequeued.
631                                  */
632                                 blocking_lock_reply_error(blr,
633                                         NT_STATUS_FILE_LOCK_CONFLICT);
634                                 return true;
635                         }
636                         /* Still can't get the lock, just keep waiting. */
637                         return False;
638                 }
639                 /*
640                  * We have other than a "can't get lock"
641                  * error. Send an error and return True so we get dequeued.
642                  */
643                 blocking_lock_reply_error(blr, status);
644                 return True;
645         }
646
647         /* We finally got the lock, return success. */
648
649         SSVAL(params,0,0);
650         /* Fake up max_data_bytes here - we know it fits. */
651         send_trans2_replies(blr->fsp->conn, blr->req, NT_STATUS_OK, params, 2, NULL, 0, 0xffff);
652         return True;
653 }
654
655
656 /****************************************************************************
657  Process a blocking lock SMB.
658  Returns True if we want to be removed from the list.
659 *****************************************************************************/
660
661 static bool blocking_lock_record_process(struct blocking_lock_record *blr)
662 {
663         switch(blr->req->cmd) {
664                 case SMBlockingX:
665                         return process_lockingX(blr);
666                 case SMBtrans2:
667                 case SMBtranss2:
668                         return process_trans2(blr);
669                 default:
670                         DEBUG(0,("blocking_lock_record_process: PANIC - unknown type on blocking lock queue - exiting.!\n"));
671                         exit_server("PANIC - unknown type on blocking lock queue");
672         }
673         return False; /* Keep compiler happy. */
674 }
675
676 /****************************************************************************
677  Cancel entries by fnum from the blocking lock pending queue.
678  Called when a file is closed.
679 *****************************************************************************/
680
681 void smbd_cancel_pending_lock_requests_by_fid(files_struct *fsp,
682                                               struct byte_range_lock *br_lck,
683                                               enum file_close_type close_type)
684 {
685         struct smbd_server_connection *sconn = fsp->conn->sconn;
686         struct blocking_lock_record *blr, *blr_cancelled, *next = NULL;
687
688         if (sconn->using_smb2) {
689                 cancel_pending_lock_requests_by_fid_smb2(fsp,
690                                         br_lck,
691                                         close_type);
692                 return;
693         }
694
695         for(blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) {
696                 unsigned char locktype = 0;
697
698                 next = blr->next;
699                 if (blr->fsp->fnum != fsp->fnum) {
700                         continue;
701                 }
702
703                 if (blr->req->cmd == SMBlockingX) {
704                         locktype = CVAL(blr->req->vwv+3, 0);
705                 }
706
707                 DEBUG(10, ("remove_pending_lock_requests_by_fid - removing "
708                            "request type %d for file %s, %s\n",
709                            blr->req->cmd, fsp_str_dbg(fsp), fsp_fnum_dbg(fsp)));
710
711                 blr_cancelled = blocking_lock_cancel_smb1(fsp,
712                                      blr->smblctx,
713                                      blr->offset,
714                                      blr->count,
715                                      blr->lock_flav,
716                                      locktype,
717                                      NT_STATUS_RANGE_NOT_LOCKED);
718
719                 SMB_ASSERT(blr_cancelled == blr);
720
721                 brl_lock_cancel(br_lck,
722                                 blr->smblctx,
723                                 messaging_server_id(sconn->msg_ctx),
724                                 blr->offset,
725                                 blr->count,
726                                 blr->lock_flav);
727
728                 /* We're closing the file fsp here, so ensure
729                  * we don't have a dangling pointer. */
730                 blr->fsp = NULL;
731         }
732 }
733
734 /****************************************************************************
735  Delete entries by mid from the blocking lock pending queue. Always send reply.
736  Only called from the SMB1 cancel code.
737 *****************************************************************************/
738
739 void remove_pending_lock_requests_by_mid_smb1(
740         struct smbd_server_connection *sconn, uint64_t mid)
741 {
742         struct blocking_lock_record *blr, *next = NULL;
743
744         for(blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) {
745                 files_struct *fsp;
746                 struct byte_range_lock *br_lck;
747
748                 next = blr->next;
749
750                 if (blr->req->mid != mid) {
751                         continue;
752                 }
753
754                 fsp = blr->fsp;
755                 br_lck = brl_get_locks(talloc_tos(), fsp);
756
757                 if (br_lck) {
758                         DEBUG(10, ("remove_pending_lock_requests_by_mid_smb1 - "
759                                    "removing request type %d for file %s, %s\n",
760                                    blr->req->cmd, fsp_str_dbg(fsp),
761                                    fsp_fnum_dbg(fsp)));
762
763                         brl_lock_cancel(br_lck,
764                                         blr->smblctx,
765                                         messaging_server_id(sconn->msg_ctx),
766                                         blr->offset,
767                                         blr->count,
768                                         blr->lock_flav);
769                         TALLOC_FREE(br_lck);
770                 }
771
772                 blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
773                 DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr);
774                 TALLOC_FREE(blr);
775         }
776 }
777
778 /****************************************************************************
779  Is this mid a blocking lock request on the queue ?
780  Currently only called from the SMB1 unix extensions POSIX lock code.
781 *****************************************************************************/
782
783 bool blocking_lock_was_deferred_smb1(
784         struct smbd_server_connection *sconn, uint64_t mid)
785 {
786         struct blocking_lock_record *blr, *next = NULL;
787
788         for(blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) {
789                 next = blr->next;
790                 if(blr->req->mid == mid) {
791                         return True;
792                 }
793         }
794         return False;
795 }
796
797 /****************************************************************************
798   Set a flag as an unlock request affects one of our pending locks.
799 *****************************************************************************/
800
801 static void received_unlock_msg(struct messaging_context *msg,
802                                 void *private_data,
803                                 uint32_t msg_type,
804                                 struct server_id server_id,
805                                 DATA_BLOB *data)
806 {
807         struct smbd_server_connection *sconn =
808                 talloc_get_type_abort(private_data,
809                 struct smbd_server_connection);
810
811         DEBUG(10,("received_unlock_msg\n"));
812         process_blocking_lock_queue(sconn);
813 }
814
815 /****************************************************************************
816  Process the blocking lock queue. Note that this is only called as root.
817 *****************************************************************************/
818
819 void process_blocking_lock_queue(struct smbd_server_connection *sconn)
820 {
821         struct blocking_lock_record *blr, *next = NULL;
822
823         if (sconn->using_smb2) {
824                 process_blocking_lock_queue_smb2(sconn, timeval_current());
825                 return;
826         }
827
828         /*
829          * Go through the queue and see if we can get any of the locks.
830          */
831
832         for (blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = next) {
833                 struct byte_range_lock *br_lck = NULL;
834
835                 next = blr->next;
836
837                 /*
838                  * Go through the remaining locks and try and obtain them.
839                  * The call returns True if all locks were obtained successfully
840                  * and False if we still need to wait.
841                  */
842
843                 DEBUG(10, ("Processing BLR = %p\n", blr));
844
845                 /*
846                  * Connections with pending locks are not marked as idle.
847                  */
848                 blr->fsp->conn->lastused_count++;
849
850                 /*
851                  * Remove the pending lock we're waiting on.
852                  * If we need to keep waiting blocking_lock_record_process()
853                  * will re-add it.
854                  */
855
856                 br_lck = brl_get_locks(talloc_tos(), blr->fsp);
857                 if (br_lck) {
858                         brl_lock_cancel(br_lck,
859                                 blr->smblctx,
860                                 messaging_server_id(sconn->msg_ctx),
861                                 blr->offset,
862                                 blr->count,
863                                 blr->lock_flav);
864                 }
865                 TALLOC_FREE(br_lck);
866
867                 if(!blocking_lock_record_process(blr)) {
868                         DEBUG(10, ("still waiting for lock. BLR = %p\n", blr));
869                         continue;
870                 }
871
872                 DEBUG(10, ("BLR_process returned true: removing BLR = %p\n",
873                         blr));
874
875                 DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr);
876                 TALLOC_FREE(blr);
877         }
878
879         recalc_brl_timeout(sconn);
880 }
881
882 /****************************************************************************
883  Handle a cancel message. Lock already moved onto the cancel queue.
884 *****************************************************************************/
885
886 #define MSG_BLOCKING_LOCK_CANCEL_SIZE (sizeof(struct blocking_lock_record *) + sizeof(NTSTATUS))
887
888 static void process_blocking_lock_cancel_message(struct messaging_context *ctx,
889                                                  void *private_data,
890                                                  uint32_t msg_type,
891                                                  struct server_id server_id,
892                                                  DATA_BLOB *data)
893 {
894         NTSTATUS err;
895         const char *msg = (const char *)data->data;
896         struct blocking_lock_record *blr;
897         struct smbd_server_connection *sconn =
898                 talloc_get_type_abort(private_data,
899                 struct smbd_server_connection);
900
901         if (data->data == NULL) {
902                 smb_panic("process_blocking_lock_cancel_message: null msg");
903         }
904
905         if (data->length != MSG_BLOCKING_LOCK_CANCEL_SIZE) {
906                 DEBUG(0, ("process_blocking_lock_cancel_message: "
907                           "Got invalid msg len %d\n", (int)data->length));
908                 smb_panic("process_blocking_lock_cancel_message: bad msg");
909         }
910
911         memcpy(&blr, msg, sizeof(blr));
912         memcpy(&err, &msg[sizeof(blr)], sizeof(NTSTATUS));
913
914         DEBUG(10,("process_blocking_lock_cancel_message: returning error %s\n",
915                 nt_errstr(err) ));
916
917         blocking_lock_reply_error(blr, err);
918         DLIST_REMOVE(sconn->smb1.locks.blocking_lock_cancelled_queue, blr);
919         TALLOC_FREE(blr);
920 }
921
922 /****************************************************************************
923  Send ourselves a blocking lock cancelled message. Handled asynchronously above.
924  Returns the blocking_lock_record that is being cancelled.
925  Only called from the SMB1 code.
926 *****************************************************************************/
927
928 struct blocking_lock_record *blocking_lock_cancel_smb1(files_struct *fsp,
929                         uint64_t smblctx,
930                         uint64_t offset,
931                         uint64_t count,
932                         enum brl_flavour lock_flav,
933                         unsigned char locktype,
934                         NTSTATUS err)
935 {
936         struct smbd_server_connection *sconn = fsp->conn->sconn;
937         char msg[MSG_BLOCKING_LOCK_CANCEL_SIZE];
938         struct blocking_lock_record *blr;
939
940         if (!sconn->smb1.locks.blocking_lock_cancel_state) {
941                 /* Register our message. */
942                 messaging_register(sconn->msg_ctx, sconn,
943                                    MSG_SMB_BLOCKING_LOCK_CANCEL,
944                                    process_blocking_lock_cancel_message);
945
946                 sconn->smb1.locks.blocking_lock_cancel_state = True;
947         }
948
949         for (blr = sconn->smb1.locks.blocking_lock_queue; blr; blr = blr->next) {
950                 if (fsp == blr->fsp &&
951                                 smblctx == blr->smblctx &&
952                                 offset == blr->offset &&
953                                 count == blr->count &&
954                                 lock_flav == blr->lock_flav) {
955                         break;
956                 }
957         }
958
959         if (!blr) {
960                 return NULL;
961         }
962
963         /* Check the flags are right. */
964         if (blr->req->cmd == SMBlockingX &&
965                 (locktype & LOCKING_ANDX_LARGE_FILES) !=
966                         (CVAL(blr->req->vwv+3, 0) & LOCKING_ANDX_LARGE_FILES)) {
967                 return NULL;
968         }
969
970         /* Move to cancelled queue. */
971         DLIST_REMOVE(sconn->smb1.locks.blocking_lock_queue, blr);
972         DLIST_ADD(sconn->smb1.locks.blocking_lock_cancelled_queue, blr);
973
974         /* Create the message. */
975         memcpy(msg, &blr, sizeof(blr));
976         memcpy(&msg[sizeof(blr)], &err, sizeof(NTSTATUS));
977
978         messaging_send_buf(sconn->msg_ctx, messaging_server_id(sconn->msg_ctx),
979                            MSG_SMB_BLOCKING_LOCK_CANCEL,
980                            (uint8_t *)&msg, sizeof(msg));
981
982         return blr;
983 }