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