3f49421f53ce12be13a23ed651e7b5d4893b490a
[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 reply_lockingX_error(struct blocking_lock_record *blr, NTSTATUS status)
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         generic_blocking_lock_error(blr, status);
348 }
349
350 /****************************************************************************
351  Return a lock fail error.
352 *****************************************************************************/
353
354 static void blocking_lock_reply_error(struct blocking_lock_record *blr, NTSTATUS status)
355 {
356         DEBUG(10, ("Replying with error=%s. BLR = %p\n", nt_errstr(status), blr));
357
358         switch(blr->req->cmd) {
359         case SMBlockingX:
360                 reply_lockingX_error(blr, status);
361                 break;
362         case SMBtrans2:
363         case SMBtranss2:
364                 reply_nterror(blr->req, status);
365
366                 /*
367                  * construct_reply_common has done us the favor to pre-fill
368                  * the command field with SMBtranss2 which is wrong :-)
369                  */
370                 SCVAL(blr->req->outbuf,smb_com,SMBtrans2);
371
372                 if (!srv_send_smb(smbd_server_fd(),
373                                   (char *)blr->req->outbuf,
374                                   true, blr->req->seqnum+1,
375                                   IS_CONN_ENCRYPTED(blr->fsp->conn),
376                                   NULL)) {
377                         exit_server_cleanly("blocking_lock_reply_error: "
378                                             "srv_send_smb failed.");
379                 }
380                 TALLOC_FREE(blr->req->outbuf);
381                 break;
382         default:
383                 DEBUG(0,("blocking_lock_reply_error: PANIC - unknown type on blocking lock queue - exiting.!\n"));
384                 exit_server("PANIC - unknown type on blocking lock queue");
385         }
386 }
387
388 /****************************************************************************
389  Attempt to finish off getting all pending blocking locks for a lockingX call.
390  Returns True if we want to be removed from the list.
391 *****************************************************************************/
392
393 static bool process_lockingX(struct blocking_lock_record *blr)
394 {
395         unsigned char locktype = CVAL(blr->req->vwv+3, 0);
396         files_struct *fsp = blr->fsp;
397         uint16 num_ulocks = SVAL(blr->req->vwv+6, 0);
398         uint16 num_locks = SVAL(blr->req->vwv+7, 0);
399         uint64_t count = (uint64_t)0, offset = (uint64_t)0;
400         uint32 lock_pid;
401         bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
402         uint8_t *data;
403         NTSTATUS status = NT_STATUS_OK;
404
405         data = (uint8_t *)blr->req->buf
406                 + ((large_file_format ? 20 : 10)*num_ulocks);
407
408         /* 
409          * Data now points at the beginning of the list
410          * of smb_lkrng structs.
411          */
412
413         for(; blr->lock_num < num_locks; blr->lock_num++) {
414                 struct byte_range_lock *br_lck = NULL;
415                 bool err;
416
417                 lock_pid = get_lock_pid( data, blr->lock_num, large_file_format);
418                 count = get_lock_count( data, blr->lock_num, large_file_format);
419                 offset = get_lock_offset( data, blr->lock_num, large_file_format, &err);
420
421                 /*
422                  * We know err cannot be set as if it was the lock
423                  * request would never have been queued. JRA.
424                  */
425                 errno = 0;
426                 br_lck = do_lock(smbd_messaging_context(),
427                                 fsp,
428                                 lock_pid,
429                                 count,
430                                 offset, 
431                                 ((locktype & LOCKING_ANDX_SHARED_LOCK) ?
432                                         READ_LOCK : WRITE_LOCK),
433                                 WINDOWS_LOCK,
434                                 True,
435                                 &status,
436                                 &blr->blocking_pid,
437                                 blr);
438
439                 TALLOC_FREE(br_lck);
440
441                 if (NT_STATUS_IS_ERR(status)) {
442                         break;
443                 }
444         }
445
446         if(blr->lock_num == num_locks) {
447                 /*
448                  * Success - we got all the locks.
449                  */
450
451                 DEBUG(3,("process_lockingX file = %s, fnum=%d type=%d "
452                          "num_locks=%d\n", fsp_str_dbg(fsp), fsp->fnum,
453                          (unsigned int)locktype, num_locks));
454
455                 reply_lockingX_success(blr);
456                 return True;
457         }
458
459         if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) &&
460             !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) {
461                 /*
462                  * We have other than a "can't get lock"
463                  * error. Free any locks we had and return an error.
464                  * Return True so we get dequeued.
465                  */
466                 blocking_lock_reply_error(blr, status);
467                 return True;
468         }
469
470         /*
471          * Still can't get all the locks - keep waiting.
472          */
473
474         DEBUG(10,("process_lockingX: only got %d locks of %d needed for file %s, fnum = %d. \
475 Waiting....\n", 
476                  blr->lock_num, num_locks, fsp_str_dbg(fsp), fsp->fnum));
477
478         return False;
479 }
480
481 /****************************************************************************
482  Attempt to get the posix lock request from a SMBtrans2 call.
483  Returns True if we want to be removed from the list.
484 *****************************************************************************/
485
486 static bool process_trans2(struct blocking_lock_record *blr)
487 {
488         char params[2];
489         NTSTATUS status;
490         struct byte_range_lock *br_lck = do_lock(smbd_messaging_context(),
491                                                 blr->fsp,
492                                                 blr->lock_pid,
493                                                 blr->count,
494                                                 blr->offset,
495                                                 blr->lock_type,
496                                                 blr->lock_flav,
497                                                 True,
498                                                 &status,
499                                                 &blr->blocking_pid,
500                                                 blr);
501         TALLOC_FREE(br_lck);
502
503         if (!NT_STATUS_IS_OK(status)) {
504                 if (ERROR_WAS_LOCK_DENIED(status)) {
505                         /* Still can't get the lock, just keep waiting. */
506                         return False;
507                 }       
508                 /*
509                  * We have other than a "can't get lock"
510                  * error. Send an error and return True so we get dequeued.
511                  */
512                 blocking_lock_reply_error(blr, status);
513                 return True;
514         }
515
516         /* We finally got the lock, return success. */
517
518         SSVAL(params,0,0);
519         /* Fake up max_data_bytes here - we know it fits. */
520         send_trans2_replies(blr->fsp->conn, blr->req, params, 2, NULL, 0, 0xffff);
521         return True;
522 }
523
524
525 /****************************************************************************
526  Process a blocking lock SMB.
527  Returns True if we want to be removed from the list.
528 *****************************************************************************/
529
530 static bool blocking_lock_record_process(struct blocking_lock_record *blr)
531 {
532         switch(blr->req->cmd) {
533                 case SMBlockingX:
534                         return process_lockingX(blr);
535                 case SMBtrans2:
536                 case SMBtranss2:
537                         return process_trans2(blr);
538                 default:
539                         DEBUG(0,("blocking_lock_record_process: PANIC - unknown type on blocking lock queue - exiting.!\n"));
540                         exit_server("PANIC - unknown type on blocking lock queue");
541         }
542         return False; /* Keep compiler happy. */
543 }
544
545 /****************************************************************************
546  Cancel entries by fnum from the blocking lock pending queue.
547 *****************************************************************************/
548
549 void cancel_pending_lock_requests_by_fid(files_struct *fsp, struct byte_range_lock *br_lck)
550 {
551         struct blocking_lock_record *blr, *blr_cancelled, *next = NULL;
552
553         for(blr = blocking_lock_queue; blr; blr = next) {
554                 unsigned char locktype = 0;
555
556                 next = blr->next;
557                 if (blr->fsp->fnum != fsp->fnum) {
558                         continue;
559                 }
560
561                 if (blr->req->cmd == SMBlockingX) {
562                         locktype = CVAL(blr->req->vwv+3, 0);
563                 }
564
565                 DEBUG(10, ("remove_pending_lock_requests_by_fid - removing "
566                            "request type %d for file %s fnum = %d\n",
567                            blr->req->cmd, fsp_str_dbg(fsp), fsp->fnum));
568
569                 blr_cancelled = blocking_lock_cancel(fsp,
570                                      blr->lock_pid,
571                                      blr->offset,
572                                      blr->count,
573                                      blr->lock_flav,
574                                      locktype,
575                                      NT_STATUS_RANGE_NOT_LOCKED);
576
577                 SMB_ASSERT(blr_cancelled == blr);
578
579                 brl_lock_cancel(br_lck,
580                                 blr->lock_pid,
581                                 procid_self(),
582                                 blr->offset,
583                                 blr->count,
584                                 blr->lock_flav,
585                                 blr);
586
587                 /* We're closing the file fsp here, so ensure
588                  * we don't have a dangling pointer. */
589                 blr->fsp = NULL;
590         }
591 }
592
593 /****************************************************************************
594  Delete entries by mid from the blocking lock pending queue. Always send reply.
595 *****************************************************************************/
596
597 void remove_pending_lock_requests_by_mid(int mid)
598 {
599         struct blocking_lock_record *blr, *next = NULL;
600
601         for(blr = blocking_lock_queue; blr; blr = next) {
602                 files_struct *fsp;
603                 struct byte_range_lock *br_lck;
604
605                 next = blr->next;
606
607                 if (blr->req->mid != mid) {
608                         continue;
609                 }
610
611                 fsp = blr->fsp;
612                 br_lck = brl_get_locks(talloc_tos(), fsp);
613
614                 if (br_lck) {
615                         DEBUG(10, ("remove_pending_lock_requests_by_mid - "
616                                    "removing request type %d for file %s fnum "
617                                    "= %d\n", blr->req->cmd, fsp_str_dbg(fsp),
618                                    fsp->fnum ));
619
620                         brl_lock_cancel(br_lck,
621                                         blr->lock_pid,
622                                         procid_self(),
623                                         blr->offset,
624                                         blr->count,
625                                         blr->lock_flav,
626                                         blr);
627                         TALLOC_FREE(br_lck);
628                 }
629
630                 blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
631                 DLIST_REMOVE(blocking_lock_queue, blr);
632                 TALLOC_FREE(blr);
633         }
634 }
635
636 /****************************************************************************
637  Is this mid a blocking lock request on the queue ?
638 *****************************************************************************/
639
640 bool blocking_lock_was_deferred(int mid)
641 {
642         struct blocking_lock_record *blr, *next = NULL;
643
644         for(blr = blocking_lock_queue; blr; blr = next) {
645                 next = blr->next;
646                 if(blr->req->mid == mid) {
647                         return True;
648                 }
649         }
650         return False;
651 }
652
653 /****************************************************************************
654   Set a flag as an unlock request affects one of our pending locks.
655 *****************************************************************************/
656
657 static void received_unlock_msg(struct messaging_context *msg,
658                                 void *private_data,
659                                 uint32_t msg_type,
660                                 struct server_id server_id,
661                                 DATA_BLOB *data)
662 {
663         DEBUG(10,("received_unlock_msg\n"));
664         process_blocking_lock_queue();
665 }
666
667 /****************************************************************************
668  Process the blocking lock queue. Note that this is only called as root.
669 *****************************************************************************/
670
671 void process_blocking_lock_queue(void)
672 {
673         struct timeval tv_curr = timeval_current();
674         struct blocking_lock_record *blr, *next = NULL;
675
676         /*
677          * Go through the queue and see if we can get any of the locks.
678          */
679
680         for (blr = blocking_lock_queue; blr; blr = next) {
681
682                 next = blr->next;
683
684                 /*
685                  * Go through the remaining locks and try and obtain them.
686                  * The call returns True if all locks were obtained successfully
687                  * and False if we still need to wait.
688                  */
689
690                 DEBUG(10, ("Processing BLR = %p\n", blr));
691
692                 /* We use set_current_service so connections with
693                  * pending locks are not marked as idle.
694                  */
695
696                 set_current_service(blr->fsp->conn,
697                                 SVAL(blr->req->inbuf,smb_flg),
698                                 false);
699
700                 if(blocking_lock_record_process(blr)) {
701                         struct byte_range_lock *br_lck = brl_get_locks(
702                                 talloc_tos(), blr->fsp);
703
704                         DEBUG(10, ("BLR_process returned true: cancelling and "
705                             "removing lock. BLR = %p\n", blr));
706
707                         if (br_lck) {
708                                 brl_lock_cancel(br_lck,
709                                         blr->lock_pid,
710                                         procid_self(),
711                                         blr->offset,
712                                         blr->count,
713                                         blr->lock_flav,
714                                         blr);
715                                 TALLOC_FREE(br_lck);
716                         }
717
718                         DLIST_REMOVE(blocking_lock_queue, blr);
719                         TALLOC_FREE(blr);
720                         continue;
721                 }
722
723                 /*
724                  * We couldn't get the locks for this record on the list.
725                  * If the time has expired, return a lock error.
726                  */
727
728                 if (!timeval_is_zero(&blr->expire_time) && timeval_compare(&blr->expire_time, &tv_curr) <= 0) {
729                         struct byte_range_lock *br_lck = brl_get_locks(
730                                 talloc_tos(), blr->fsp);
731
732                         DEBUG(10, ("Lock timed out! BLR = %p\n", blr));
733
734                         /*
735                          * Lock expired - throw away all previously
736                          * obtained locks and return lock error.
737                          */
738
739                         if (br_lck) {
740                                 DEBUG(5,("process_blocking_lock_queue: "
741                                          "pending lock fnum = %d for file %s "
742                                          "timed out.\n", blr->fsp->fnum,
743                                          fsp_str_dbg(blr->fsp)));
744
745                                 brl_lock_cancel(br_lck,
746                                         blr->lock_pid,
747                                         procid_self(),
748                                         blr->offset,
749                                         blr->count,
750                                         blr->lock_flav,
751                                         blr);
752                                 TALLOC_FREE(br_lck);
753                         }
754
755                         blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
756                         DLIST_REMOVE(blocking_lock_queue, blr);
757                         TALLOC_FREE(blr);
758                 }
759         }
760
761         recalc_brl_timeout();
762 }
763
764 /****************************************************************************
765  Handle a cancel message. Lock already moved onto the cancel queue.
766 *****************************************************************************/
767
768 #define MSG_BLOCKING_LOCK_CANCEL_SIZE (sizeof(struct blocking_lock_record *) + sizeof(NTSTATUS))
769
770 static void process_blocking_lock_cancel_message(struct messaging_context *ctx,
771                                                  void *private_data,
772                                                  uint32_t msg_type,
773                                                  struct server_id server_id,
774                                                  DATA_BLOB *data)
775 {
776         NTSTATUS err;
777         const char *msg = (const char *)data->data;
778         struct blocking_lock_record *blr;
779
780         if (data->data == NULL) {
781                 smb_panic("process_blocking_lock_cancel_message: null msg");
782         }
783
784         if (data->length != MSG_BLOCKING_LOCK_CANCEL_SIZE) {
785                 DEBUG(0, ("process_blocking_lock_cancel_message: "
786                           "Got invalid msg len %d\n", (int)data->length));
787                 smb_panic("process_blocking_lock_cancel_message: bad msg");
788         }
789
790         memcpy(&blr, msg, sizeof(blr));
791         memcpy(&err, &msg[sizeof(blr)], sizeof(NTSTATUS));
792
793         DEBUG(10,("process_blocking_lock_cancel_message: returning error %s\n",
794                 nt_errstr(err) ));
795
796         blocking_lock_reply_error(blr, err);
797         DLIST_REMOVE(blocking_lock_cancelled_queue, blr);
798         TALLOC_FREE(blr);
799 }
800
801 /****************************************************************************
802  Send ourselves a blocking lock cancelled message. Handled asynchronously above.
803  Returns the blocking_lock_record that is being cancelled.
804 *****************************************************************************/
805
806 struct blocking_lock_record *blocking_lock_cancel(files_struct *fsp,
807                         uint32 lock_pid,
808                         uint64_t offset,
809                         uint64_t count,
810                         enum brl_flavour lock_flav,
811                         unsigned char locktype,
812                         NTSTATUS err)
813 {
814         char msg[MSG_BLOCKING_LOCK_CANCEL_SIZE];
815         struct blocking_lock_record *blr;
816
817         if (!blocking_lock_cancel_state) {
818                 /* Register our message. */
819                 messaging_register(smbd_messaging_context(), NULL,
820                                    MSG_SMB_BLOCKING_LOCK_CANCEL,
821                                    process_blocking_lock_cancel_message);
822
823                 blocking_lock_cancel_state = True;
824         }
825
826         for (blr = blocking_lock_queue; blr; blr = blr->next) {
827                 if (fsp == blr->fsp &&
828                                 lock_pid == blr->lock_pid &&
829                                 offset == blr->offset &&
830                                 count == blr->count &&
831                                 lock_flav == blr->lock_flav) {
832                         break;
833                 }
834         }
835
836         if (!blr) {
837                 return NULL;
838         }
839
840         /* Check the flags are right. */
841         if (blr->req->cmd == SMBlockingX &&
842                 (locktype & LOCKING_ANDX_LARGE_FILES) !=
843                         (CVAL(blr->req->vwv+3, 0) & LOCKING_ANDX_LARGE_FILES)) {
844                 return NULL;
845         }
846
847         /* Move to cancelled queue. */
848         DLIST_REMOVE(blocking_lock_queue, blr);
849         DLIST_ADD(blocking_lock_cancelled_queue, blr);
850
851         /* Create the message. */
852         memcpy(msg, &blr, sizeof(blr));
853         memcpy(&msg[sizeof(blr)], &err, sizeof(NTSTATUS));
854
855         messaging_send_buf(smbd_messaging_context(), procid_self(),
856                            MSG_SMB_BLOCKING_LOCK_CANCEL,
857                            (uint8 *)&msg, sizeof(msg));
858
859         return blr;
860 }