2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 1998 - 2001
6 Copyright (C) Volker Lendecke 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #define DBGC_CLASS DBGC_LOCKING
24 #include "lib/util/server_id.h"
25 #include "locking/share_mode_lock.h"
26 #include "smbd/smbd.h"
27 #include "smbd/globals.h"
29 #include "locking/leases_db.h"
30 #include "../librpc/gen_ndr/ndr_open_files.h"
31 #include "lib/util/tevent_ntstatus.h"
32 #include "source3/smbd/dir.h"
35 * helper function used by the kernel oplock backends to post the break message
37 void break_kernel_oplock(struct messaging_context
*msg_ctx
, files_struct
*fsp
)
39 struct oplock_break_message msg
= {
41 .share_file_id
= fh_get_gen_id(fsp
->fh
),
43 enum ndr_err_code ndr_err
;
45 DATA_BLOB blob
= {.data
= msgbuf
, .length
= sizeof(msgbuf
)};
47 /* Don't need to be root here as we're only ever
48 sending to ourselves. */
50 ndr_err
= ndr_push_struct_into_fixed_blob(
53 (ndr_push_flags_fn_t
)ndr_push_oplock_break_message
);
54 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
55 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
60 messaging_send(msg_ctx
,
61 messaging_server_id(msg_ctx
),
66 /****************************************************************************
67 Attempt to set an oplock on a file. Succeeds if kernel oplocks are
68 disabled (just sets flags).
69 ****************************************************************************/
71 NTSTATUS
set_file_oplock(files_struct
*fsp
)
73 struct smbd_server_connection
*sconn
= fsp
->conn
->sconn
;
74 struct kernel_oplocks
*koplocks
= sconn
->oplocks
.kernel_ops
;
75 bool use_kernel
= lp_kernel_oplocks(SNUM(fsp
->conn
)) &&
77 struct file_id_buf buf
;
79 smb_vfs_assert_allowed();
81 if (fsp
->oplock_type
== LEVEL_II_OPLOCK
&& use_kernel
) {
82 DEBUG(10, ("Refusing level2 oplock, kernel oplocks "
83 "don't support them\n"));
84 return NT_STATUS_NOT_SUPPORTED
;
87 if ((fsp
->oplock_type
!= NO_OPLOCK
) &&
89 !koplocks
->ops
->set_oplock(koplocks
, fsp
, fsp
->oplock_type
))
91 return map_nt_error_from_unix(errno
);
94 fsp
->sent_oplock_break
= NO_BREAK_SENT
;
95 if (fsp
->oplock_type
== LEVEL_II_OPLOCK
) {
96 sconn
->oplocks
.level_II_open
++;
97 } else if (EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
98 sconn
->oplocks
.exclusive_open
++;
101 DBG_INFO("granted oplock on file %s, %s/%"PRIu64
", "
102 "tv_sec = %x, tv_usec = %x\n",
104 file_id_str_buf(fsp
->file_id
, &buf
),
105 fh_get_gen_id(fsp
->fh
),
106 (int)fsp
->open_time
.tv_sec
,
107 (int)fsp
->open_time
.tv_usec
);
112 static void release_fsp_kernel_oplock(files_struct
*fsp
)
114 struct smbd_server_connection
*sconn
= fsp
->conn
->sconn
;
115 struct kernel_oplocks
*koplocks
= sconn
->oplocks
.kernel_ops
;
118 smb_vfs_assert_allowed();
120 if (koplocks
== NULL
) {
123 use_kernel
= lp_kernel_oplocks(SNUM(fsp
->conn
));
127 if (fsp
->oplock_type
== NO_OPLOCK
) {
130 if (fsp
->oplock_type
== LEASE_OPLOCK
) {
132 * For leases we don't touch kernel oplocks at all
137 koplocks
->ops
->release_oplock(koplocks
, fsp
, NO_OPLOCK
);
140 /****************************************************************************
141 Attempt to release an oplock on a file. Decrements oplock count.
142 ****************************************************************************/
144 void release_file_oplock(files_struct
*fsp
)
146 struct smbd_server_connection
*sconn
= fsp
->conn
->sconn
;
148 release_fsp_kernel_oplock(fsp
);
150 if (fsp
->oplock_type
== LEVEL_II_OPLOCK
) {
151 sconn
->oplocks
.level_II_open
--;
152 } else if (EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
153 sconn
->oplocks
.exclusive_open
--;
156 SMB_ASSERT(sconn
->oplocks
.exclusive_open
>=0);
157 SMB_ASSERT(sconn
->oplocks
.level_II_open
>=0);
159 fsp
->oplock_type
= NO_OPLOCK
;
160 fsp
->sent_oplock_break
= NO_BREAK_SENT
;
162 TALLOC_FREE(fsp
->oplock_timeout
);
165 /****************************************************************************
166 Attempt to downgrade an oplock on a file. Doesn't decrement oplock count.
167 ****************************************************************************/
169 static void downgrade_file_oplock(files_struct
*fsp
)
171 struct smbd_server_connection
*sconn
= fsp
->conn
->sconn
;
172 struct kernel_oplocks
*koplocks
= sconn
->oplocks
.kernel_ops
;
173 bool use_kernel
= lp_kernel_oplocks(SNUM(fsp
->conn
)) &&
176 smb_vfs_assert_allowed();
178 if (!EXCLUSIVE_OPLOCK_TYPE(fsp
->oplock_type
)) {
179 DEBUG(0, ("trying to downgrade an already-downgraded oplock!\n"));
184 koplocks
->ops
->release_oplock(koplocks
, fsp
, LEVEL_II_OPLOCK
);
186 fsp
->oplock_type
= LEVEL_II_OPLOCK
;
187 sconn
->oplocks
.exclusive_open
--;
188 sconn
->oplocks
.level_II_open
++;
189 fsp
->sent_oplock_break
= NO_BREAK_SENT
;
191 TALLOC_FREE(fsp
->oplock_timeout
);
194 uint32_t get_lease_type(struct share_mode_entry
*e
, struct file_id id
)
196 struct GUID_txt_buf guid_strbuf
;
197 struct file_id_buf file_id_strbuf
;
199 uint32_t current_state
;
201 if (e
->op_type
!= LEASE_OPLOCK
) {
202 return map_oplock_to_lease_type(e
->op_type
);
205 status
= leases_db_get(&e
->client_guid
,
210 NULL
, /* breaking_to_requested */
211 NULL
, /* breaking_to_required */
212 NULL
, /* lease_version */
214 if (NT_STATUS_IS_OK(status
)) {
215 return current_state
;
218 if (share_entry_stale_pid(e
)) {
221 DBG_ERR("leases_db_get for client_guid [%s] "
222 "lease_key [%"PRIx64
"/%"PRIx64
"] "
223 "file_id [%s] failed: %s\n",
224 GUID_buf_string(&e
->client_guid
, &guid_strbuf
),
225 e
->lease_key
.data
[0],
226 e
->lease_key
.data
[1],
227 file_id_str_buf(id
, &file_id_strbuf
),
229 smb_panic("leases_db_get() failed");
232 /****************************************************************************
233 Remove a file oplock. Copes with level II and exclusive.
234 Locks then unlocks the share mode lock. Client can decide to go directly
235 to none even if a "break-to-level II" was sent.
236 ****************************************************************************/
238 bool remove_oplock(files_struct
*fsp
)
241 struct share_mode_lock
*lck
;
243 DBG_DEBUG("remove_oplock called for %s\n", fsp_str_dbg(fsp
));
245 /* Remove the oplock flag from the sharemode. */
246 lck
= get_existing_share_mode_lock(talloc_tos(), fsp
->file_id
);
248 DBG_ERR("failed to lock share entry for "
249 "file %s\n", fsp_str_dbg(fsp
));
253 ret
= remove_share_oplock(lck
, fsp
);
255 struct file_id_buf buf
;
257 DBG_ERR("failed to remove share oplock for "
259 fsp_str_dbg(fsp
), fsp_fnum_dbg(fsp
),
260 file_id_str_buf(fsp
->file_id
, &buf
));
262 release_file_oplock(fsp
);
269 * Deal with a reply when a break-to-level II was sent.
271 bool downgrade_oplock(files_struct
*fsp
)
274 struct share_mode_lock
*lck
;
276 DEBUG(10, ("downgrade_oplock called for %s\n",
279 lck
= get_existing_share_mode_lock(talloc_tos(), fsp
->file_id
);
281 DEBUG(0,("downgrade_oplock: failed to lock share entry for "
282 "file %s\n", fsp_str_dbg(fsp
)));
285 ret
= downgrade_share_oplock(lck
, fsp
);
287 struct file_id_buf idbuf
;
288 DBG_ERR("failed to downgrade share oplock "
289 "for file %s, %s, file_id %s\n",
292 file_id_str_buf(fsp
->file_id
, &idbuf
));
294 downgrade_file_oplock(fsp
);
300 static void lease_timeout_handler(struct tevent_context
*ctx
,
301 struct tevent_timer
*te
,
305 struct fsp_lease
*lease
=
306 talloc_get_type_abort(private_data
,
308 struct files_struct
*fsp
;
309 struct share_mode_lock
*lck
;
310 uint16_t old_epoch
= lease
->lease
.lease_epoch
;
312 fsp
= file_find_one_fsp_from_lease_key(lease
->sconn
,
313 &lease
->lease
.lease_key
);
316 TALLOC_FREE(lease
->timeout
);
321 * Paranoia check: There can only be one fsp_lease per lease
324 SMB_ASSERT(fsp
->lease
== lease
);
326 lck
= get_existing_share_mode_lock(
327 talloc_tos(), fsp
->file_id
);
330 TALLOC_FREE(lease
->timeout
);
334 fsp_lease_update(fsp
);
336 if (lease
->lease
.lease_epoch
!= old_epoch
) {
338 * If the epoch changed we need to wait for
339 * the next timeout to happen.
341 DEBUG(10, ("lease break timeout race (epoch) for file %s - ignoring\n",
347 if (!(lease
->lease
.lease_flags
& SMB2_LEASE_FLAG_BREAK_IN_PROGRESS
)) {
349 * If the epoch changed we need to wait for
350 * the next timeout to happen.
352 DEBUG(10, ("lease break timeout race (flags) for file %s - ignoring\n",
358 DEBUG(1, ("lease break timed out for file %s -- replying anyway\n",
360 (void)downgrade_lease(lease
->sconn
->client
,
363 &lease
->lease
.lease_key
,
369 bool fsp_lease_update(struct files_struct
*fsp
)
371 const struct GUID
*client_guid
= fsp_client_guid(fsp
);
372 struct fsp_lease
*lease
= fsp
->lease
;
373 uint32_t current_state
;
375 uint16_t lease_version
, epoch
;
378 status
= leases_db_get(client_guid
,
379 &lease
->lease
.lease_key
,
383 NULL
, /* breaking_to_requested */
384 NULL
, /* breaking_to_required */
387 if (!NT_STATUS_IS_OK(status
)) {
388 DBG_WARNING("Could not find lease entry: %s\n",
390 TALLOC_FREE(lease
->timeout
);
391 lease
->lease
.lease_state
= SMB2_LEASE_NONE
;
392 lease
->lease
.lease_epoch
+= 1;
393 lease
->lease
.lease_flags
= 0;
397 DEBUG(10,("%s: refresh lease state\n", __func__
));
399 /* Ensure we're in sync with current lease state. */
400 if (lease
->lease
.lease_epoch
!= epoch
) {
401 DEBUG(10,("%s: cancel outdated timeout\n", __func__
));
402 TALLOC_FREE(lease
->timeout
);
404 lease
->lease
.lease_epoch
= epoch
;
405 lease
->lease
.lease_state
= current_state
;
408 lease
->lease
.lease_flags
|= SMB2_LEASE_FLAG_BREAK_IN_PROGRESS
;
410 if (lease
->timeout
== NULL
) {
411 struct timeval t
= timeval_current_ofs(OPLOCK_BREAK_TIMEOUT
, 0);
413 DEBUG(10,("%s: setup timeout handler\n", __func__
));
415 lease
->timeout
= tevent_add_timer(lease
->sconn
->ev_ctx
,
417 lease_timeout_handler
,
419 if (lease
->timeout
== NULL
) {
420 DEBUG(0, ("%s: Could not add lease timeout handler\n",
425 lease
->lease
.lease_flags
&= ~SMB2_LEASE_FLAG_BREAK_IN_PROGRESS
;
426 TALLOC_FREE(lease
->timeout
);
432 struct downgrade_lease_additional_state
{
433 struct tevent_immediate
*im
;
434 struct smbXsrv_client
*client
;
435 uint32_t break_flags
;
436 struct smb2_lease_key lease_key
;
442 static void downgrade_lease_additional_trigger(struct tevent_context
*ev
,
443 struct tevent_immediate
*im
,
446 struct downgrade_lease_additional_state
*state
=
447 talloc_get_type_abort(private_data
,
448 struct downgrade_lease_additional_state
);
451 status
= smbd_smb2_send_lease_break(state
->client
,
457 if (!NT_STATUS_IS_OK(status
)) {
458 smbd_server_disconnect_client(state
->client
,
464 struct fsps_lease_update_state
{
465 const struct file_id
*id
;
466 const struct smb2_lease_key
*key
;
469 static struct files_struct
*fsps_lease_update_fn(
470 struct files_struct
*fsp
, void *private_data
)
472 struct fsps_lease_update_state
*state
=
473 (struct fsps_lease_update_state
*)private_data
;
475 if (fsp
->oplock_type
!= LEASE_OPLOCK
) {
478 if (!smb2_lease_key_equal(&fsp
->lease
->lease
.lease_key
, state
->key
)) {
481 if (!file_id_equal(&fsp
->file_id
, state
->id
)) {
485 fsp_lease_update(fsp
);
490 static void fsps_lease_update(struct smbd_server_connection
*sconn
,
491 const struct file_id
*id
,
492 const struct smb2_lease_key
*key
)
494 struct fsps_lease_update_state state
= { .id
= id
, .key
= key
};
495 files_forall(sconn
, fsps_lease_update_fn
, &state
);
498 NTSTATUS
downgrade_lease(struct smbXsrv_client
*client
,
499 uint32_t num_file_ids
,
500 const struct file_id
*ids
,
501 const struct smb2_lease_key
*key
,
502 uint32_t lease_state
)
504 struct smbd_server_connection
*sconn
= client
->sconn
;
505 const struct GUID
*client_guid
= NULL
;
506 struct share_mode_lock
*lck
;
507 const struct file_id id
= ids
[0];
508 uint32_t current_state
, breaking_to_requested
, breaking_to_required
;
510 uint16_t lease_version
, epoch
;
513 struct file_id_buf idbuf
;
515 DBG_DEBUG("Downgrading %s to %"PRIu32
"\n",
516 file_id_str_buf(id
, &idbuf
),
519 lck
= get_existing_share_mode_lock(talloc_tos(), id
);
521 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
524 client_guid
= &sconn
->client
->global
->client_guid
;
526 status
= leases_db_get(client_guid
,
531 &breaking_to_requested
,
532 &breaking_to_required
,
535 if (!NT_STATUS_IS_OK(status
)) {
536 DBG_WARNING("leases_db_get returned %s\n",
543 DBG_WARNING("Attempt to break from %"PRIu32
" to %"PRIu32
" - "
544 "but we're not in breaking state\n",
545 current_state
, lease_state
);
547 return NT_STATUS_UNSUCCESSFUL
;
551 * Can't upgrade anything: breaking_to_requested (and current_state)
552 * must be a strict bitwise superset of new_lease_state
554 if ((lease_state
& breaking_to_requested
) != lease_state
) {
555 DBG_WARNING("Attempt to upgrade from %"PRIu32
" to %"PRIu32
" "
556 "- expected %"PRIu32
"\n",
557 current_state
, lease_state
,
558 breaking_to_requested
);
560 return NT_STATUS_REQUEST_NOT_ACCEPTED
;
563 if (current_state
!= lease_state
) {
564 current_state
= lease_state
;
567 status
= NT_STATUS_OK
;
569 if ((lease_state
& ~breaking_to_required
) != 0) {
570 struct downgrade_lease_additional_state
*state
;
572 DBG_INFO("lease state %"PRIu32
" not fully broken from "
573 "%"PRIu32
" to %"PRIu32
"\n",
576 breaking_to_required
);
578 breaking_to_requested
= breaking_to_required
;
580 if (current_state
& (SMB2_LEASE_WRITE
|SMB2_LEASE_HANDLE
)) {
582 * Here we break in steps, as windows does
583 * see the breaking3 and v2_breaking3 tests.
585 breaking_to_requested
|= SMB2_LEASE_READ
;
588 state
= talloc_zero(client
,
589 struct downgrade_lease_additional_state
);
592 return NT_STATUS_NO_MEMORY
;
595 state
->im
= tevent_create_immediate(state
);
596 if (state
->im
== NULL
) {
599 return NT_STATUS_NO_MEMORY
;
602 state
->client
= client
;
603 state
->lease_key
= *key
;
604 state
->break_from
= current_state
;
605 state
->break_to
= breaking_to_requested
;
606 if (lease_version
> 1) {
607 state
->new_epoch
= epoch
;
610 if (current_state
& (SMB2_LEASE_WRITE
|SMB2_LEASE_HANDLE
)) {
612 SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED
;
615 * This is an async break without
616 * SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED
618 * we need to store NONE state in the
622 breaking_to_requested
= 0;
623 breaking_to_required
= 0;
629 set_status
= leases_db_set(
630 &sconn
->client
->global
->client_guid
,
634 breaking_to_requested
,
635 breaking_to_required
,
639 if (!NT_STATUS_IS_OK(set_status
)) {
640 DBG_DEBUG("leases_db_set failed: %s\n",
641 nt_errstr(set_status
));
647 tevent_schedule_immediate(state
->im
,
649 downgrade_lease_additional_trigger
,
652 status
= NT_STATUS_OPLOCK_BREAK_IN_PROGRESS
;
654 DBG_DEBUG("breaking from %"PRIu32
" to %"PRIu32
" - "
655 "expected %"PRIu32
"\n",
658 breaking_to_requested
);
660 breaking_to_requested
= 0;
661 breaking_to_required
= 0;
668 set_status
= leases_db_set(
673 breaking_to_requested
,
674 breaking_to_required
,
678 if (!NT_STATUS_IS_OK(set_status
)) {
679 DBG_DEBUG("leases_db_set failed: %s\n",
680 nt_errstr(set_status
));
686 DBG_DEBUG("Downgrading %s to %"PRIu32
" => %s\n",
687 file_id_str_buf(id
, &idbuf
),
691 share_mode_wakeup_waiters(id
);
693 fsps_lease_update(sconn
, &id
, key
);
697 DBG_DEBUG("Downgrading %s to %"PRIu32
" => %s\n",
698 file_id_str_buf(id
, &idbuf
),
703 * Dynamic share case. Ensure other opens are copies.
704 * This will only be breaking to NONE.
707 for (i
= 1; i
< num_file_ids
; i
++) {
708 lck
= get_existing_share_mode_lock(talloc_tos(), ids
[i
]);
710 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
713 fsps_lease_update(sconn
, &ids
[i
], key
);
715 DBG_DEBUG("Downgrading %s to %"PRIu32
" => %s\n",
716 file_id_str_buf(ids
[i
], &idbuf
),
726 #define SMB1_BREAK_MESSAGE_LENGTH (smb_size + 8*2)
728 /****************************************************************************
729 Function to do the waiting before sending a local break.
730 ****************************************************************************/
732 static void wait_before_sending_break(void)
734 long wait_time
= (long)lp_oplock_break_wait_time();
737 smb_msleep(wait_time
);
741 /****************************************************************************
742 Ensure that we have a valid oplock.
743 ****************************************************************************/
745 static files_struct
*initial_break_processing(
746 struct smbd_server_connection
*sconn
, struct file_id id
,
747 unsigned long file_id
)
749 files_struct
*fsp
= NULL
;
750 struct file_id_buf idbuf
;
752 DBG_NOTICE("called for %s/%u\n"
753 "Current oplocks_open (exclusive = %d, levelII = %d)\n",
754 file_id_str_buf(id
, &idbuf
),
756 sconn
->oplocks
.exclusive_open
,
757 sconn
->oplocks
.level_II_open
);
760 * We need to search the file open table for the
761 * entry containing this dev and inode, and ensure
762 * we have an oplock on it.
765 fsp
= file_find_dif(sconn
, id
, file_id
);
768 /* The file could have been closed in the meantime - return success. */
769 DBG_NOTICE("cannot find open file "
770 "with file_id %s gen_id = %lu, allowing break to "
772 file_id_str_buf(id
, &idbuf
),
777 /* Ensure we have an oplock on the file */
780 * There is a potential race condition in that an oplock could
781 * have been broken due to another udp request, and yet there are
782 * still oplock break messages being sent in the udp message
783 * queue for this file. So return true if we don't have an oplock,
784 * as we may have just freed it.
787 if(fsp
->oplock_type
== NO_OPLOCK
) {
788 DBG_NOTICE("file %s (file_id = %s gen_id = %"PRIu64
") "
790 "Allowing break to succeed regardless.\n",
792 file_id_str_buf(id
, &idbuf
),
793 fh_get_gen_id(fsp
->fh
));
800 static void oplock_timeout_handler(struct tevent_context
*ctx
,
801 struct tevent_timer
*te
,
805 files_struct
*fsp
= (files_struct
*)private_data
;
807 SMB_ASSERT(fsp
->sent_oplock_break
!= NO_BREAK_SENT
);
809 /* Remove the timed event handler. */
810 TALLOC_FREE(fsp
->oplock_timeout
);
811 DEBUG(0, ("Oplock break failed for file %s -- replying anyway\n",
816 /*******************************************************************
817 Add a timeout handler waiting for the client reply.
818 *******************************************************************/
820 static void add_oplock_timeout_handler(files_struct
*fsp
)
822 if (fsp
->oplock_timeout
!= NULL
) {
823 DEBUG(0, ("Logic problem -- have an oplock event hanging "
827 fsp
->oplock_timeout
=
828 tevent_add_timer(fsp
->conn
->sconn
->ev_ctx
, fsp
,
829 timeval_current_ofs(OPLOCK_BREAK_TIMEOUT
, 0),
830 oplock_timeout_handler
, fsp
);
832 if (fsp
->oplock_timeout
== NULL
) {
833 DEBUG(0, ("Could not add oplock timeout handler\n"));
837 /*******************************************************************
838 This handles the generic oplock break message from another smbd.
839 *******************************************************************/
841 static void process_oplock_break_message(struct messaging_context
*msg_ctx
,
844 struct server_id src
,
847 struct oplock_break_message msg
;
848 enum ndr_err_code ndr_err
;
851 struct smbd_server_connection
*sconn
=
852 talloc_get_type_abort(private_data
,
853 struct smbd_server_connection
);
854 struct server_id self
= messaging_server_id(sconn
->msg_ctx
);
855 struct kernel_oplocks
*koplocks
= sconn
->oplocks
.kernel_ops
;
858 bool break_needed
= true;
860 smb_vfs_assert_allowed();
862 ndr_err
= ndr_pull_struct_blob_all_noalloc(
863 data
, &msg
, (ndr_pull_flags_fn_t
)ndr_pull_oplock_break_message
);
864 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
865 DBG_DEBUG("ndr_pull_oplock_break_message failed: %s\n",
866 ndr_errstr(ndr_err
));
869 if (DEBUGLEVEL
>= 10) {
870 struct server_id_buf buf
;
871 DBG_DEBUG("Got break message from %s\n",
872 server_id_str_buf(src
, &buf
));
873 NDR_PRINT_DEBUG(oplock_break_message
, &msg
);
876 break_to
= msg
.break_to
;
877 fsp
= initial_break_processing(sconn
, msg
.id
, msg
.share_file_id
);
880 /* We hit a race here. Break messages are sent, and before we
881 * get to process this message, we have closed the file. */
882 DEBUG(3, ("Did not find fsp\n"));
886 break_from
= fsp_lease_type(fsp
);
888 if (fsp
->oplock_type
!= LEASE_OPLOCK
) {
889 if (fsp
->sent_oplock_break
!= NO_BREAK_SENT
) {
891 * Nothing to do anymore
893 DEBUG(10, ("fsp->sent_oplock_break = %d\n",
894 fsp
->sent_oplock_break
));
899 if (!(global_client_caps
& CAP_LEVEL_II_OPLOCKS
)) {
900 DEBUG(10, ("client_caps without level2 oplocks\n"));
901 break_to
&= ~SMB2_LEASE_READ
;
904 use_kernel
= lp_kernel_oplocks(SNUM(fsp
->conn
)) &&
907 DEBUG(10, ("Kernel oplocks don't allow level2\n"));
908 break_to
&= ~SMB2_LEASE_READ
;
911 if (!lp_level2_oplocks(SNUM(fsp
->conn
))) {
912 DEBUG(10, ("no level2 oplocks by config\n"));
913 break_to
&= ~SMB2_LEASE_READ
;
916 if (fsp
->oplock_type
== LEASE_OPLOCK
) {
917 const struct GUID
*client_guid
= fsp_client_guid(fsp
);
918 struct share_mode_lock
*lck
;
919 uint32_t current_state
;
920 uint32_t breaking_to_requested
, breaking_to_required
;
922 uint16_t lease_version
, epoch
;
925 lck
= get_existing_share_mode_lock(
926 talloc_tos(), fsp
->file_id
);
929 * We hit a race here. Break messages are sent, and
930 * before we get to process this message, we have closed
933 DEBUG(3, ("Did not find share_mode\n"));
937 status
= leases_db_get(client_guid
,
938 &fsp
->lease
->lease
.lease_key
,
942 &breaking_to_requested
,
943 &breaking_to_required
,
946 if (!NT_STATUS_IS_OK(status
)) {
947 DBG_WARNING("leases_db_get returned %s\n",
953 break_from
= current_state
;
954 break_to
&= current_state
;
957 break_to
&= breaking_to_required
;
958 if (breaking_to_required
!= break_to
) {
960 * Note we don't increment the epoch
961 * here, which might be a bug in
964 breaking_to_required
= break_to
;
966 break_needed
= false;
967 } else if (current_state
== break_to
) {
968 break_needed
= false;
969 } else if (current_state
== SMB2_LEASE_READ
) {
970 current_state
= SMB2_LEASE_NONE
;
971 /* Need to increment the epoch */
975 breaking_to_required
= break_to
;
976 breaking_to_requested
= break_to
;
977 /* Need to increment the epoch */
984 set_status
= leases_db_set(
986 &fsp
->lease
->lease
.lease_key
,
989 breaking_to_requested
,
990 breaking_to_required
,
994 if (!NT_STATUS_IS_OK(set_status
)) {
995 DBG_DEBUG("leases_db_set failed: %s\n",
996 nt_errstr(set_status
));
1001 /* Ensure we're in sync with current lease state. */
1002 fsp_lease_update(fsp
);
1007 if (!break_needed
) {
1008 DEBUG(10,("%s: skip break\n", __func__
));
1012 if (break_from
== SMB2_LEASE_NONE
) {
1013 struct file_id_buf idbuf
;
1014 DBG_NOTICE("Already downgraded oplock to none on %s: %s\n",
1015 file_id_str_buf(fsp
->file_id
, &idbuf
),
1020 DEBUG(10, ("break_from=%u, break_to=%u\n",
1021 (unsigned)break_from
, (unsigned)break_to
));
1023 if (break_from
== break_to
) {
1024 struct file_id_buf idbuf
;
1025 DBG_NOTICE("Already downgraded oplock to %u on %s: %s\n",
1027 file_id_str_buf(fsp
->file_id
, &idbuf
),
1032 /* Need to wait before sending a break
1033 message if we sent ourselves this message. */
1034 if (server_id_equal(&self
, &src
)) {
1035 wait_before_sending_break();
1038 #if defined(WITH_SMB1SERVER)
1039 if (conn_using_smb2(sconn
)) {
1041 send_break_message_smb2(fsp
, break_from
, break_to
);
1042 #if defined(WITH_SMB1SERVER)
1044 send_break_message_smb1(fsp
, (break_to
& SMB2_LEASE_READ
) ?
1045 OPLOCKLEVEL_II
: OPLOCKLEVEL_NONE
);
1049 if ((break_from
== SMB2_LEASE_READ
) &&
1050 (break_to
== SMB2_LEASE_NONE
)) {
1052 * This is an async break without a reply and thus no timeout
1054 * leases are handled above.
1056 if (fsp
->oplock_type
!= LEASE_OPLOCK
) {
1061 if (fsp
->oplock_type
== LEASE_OPLOCK
) {
1065 fsp
->sent_oplock_break
= (break_to
& SMB2_LEASE_READ
) ?
1066 LEVEL_II_BREAK_SENT
:BREAK_TO_NONE_SENT
;
1068 add_oplock_timeout_handler(fsp
);
1071 /*******************************************************************
1072 This handles the kernel oplock break message.
1073 *******************************************************************/
1075 static void process_kernel_oplock_break(struct messaging_context
*msg_ctx
,
1078 struct server_id src
,
1081 struct oplock_break_message msg
;
1082 enum ndr_err_code ndr_err
;
1083 struct file_id_buf idbuf
;
1085 struct smbd_server_connection
*sconn
=
1086 talloc_get_type_abort(private_data
,
1087 struct smbd_server_connection
);
1088 struct server_id_buf tmp
;
1090 ndr_err
= ndr_pull_struct_blob_all_noalloc(
1093 (ndr_pull_flags_fn_t
)ndr_pull_oplock_break_message
);
1094 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1095 DBG_DEBUG("ndr_pull_oplock_break_message failed: %s\n",
1096 ndr_errstr(ndr_err
));
1100 DBG_DEBUG("Got kernel oplock break message from pid %s: %s/%u\n",
1101 server_id_str_buf(src
, &tmp
),
1102 file_id_str_buf(msg
.id
, &idbuf
),
1103 (unsigned int)msg
.share_file_id
);
1105 fsp
= initial_break_processing(sconn
, msg
.id
, msg
.share_file_id
);
1108 DEBUG(3, ("Got a kernel oplock break message for a file "
1109 "I don't know about\n"));
1113 if (fsp
->sent_oplock_break
!= NO_BREAK_SENT
) {
1114 /* This is ok, kernel oplocks come in completely async */
1115 DEBUG(3, ("Got a kernel oplock request while waiting for a "
1120 #if defined(WITH_SMB1SERVER)
1121 if (conn_using_smb2(sconn
)) {
1123 send_break_message_smb2(fsp
, 0, OPLOCKLEVEL_NONE
);
1124 #if defined(WITH_SMB1SERVER)
1126 send_break_message_smb1(fsp
, OPLOCKLEVEL_NONE
);
1130 fsp
->sent_oplock_break
= BREAK_TO_NONE_SENT
;
1132 add_oplock_timeout_handler(fsp
);
1135 static void send_break_to_none(struct messaging_context
*msg_ctx
,
1136 const struct file_id
*id
,
1137 const struct share_mode_entry
*e
)
1140 status
= send_break_message(msg_ctx
, id
, e
, OPLOCK_NONE
);
1141 if (!NT_STATUS_IS_OK(status
)) {
1142 DBG_DEBUG("send_break_message failed: %s\n",
1146 struct break_to_none_state
{
1147 struct smbd_server_connection
*sconn
;
1149 struct smb2_lease_key lease_key
;
1150 struct GUID client_guid
;
1151 size_t num_read_leases
;
1152 uint32_t total_lease_types
;
1155 static bool do_break_lease_to_none(struct share_mode_entry
*e
,
1158 struct break_to_none_state
*state
= private_data
;
1159 uint32_t current_state
= 0;
1163 DBG_DEBUG("lease_key=%"PRIu64
"/%"PRIu64
"\n",
1164 e
->lease_key
.data
[0],
1165 e
->lease_key
.data
[1]);
1167 status
= leases_db_get(&e
->client_guid
,
1171 NULL
, /* breaking */
1172 NULL
, /* breaking_to_requested */
1173 NULL
, /* breaking_to_required */
1174 NULL
, /* lease_version */
1176 if (!NT_STATUS_IS_OK(status
)) {
1177 DBG_WARNING("leases_db_get failed: %s\n",
1182 state
->total_lease_types
|= current_state
;
1184 if ((current_state
& SMB2_LEASE_READ
) == 0) {
1188 state
->num_read_leases
+= 1;
1190 our_own
= smb2_lease_equal(&state
->client_guid
,
1195 DEBUG(10, ("Don't break our own lease\n"));
1199 DBG_DEBUG("Breaking %"PRIu64
"/%"PRIu64
" to none\n",
1200 e
->lease_key
.data
[0],
1201 e
->lease_key
.data
[1]);
1203 send_break_to_none(state
->sconn
->msg_ctx
, &state
->id
, e
);
1208 static bool do_break_oplock_to_none(struct share_mode_entry
*e
,
1212 struct break_to_none_state
*state
= private_data
;
1214 if (e
->op_type
== LEASE_OPLOCK
) {
1216 * Already being taken care of
1222 * As there could have been multiple writes waiting at the
1223 * lock_share_entry gate we may not be the first to
1224 * enter. Hence the state of the op_types in the share mode
1225 * entries may be partly NO_OPLOCK and partly LEVEL_II
1226 * oplock. It will do no harm to re-send break messages to
1227 * those smbd's that are still waiting their turn to remove
1228 * their LEVEL_II state, and also no harm to ignore existing
1229 * NO_OPLOCK states. JRA.
1232 DBG_DEBUG("e->op_type == %d\n", e
->op_type
);
1234 state
->total_lease_types
|= map_oplock_to_lease_type(e
->op_type
);
1236 if (e
->op_type
== NO_OPLOCK
) {
1240 state
->num_read_leases
+= 1;
1243 SMB_ASSERT(!EXCLUSIVE_OPLOCK_TYPE(e
->op_type
));
1245 send_break_to_none(state
->sconn
->msg_ctx
, &state
->id
, e
);
1250 struct dirlease_break_state
{
1251 struct smbd_server_connection
*sconn
;
1252 struct file_id file_id
;
1253 struct smb2_lease_key parent_lease_key
;
1254 uint32_t total_lease_types
;
1257 static bool do_dirlease_break_to_none(struct share_mode_entry
*e
,
1260 struct dirlease_break_state
*state
= private_data
;
1261 uint32_t current_state
= 0;
1264 DBG_DEBUG("lease_key=%"PRIu64
"/%"PRIu64
"\n",
1265 e
->lease_key
.data
[0],
1266 e
->lease_key
.data
[1]);
1268 status
= leases_db_get(&e
->client_guid
,
1272 NULL
, /* breaking */
1273 NULL
, /* breaking_to_requested */
1274 NULL
, /* breaking_to_required */
1275 NULL
, /* lease_version */
1277 if (!NT_STATUS_IS_OK(status
)) {
1278 DBG_WARNING("leases_db_get failed: %s\n",
1283 if (share_entry_stale_pid(e
)) {
1287 state
->total_lease_types
|= current_state
;
1289 if (smb2_lease_key_equal(&state
->parent_lease_key
, &e
->lease_key
)) {
1293 if ((current_state
& (SMB2_LEASE_READ
| SMB2_LEASE_HANDLE
)) == 0) {
1297 DBG_DEBUG("Breaking %"PRIu64
"/%"PRIu64
" to none\n",
1298 e
->lease_key
.data
[0],
1299 e
->lease_key
.data
[1]);
1301 send_break_to_none(state
->sconn
->msg_ctx
, &state
->file_id
, e
);
1305 void contend_dirleases(struct connection_struct
*conn
,
1306 const struct smb_filename
*smb_fname
,
1307 const struct smb2_lease
*lease
)
1309 struct dirlease_break_state state
= {
1310 .sconn
= conn
->sconn
,
1312 struct share_mode_lock
*lck
= NULL
;
1313 struct smb_filename
*parent_fname
= NULL
;
1314 uint32_t access_mask
, share_mode
;
1319 if (lease
!= NULL
) {
1320 DBG_DEBUG("Parent leasekey %"PRIx64
"/%"PRIx64
"\n",
1321 lease
->parent_lease_key
.data
[0],
1322 lease
->parent_lease_key
.data
[1]);
1323 state
.parent_lease_key
= lease
->parent_lease_key
;
1326 status
= SMB_VFS_PARENT_PATHNAME(conn
,
1331 if (!NT_STATUS_IS_OK(status
)) {
1332 DBG_ERR("parent_smb_fname() for [%s] failed: %s\n",
1333 smb_fname_str_dbg(smb_fname
), strerror(errno
));
1337 ret
= SMB_VFS_STAT(conn
, parent_fname
);
1339 DBG_ERR("Failed to stat [%s]: %s\n",
1340 smb_fname_str_dbg(parent_fname
), strerror(errno
));
1341 TALLOC_FREE(parent_fname
);
1345 state
.file_id
= vfs_file_id_from_sbuf(conn
, &parent_fname
->st
);
1346 TALLOC_FREE(parent_fname
);
1348 lck
= get_existing_share_mode_lock(talloc_tos(), state
.file_id
);
1351 * No sharemode db entry -> no leases.
1356 ok
= share_mode_forall_leases(lck
, do_dirlease_break_to_none
, &state
);
1358 DBG_WARNING("share_mode_forall_leases failed\n");
1362 * While we're at it, update lease type.
1364 share_mode_flags_get(lck
,
1368 share_mode_flags_set(lck
,
1371 state
.total_lease_types
,
1377 /****************************************************************************
1378 This function is called on any file modification or lock request. If a file
1379 is level 2 oplocked then it must tell all other level 2 holders to break to
1381 ****************************************************************************/
1383 static void contend_level2_oplocks_begin_default(files_struct
*fsp
,
1384 enum level2_contention_type type
)
1386 struct break_to_none_state state
= {
1387 .sconn
= fsp
->conn
->sconn
, .id
= fsp
->file_id
,
1389 struct share_mode_lock
*lck
= NULL
;
1390 uint32_t fsp_lease
= fsp_lease_type(fsp
);
1391 bool ok
, has_read_lease
;
1394 * If this file is level II oplocked then we need
1395 * to grab the shared memory lock and inform all
1396 * other files with a level II lock that they need
1397 * to flush their read caches. We keep the lock over
1398 * the shared memory area whilst doing this.
1401 if (fsp_lease
& SMB2_LEASE_WRITE
) {
1403 * There can't be any level2 oplocks, we're alone.
1408 has_read_lease
= file_has_read_lease(fsp
);
1409 if (!has_read_lease
) {
1410 DEBUG(10, ("No read oplocks around\n"));
1414 if (fsp
->oplock_type
== LEASE_OPLOCK
) {
1415 state
.client_guid
= *fsp_client_guid(fsp
);
1416 state
.lease_key
= fsp
->lease
->lease
.lease_key
;
1417 DEBUG(10, ("Breaking through lease key %"PRIu64
"/%"PRIu64
"\n",
1418 state
.lease_key
.data
[0],
1419 state
.lease_key
.data
[1]));
1422 lck
= get_existing_share_mode_lock(talloc_tos(), fsp
->file_id
);
1424 struct file_id_buf idbuf
;
1425 DBG_WARNING("failed to lock share mode entry for file %s.\n",
1426 file_id_str_buf(state
.id
, &idbuf
));
1431 * Walk leases and oplocks separately: We have to send one break per
1432 * lease. If we have multiple share_mode_entry having a common lease,
1433 * we would break the lease twice if we don't walk the leases list
1437 ok
= share_mode_forall_leases(lck
, do_break_lease_to_none
, &state
);
1439 DBG_WARNING("share_mode_forall_leases failed\n");
1442 ok
= share_mode_forall_entries(lck
, do_break_oplock_to_none
, &state
);
1444 DBG_WARNING("share_mode_forall_entries failed\n");
1449 * Lazy update here. It might be that all leases
1450 * have gone in the meantime.
1452 uint32_t acc
, sh
, ls
;
1453 share_mode_flags_get(lck
, &acc
, &sh
, &ls
);
1454 ls
= state
.total_lease_types
;
1455 share_mode_flags_set(lck
, acc
, sh
, ls
, NULL
);
1461 void smbd_contend_level2_oplocks_begin(files_struct
*fsp
,
1462 enum level2_contention_type type
)
1464 contend_level2_oplocks_begin_default(fsp
, type
);
1467 void smbd_contend_level2_oplocks_end(files_struct
*fsp
,
1468 enum level2_contention_type type
)
1473 /****************************************************************************
1474 Setup oplocks for this process.
1475 ****************************************************************************/
1477 bool init_oplocks(struct smbd_server_connection
*sconn
)
1479 DEBUG(3,("init_oplocks: initializing messages.\n"));
1481 messaging_register(sconn
->msg_ctx
, sconn
, MSG_SMB_BREAK_REQUEST
,
1482 process_oplock_break_message
);
1483 messaging_register(sconn
->msg_ctx
, sconn
, MSG_SMB_KERNEL_BREAK
,
1484 process_kernel_oplock_break
);
1488 void init_kernel_oplocks(struct smbd_server_connection
*sconn
)
1490 struct kernel_oplocks
*koplocks
= sconn
->oplocks
.kernel_ops
;
1492 /* only initialize once */
1493 if (koplocks
== NULL
) {
1494 #ifdef HAVE_KERNEL_OPLOCKS_LINUX
1495 koplocks
= linux_init_kernel_oplocks(sconn
);
1497 sconn
->oplocks
.kernel_ops
= koplocks
;
1501 struct pending_hlease_break
{
1502 struct pending_hlease_break
*prev
;
1503 struct pending_hlease_break
*next
;
1504 struct server_id pid
;
1506 uint64_t share_file_id
;
1510 struct delay_for_handle_lease_break_state
{
1511 TALLOC_CTX
*mem_ctx
;
1512 struct tevent_context
*ev
;
1513 struct timeval timeout
;
1515 bool recursive_h_leases_break
;
1516 struct files_struct
*fsp
;
1517 struct share_mode_lock
*lck
;
1519 struct pending_hlease_break
*breaks
;
1520 struct file_id break_id
;
1522 uint32_t num_watches
;
1525 static void delay_for_handle_lease_break_cleanup(struct tevent_req
*req
,
1526 enum tevent_req_state req_state
)
1528 struct delay_for_handle_lease_break_state
*state
=
1529 tevent_req_data(req
, struct delay_for_handle_lease_break_state
);
1531 if (req_state
== TEVENT_REQ_DONE
) {
1534 TALLOC_FREE(state
->lck
);
1537 static void delay_for_handle_lease_break_check(struct tevent_req
*req
);
1539 struct tevent_req
*delay_for_handle_lease_break_send(
1540 TALLOC_CTX
*mem_ctx
,
1541 struct tevent_context
*ev
,
1542 struct timeval timeout
,
1543 struct files_struct
*fsp
,
1545 struct share_mode_lock
**lck
)
1547 struct tevent_req
*req
= NULL
;
1548 struct delay_for_handle_lease_break_state
*state
= NULL
;
1550 req
= tevent_req_create(
1551 mem_ctx
, &state
, struct delay_for_handle_lease_break_state
);
1556 tevent_req_set_cleanup_fn(req
, delay_for_handle_lease_break_cleanup
);
1558 *state
= (struct delay_for_handle_lease_break_state
) {
1562 .recursive
= recursive
,
1563 .recursive_h_leases_break
= recursive
,
1565 .lck
= talloc_move(state
, lck
),
1568 delay_for_handle_lease_break_check(req
);
1569 if (!tevent_req_is_in_progress(req
)) {
1570 return tevent_req_post(req
, ev
);
1573 /* Ensure we can't be closed in flight. */
1574 if (!aio_add_req_to_fsp(fsp
, req
)) {
1575 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1576 return tevent_req_post(req
, ev
);
1582 static bool delay_for_handle_lease_break_fn(struct share_mode_entry
*e
,
1585 struct delay_for_handle_lease_break_state
*state
= talloc_get_type_abort(
1586 private_data
, struct delay_for_handle_lease_break_state
);
1587 struct files_struct
*fsp
= state
->fsp
;
1588 struct server_id_buf buf
;
1589 uint32_t lease_type
;
1592 if (fsp
->lease
!= NULL
) {
1593 ours
= smb2_lease_equal(fsp_client_guid(fsp
),
1594 &fsp
->lease
->lease
.lease_key
,
1602 lease_type
= get_lease_type(e
, fsp
->file_id
);
1603 if ((lease_type
& SMB2_LEASE_HANDLE
) == 0) {
1607 stale
= share_entry_stale_pid(e
);
1612 state
->delay
= true;
1614 DBG_DEBUG("Breaking h-lease on [%s] pid [%s]\n",
1616 server_id_str_buf(e
->pid
, &buf
));
1618 send_break_message(fsp
->conn
->sconn
->msg_ctx
,
1621 lease_type
& ~SMB2_LEASE_HANDLE
);
1626 static void delay_for_handle_lease_break_fsp_done(struct tevent_req
*subreq
);
1628 static void delay_for_handle_lease_break_fsp_check(struct tevent_req
*req
)
1630 struct delay_for_handle_lease_break_state
*state
= tevent_req_data(
1631 req
, struct delay_for_handle_lease_break_state
);
1632 struct tevent_req
*subreq
= NULL
;
1635 DBG_DEBUG("fsp [%s]\n", fsp_str_dbg(state
->fsp
));
1637 ok
= share_mode_forall_leases(state
->lck
,
1638 delay_for_handle_lease_break_fn
,
1641 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
1645 DBG_DEBUG("Delaying fsp [%s]\n", fsp_str_dbg(state
->fsp
));
1647 subreq
= share_mode_watch_send(state
,
1649 &state
->fsp
->file_id
,
1650 (struct server_id
){0});
1651 if (tevent_req_nomem(subreq
, req
)) {
1655 tevent_req_set_callback(subreq
,
1656 delay_for_handle_lease_break_fsp_done
,
1659 if (!tevent_req_set_endtime(subreq
, state
->ev
, state
->timeout
)) {
1660 tevent_req_nterror(req
, NT_STATUS_NO_MEMORY
);
1667 static void delay_for_handle_lease_break_fsp_done(struct tevent_req
*subreq
)
1669 struct tevent_req
*req
= tevent_req_callback_data(
1670 subreq
, struct tevent_req
);
1671 struct delay_for_handle_lease_break_state
*state
= tevent_req_data(
1672 req
, struct delay_for_handle_lease_break_state
);
1675 DBG_DEBUG("Watch returned for fsp [%s]\n", fsp_str_dbg(state
->fsp
));
1677 status
= share_mode_watch_recv(subreq
, NULL
, NULL
);
1678 TALLOC_FREE(subreq
);
1679 if (!NT_STATUS_IS_OK(status
)) {
1680 DBG_ERR("share_mode_watch_recv returned %s\n",
1682 if (NT_STATUS_EQUAL(status
, NT_STATUS_IO_TIMEOUT
)) {
1684 * The sharemode-watch timer fired because a client
1685 * didn't respond to the lease break.
1687 status
= NT_STATUS_ACCESS_DENIED
;
1689 tevent_req_nterror(req
, status
);
1693 state
->lck
= get_existing_share_mode_lock(state
, state
->fsp
->file_id
);
1694 if (state
->lck
== NULL
) {
1695 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1700 * This could potentially end up looping for some if a client
1701 * aggressively reaquires H-leases on the file, but we have a
1702 * timeout on the tevent req as upper bound.
1704 delay_for_handle_lease_break_check(req
);
1707 static int delay_for_handle_lease_break_below_fn(struct share_mode_data
*d
,
1708 struct share_mode_entry
*e
,
1711 struct tevent_req
*req
= talloc_get_type_abort(
1712 private_data
, struct tevent_req
);
1713 struct delay_for_handle_lease_break_state
*state
= tevent_req_data(
1714 req
, struct delay_for_handle_lease_break_state
);
1715 struct pending_hlease_break
*b
= NULL
;
1716 struct file_id_buf fid_buf
;
1717 const char *fid_bufp
= NULL
;
1718 struct server_id_buf sid_buf
;
1722 if (DEBUGLVL(DBGLVL_DEBUG
)) {
1723 fid_bufp
= file_id_str_buf(d
->id
, &fid_buf
);
1726 DBG_DEBUG("Breaking [%s] file-id [%s]\n",
1727 state
->recursive_h_leases_break
? "yes" : "no",
1730 stale
= share_entry_stale_pid(e
);
1735 if (state
->recursive_h_leases_break
) {
1736 lease
= get_lease_type(e
, d
->id
);
1739 if ((lease
& SMB2_LEASE_HANDLE
) == 0) {
1740 if (e
->flags
& SHARE_MODE_FLAG_POSIX_OPEN
) {
1741 DBG_DEBUG("POSIX open file-id [%s]\n", fid_bufp
);
1742 /* Ignore POSIX opens. */
1745 state
->found_open
= true;
1746 DBG_DEBUG("Unbreakable open [%s]\n", fid_bufp
);
1747 if (!state
->recursive_h_leases_break
) {
1748 /* Second round, stop */
1749 DBG_DEBUG("Stopping\n");
1754 lease
&= ~SMB2_LEASE_HANDLE
;
1756 b
= talloc_zero(state
, struct pending_hlease_break
);
1758 DBG_ERR("talloc_zero failed\n");
1762 b
->break_to
= lease
;
1764 b
->share_file_id
= e
->share_file_id
;
1766 DLIST_ADD_END(state
->breaks
, b
);
1768 DBG_DEBUG("Queued h-lease break on file-id [%s] pid [%s]\n",
1770 server_id_str_buf(b
->pid
, &sid_buf
));
1772 state
->delay
= true;
1776 static void delay_for_handle_lease_break_below_send_breaks(
1777 struct tevent_req
*req
);
1779 static void delay_for_handle_lease_break_below_check(struct tevent_req
*req
)
1781 struct delay_for_handle_lease_break_state
*state
= tevent_req_data(
1782 req
, struct delay_for_handle_lease_break_state
);
1785 DBG_DEBUG("fsp [%s]\n", fsp_str_dbg(state
->fsp
));
1787 if (!state
->recursive
) {
1790 if (!S_ISDIR(state
->fsp
->fsp_name
->st
.st_ex_mode
)) {
1793 if (!lp_strict_rename(SNUM(state
->fsp
->conn
))) {
1795 * This will also not do h-lease breaks
1797 state
->found_open
= file_find_subpath(state
->fsp
);
1801 ret
= opens_below_forall(state
->fsp
->conn
,
1802 state
->fsp
->fsp_name
,
1803 delay_for_handle_lease_break_below_fn
,
1806 tevent_req_nterror(req
, NT_STATUS_INTERNAL_ERROR
);
1809 if (!state
->delay
) {
1810 DBG_DEBUG("No delay for [%s]\n", fsp_str_dbg(state
->fsp
));
1814 * Ignore any opens without h-lease in the first round of listing opens
1816 state
->found_open
= false;
1817 delay_for_handle_lease_break_below_send_breaks(req
);
1821 static void delay_for_handle_lease_break_below_done(struct tevent_req
*subreq
);
1823 static void delay_for_handle_lease_break_below_send_breaks(
1824 struct tevent_req
*req
)
1826 struct delay_for_handle_lease_break_state
*state
= tevent_req_data(
1827 req
, struct delay_for_handle_lease_break_state
);
1828 struct messaging_context
*msg_ctx
= state
->fsp
->conn
->sconn
->msg_ctx
;
1829 struct pending_hlease_break
*b
= NULL
;
1830 struct file_id last_file_id
;
1831 struct tevent_req
*subreq
= NULL
;
1834 DBG_DEBUG("Sending breaks\n");
1836 if (state
->breaks
== NULL
) {
1840 for (b
= state
->breaks
, last_file_id
= b
->id
; b
!= NULL
; b
= b
->next
) {
1841 struct share_mode_entry e
;
1842 struct file_id_buf fid_buf
;
1843 struct server_id_buf sid_buf
;
1845 if (!file_id_equal(&b
->id
, &last_file_id
)) {
1849 e
= (struct share_mode_entry
) {
1850 .share_file_id
= b
->share_file_id
,
1854 status
= send_break_message(msg_ctx
,
1858 if (tevent_req_nterror(req
, status
)) {
1859 DBG_ERR("send_break_message failed\n");
1863 DLIST_REMOVE(state
->breaks
, b
);
1865 DBG_DEBUG("Sent h-lease break on file-id [%s] pid [%s]\n",
1866 file_id_str_buf(b
->id
, &fid_buf
),
1867 server_id_str_buf(b
->pid
, &sid_buf
));
1869 subreq
= share_mode_watch_send(state
,
1872 (struct server_id
){0});
1873 if (tevent_req_nomem(subreq
, req
)) {
1876 tevent_req_set_callback(subreq
,
1877 delay_for_handle_lease_break_below_done
,
1879 if (!tevent_req_set_endtime(subreq
, state
->ev
, state
->timeout
)) {
1880 tevent_req_oom(req
);
1883 state
->num_watches
++;
1886 state
->break_id
= last_file_id
;
1887 DBG_DEBUG("Stopped sending breaks\n");
1890 static void delay_for_handle_lease_break_below_done(struct tevent_req
*subreq
)
1892 struct tevent_req
*req
= tevent_req_callback_data(
1893 subreq
, struct tevent_req
);
1894 struct delay_for_handle_lease_break_state
*state
= tevent_req_data(
1895 req
, struct delay_for_handle_lease_break_state
);
1896 struct share_mode_lock
*lck
= NULL
;
1897 struct file_id_buf fid_buf
;
1898 const char *fid_bufp
= NULL
;
1901 if (DEBUGLVL(DBGLVL_DEBUG
)) {
1902 fid_bufp
= file_id_str_buf(state
->break_id
, &fid_buf
);
1905 DBG_DEBUG("Watch finished for file-id [%s]\n", fid_bufp
);
1907 status
= share_mode_watch_recv(subreq
, NULL
, NULL
);
1908 TALLOC_FREE(subreq
);
1909 if (!NT_STATUS_IS_OK(status
)) {
1910 DBG_ERR("share_mode_watch_recv returned %s\n",
1912 if (NT_STATUS_EQUAL(status
, NT_STATUS_IO_TIMEOUT
)) {
1914 * The sharemode-watch timer fired because a client
1915 * didn't respond to the lease break.
1917 status
= NT_STATUS_ACCESS_DENIED
;
1919 tevent_req_nterror(req
, status
);
1923 state
->num_watches
--;
1924 if (state
->num_watches
> 0) {
1929 * If the client just sends a break ACK, but doesn't close the file,
1930 * Windows server directly returns NT_STATUS_ACCESS_DENIED.
1933 DBG_DEBUG("Checking for remaining opens on [%s]\n", fid_bufp
);
1935 lck
= fetch_share_mode_unlocked(state
, state
->break_id
);
1937 bool has_nonposix_open
;
1939 has_nonposix_open
= has_nonposix_opens(lck
);
1941 if (has_nonposix_open
) {
1942 DBG_DEBUG("Found open\n");
1943 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1948 if (state
->breaks
!= NULL
) {
1949 delay_for_handle_lease_break_below_send_breaks(req
);
1954 * We've sent lease breaks recursively once, don't do that again. So we
1955 * do a recursive scan a second time to check for new opens and if there
1956 * are any, with or without h-leases, just fail with
1957 * NT_STATUS_ACCESS_DENIED.
1959 state
->recursive_h_leases_break
= false;
1961 state
->lck
= get_existing_share_mode_lock(state
, state
->fsp
->file_id
);
1962 if (state
->lck
== NULL
) {
1963 tevent_req_nterror(req
, NT_STATUS_UNSUCCESSFUL
);
1967 delay_for_handle_lease_break_check(req
);
1970 static void delay_for_handle_lease_break_check(struct tevent_req
*req
)
1972 struct delay_for_handle_lease_break_state
*state
= tevent_req_data(
1973 req
, struct delay_for_handle_lease_break_state
);
1975 state
->delay
= false;
1977 DBG_DEBUG("fsp [%s]\n", fsp_str_dbg(state
->fsp
));
1979 delay_for_handle_lease_break_fsp_check(req
);
1980 if (!tevent_req_is_in_progress(req
)) {
1984 DBG_DEBUG("Delaying fsp [%s]\n", fsp_str_dbg(state
->fsp
));
1985 TALLOC_FREE(state
->lck
);
1989 delay_for_handle_lease_break_below_check(req
);
1990 if (!tevent_req_is_in_progress(req
)) {
1993 if (state
->found_open
) {
1994 tevent_req_nterror(req
, NT_STATUS_ACCESS_DENIED
);
1998 TALLOC_FREE(state
->lck
);
2002 tevent_req_done(req
);
2005 NTSTATUS
delay_for_handle_lease_break_recv(struct tevent_req
*req
,
2006 TALLOC_CTX
*mem_ctx
,
2007 struct share_mode_lock
**lck
)
2011 struct delay_for_handle_lease_break_state
*state
=
2012 tevent_req_data(req
, struct delay_for_handle_lease_break_state
);
2014 if (tevent_req_is_nterror(req
, &status
)) {
2015 tevent_req_received(req
);
2019 *lck
= talloc_move(mem_ctx
, &state
->lck
);
2020 tevent_req_received(req
);
2021 return NT_STATUS_OK
;
2024 const struct smb2_lease
*fsp_get_smb2_lease(const struct files_struct
*fsp
)
2029 if (fsp
->lease
== NULL
) {
2032 return &fsp
->lease
->lease
;