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