[SCM] Samba Shared Repository - branch master updated
Ralph Böhme
slow at samba.org
Wed Apr 2 19:04:01 UTC 2025
The branch, master has been updated
via 0e4cab78cdf s3/locking: add a comment to share_mode_data_ltdb_store()
via b096214794a s3/locking: add a comment to put_share_mode_lock_internal()
via c826af38b09 s3/locking: simplify get_static_share_mode_data_fn()
via 6a41de3ecd6 s3/locking: locking_tdb_data_get() -> locking_tdb_data_parse()
via f12f0d1d94e s3/locking: parse_share_modes() -> parse_share_mode_data()
via c36cc2b6720 s3:rpc_server/srvsvc: use brl_get_locks_readonly() instead of brl_get_locks()
via dc03a06ffcc smbd: use share_mode_do_locked_brl() in vfs_default_durable_reconnect()
via 393379fc9c7 smbd: use share_mode_do_locked_brl() in vfs_default_durable_disconnect()
via 56bb20c87a7 smbd: use share_mode_do_locked_brl() in strict_lock_check_default()
via 678f28c1af7 smbd: check can_lock in strict_lock_check_default()
via 8f9387ceb5c s3/locking: prepare brl_locktest() for upgradable read-only locks
via 4d680b6c17e smbd: call locking_close_file() while still holding a glock on the locking.tdb record
via 0c4c430c50e s3/brlock: remove brl_get_locks_for_locking()
via 2eef298ff4c smbd: use share_mode_do_locked_brl()
via 2772f147c9b s3/locking: add brl_set_modified()
via 3a0c6e99de4 s3/brlock: don't increment current_lock_count if do_lock_fn() failed
via e17fb732c89 s3/brlock: add share_mode_do_locked_brl()
via c9c04c7d75d s3/brlock: add brl_req_set()
via 94e7cbcc32b s3/brlock: split out brl_get_locks_readonly_parse()
via 7c60498cee7 smbtorture: add test "open-brlock-deadlock"
via 7eb135c42d5 dbwrap: check for option "tdb_hash_size:DBNAME.tdb" in db_open()
from fc9f0cd1ae1 s3: Fix use of dbwrap_transaction_cancel() in machine_account_secrets.c
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 0e4cab78cdff5c898f02f341a9ac238a6ca7c40a
Author: Ralph Boehme <slow at samba.org>
Date: Tue Jan 28 06:45:29 2025 +0100
s3/locking: add a comment to share_mode_data_ltdb_store()
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
Autobuild-User(master): Ralph Böhme <slow at samba.org>
Autobuild-Date(master): Wed Apr 2 19:03:50 UTC 2025 on atb-devel-224
commit b096214794abed40abbd83e49af856148ecc5084
Author: Ralph Boehme <slow at samba.org>
Date: Tue Jan 28 06:20:53 2025 +0100
s3/locking: add a comment to put_share_mode_lock_internal()
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit c826af38b0903f4b3c0260e380bc4630e60e5020
Author: Ralph Boehme <slow at samba.org>
Date: Tue Jan 28 06:13:15 2025 +0100
s3/locking: simplify get_static_share_mode_data_fn()
One if less and tighter coupling of logic. No change in behaviour.
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 6a41de3ecd6939019e8566d32cbf89e16e06dbe3
Author: Ralph Boehme <slow at samba.org>
Date: Tue Jan 28 06:04:43 2025 +0100
s3/locking: locking_tdb_data_get() -> locking_tdb_data_parse()
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit f12f0d1d94e29e4fe18de06e7eec2ffe6b1a5dcc
Author: Ralph Boehme <slow at samba.org>
Date: Tue Jan 28 05:52:59 2025 +0100
s3/locking: parse_share_modes() -> parse_share_mode_data()
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit c36cc2b6720a2cfe54ce52a500dc499418e27e34
Author: Ralph Boehme <slow at samba.org>
Date: Tue Jan 28 14:48:39 2025 +0100
s3:rpc_server/srvsvc: use brl_get_locks_readonly() instead of brl_get_locks()
No need to keep the record locked longer then needed.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit dc03a06ffcc79d0818ae4a36fe3f2df705144138
Author: Ralph Boehme <slow at samba.org>
Date: Wed Apr 2 14:52:03 2025 +0200
smbd: use share_mode_do_locked_brl() in vfs_default_durable_reconnect()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 393379fc9c726eb781fd1bfb3a70ea2802739aff
Author: Ralph Boehme <slow at samba.org>
Date: Tue Jan 28 11:19:05 2025 +0100
smbd: use share_mode_do_locked_brl() in vfs_default_durable_disconnect()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 56bb20c87a733ab8f7efedd881ea0ecaf51b2ba8
Author: Ralph Boehme <slow at samba.org>
Date: Thu Jan 30 07:40:32 2025 +0100
smbd: use share_mode_do_locked_brl() in strict_lock_check_default()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 678f28c1af7c160ffdcb0e4baa0a7d4b9906f2e5
Author: Ralph Boehme <slow at samba.org>
Date: Wed Apr 2 12:43:15 2025 +0200
smbd: check can_lock in strict_lock_check_default()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767
Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
Signed-off-by: Ralph Boehme <slow at samba.org>
Signed-off-by: Stefan Metzmacher <metze at samba.org>
commit 8f9387ceb5c94c7db92ab342e33c64b858c301b1
Author: Ralph Boehme <slow at samba.org>
Date: Thu Jan 30 17:35:26 2025 +0100
s3/locking: prepare brl_locktest() for upgradable read-only locks
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 4d680b6c17ee7674b9686aec2b69038f89e1989a
Author: Ralph Boehme <slow at samba.org>
Date: Mon Jan 27 15:22:26 2025 +0100
smbd: call locking_close_file() while still holding a glock on the locking.tdb record
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 0c4c430c50e15d591a0d871a5f3e59e8be0d0a83
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Jan 8 12:51:37 2025 +0100
s3/brlock: remove brl_get_locks_for_locking()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767
Pair-Programmed-With: Ralph Boehme <slow at samba.org>
Signed-off-by: Ralph Boehme <slow at samba.org>
Signed-off-by: Stefan Metzmacher <metze at samba.org>
commit 2eef298ff4c5baf15c7d29c65fb021dbed5b0a93
Author: Ralph Boehme <slow at samba.org>
Date: Wed Jan 29 06:13:44 2025 +0100
smbd: use share_mode_do_locked_brl()
Fix a deadlock that can happen if two clients happen to open and byte-range-lock
two different files whos record in locking.tdb and brlock.tdb happen to sit on
the same hashchain.
The deadlock was introduced by commit
680c7907325b433856ac1dd916ab63e671fbe4ab. Before, we used share_mode_do_locked()
in do_lock() which meant we acquired a chainlock on locking.tdb before getting a
chainlock on brlock.tdb via brl_get_locks_for_locking(), so the TDB chainlock
order invariant was always uphold.
The following race between specific client requests lead to the deadlock.
Client A) issues a byte-range-lock request on a file:
A1) glock locking.tdb (via _share_mode_do_locked_vfs_allowed())
A2) chainlock brlock.tdb (via brl_lock())
A3) attempt to chainlock locking.tdb (via share_mode_g_lock_dump())
[1]
Client B) opens a different (!) file:
B1) glock and chainlock locking.tdb (via _share_mode_entry_prepare_lock())
B2) attempt to chainlock brlock.tdb (via file_has_brlocks())
[2]
The glock from A1 is per record and hence doesn't synchronize with the glock
from B1 as it is for a different file and hence a different record, subsequently
A2 and A3 violate the lock order constraint
To avoid the chainlock lock order violation in the second client we modify the
br-lock code to not take the brlock.tdb chainlock from step A2 via
br_get_locks() for the whole time we process the request. Instead we just fetch
the br-locks via br_get_locks_readonly(), so when running into
contend_level2_oplocks_begin_default() to check for leases and looking into
locking.tdb we don't hold a brlock.tdb chainlock.
Or im simpler terms, we only ever take at most one low-level TDB chainlock at a
time:
Byte-range-lock code calls share_mode_do_locked_brl(..., cb_fn, ...):
1) chainlock locking.tdb
2) glock locking.tdb (via share_mode_do_locked_vfs_allowed())
3) chainunlock locking.tdb
4) share_mode_do_locked_brl_fn() -> brl_get_locks_readonly_parse():
a) chainlock brlock.tdb
b) parse record and store in-memory copy
c) chainunlock brlock.tdb
5) run cb_fn()
6) chainlock brlock.tdb:
a) br_lck->record = dbwrap_fetch_locked(brlock_db, ...)
b) store modifed br_lck from 5) via byte_range_lock_flush()
7) chainunlock brlock.tdb
8) chainlock locking.tdb
9) gunlock locking.tdb
10) chainunlock locking.tdb
All access to brlock.tdb is synchronized correctly via glocks on the locking.tdb
record of the file (step 3)), so operations still appear atomic to clients.
As a result of using share_mode_do_locked_brl(), the functions do_[un]lock() ->
brl_[un]lock() now loop over the same br_lck object in memory, avoiding
repeatedly fetching and storing the locks per loop.
[1]
Full SBT:
#0 0x00007fffa0cecbb0 in __pthread_mutex_lock_full () from /lib64/glibc-hwcaps/power9/libpthread-2.28.so
#1 0x00007fffa0a73cf8 in chain_mutex_lock (m=<optimized out>, m at entry=0x7fff9ae071b0, waitflag=<optimized out>, waitflag at entry=true) at ../../lib/tdb/common/mutex.c:182
#2 0x00007fffa0a7432c in tdb_mutex_lock (tdb=0x1543ba120, rw=<optimized out>, off=<optimized out>, len=<optimized out>, waitflag=<optimized out>, pret=0x7fffd7df3858) at ../../lib/tdb/common/mutex.c:234
#3 0x00007fffa0a6812c in fcntl_lock (waitflag=<optimized out>, len=1, off=376608, rw=0, tdb=0x1543ba120) at ../../lib/tdb/common/lock.c:200
#4 tdb_brlock (tdb=0x1543ba120, rw_type=<optimized out>, offset=<optimized out>, len=1, flags=<optimized out>) at ../../lib/tdb/common/lock.c:200
#5 0x00007fffa0a68af8 in tdb_nest_lock (flags=<optimized out>, ltype=0, offset=<optimized out>, tdb=0x1543ba120) at ../../lib/tdb/common/lock.c:390
#6 tdb_nest_lock (tdb=0x1543ba120, offset=<optimized out>, ltype=<optimized out>, flags=<optimized out>) at ../../lib/tdb/common/lock.c:336
#7 0x00007fffa0a69088 in tdb_lock_list (tdb=0x1543ba120, list=<optimized out>, ltype=<optimized out>, waitflag=<optimized out>) at ../../lib/tdb/common/lock.c:482
#8 0x00007fffa0a69198 in tdb_lock (tdb=0x1543ba120, list=<optimized out>, ltype=<optimized out>) at ../../lib/tdb/common/lock.c:500
#9 0x00007fffa0a64b50 in tdb_find_lock_hash (tdb=<optimized out>, tdb at entry=0x1543ba120, key=..., hash=<optimized out>, locktype=<optimized out>, locktype at entry=0, rec=<optimized out>, rec at entry=0x7fffd7df3ab0) at ../../lib/tdb/common/tdb.c:165
#10 0x00007fffa0a64ed0 in tdb_parse_record (tdb=0x1543ba120, key=..., parser=0x7fffa0e74470 <db_ctdb_ltdb_parser>, private_data=0x7fffd7df3b18) at ../../lib/tdb/common/tdb.c:329
#11 0x00007fffa0e74cbc in db_ctdb_ltdb_parse (db=<optimized out>, private_data=0x7fffd7df3b70, parser=0x7fffa0e76470 <db_ctdb_parse_record_parser_nonpersistent>, key=...) at ../../source3/lib/dbwrap/dbwrap_ctdb.c:170
#12 db_ctdb_try_parse_local_record (ctx=ctx at entry=0x1543d4580, key=..., state=state at entry=0x7fffd7df3b70) at ../../source3/lib/dbwrap/dbwrap_ctdb.c:1385
#13 0x00007fffa0e76024 in db_ctdb_parse_record (db=<optimized out>, key=..., parser=0x7fffa1313910 <dbwrap_watched_parse_record_parser>, private_data=0x7fffd7df3c08) at ../../source3/lib/dbwrap/dbwrap_ctdb.c:1425
#14 0x00007fffa0884760 in dbwrap_parse_record (db=<optimized out>, key=..., parser=<optimized out>, private_data=<optimized out>) at ../../lib/dbwrap/dbwrap.c:454
#15 0x00007fffa1313ab4 in dbwrap_watched_parse_record (db=0x1543a7160, key=..., parser=0x7fffa13187d0 <g_lock_dump_fn>, private_data=0x7fffd7df3ce8) at ../../source3/lib/dbwrap/dbwrap_watch.c:783
#16 0x00007fffa0884760 in dbwrap_parse_record (db=<optimized out>, key=..., parser=<optimized out>, private_data=<optimized out>) at ../../lib/dbwrap/dbwrap.c:454
#17 0x00007fffa131c004 in g_lock_dump (ctx=<error reading variable: value has been optimized out>, key=..., fn=0x7fffa14f3d70 <fsp_update_share_mode_flags_fn>, private_data=0x7fffd7df3dd8) at ../../source3/lib/g_lock.c:1653
#18 0x00007fffa14f434c in share_mode_g_lock_dump (key=..., fn=0x7fffa14f3d70 <fsp_update_share_mode_flags_fn>, private_data=0x7fffd7df3dd8) at ../../source3/locking/share_mode_lock.c:96
#19 0x00007fffa14f8d44 in fsp_update_share_mode_flags (fsp=0x15433c550) at ../../source3/locking/share_mode_lock.c:1181
#20 file_has_read_lease (fsp=0x15433c550) at ../../source3/locking/share_mode_lock.c:1207
#21 0x00007fffa15ccc98 in contend_level2_oplocks_begin_default (type=<optimized out>, fsp=0x15433c550) at ../../source3/smbd/smb2_oplock.c:1282
#22 smbd_contend_level2_oplocks_begin (fsp=0x15433c550, type=<optimized out>) at ../../source3/smbd/smb2_oplock.c:1338
#23 0x00007fffa0dd0b54 in contend_level2_oplocks_begin (fsp=<optimized out>, type=<optimized out>) at ../../source3/lib/smbd_shim.c:72
#24 0x00007fffa14ecfd0 in brl_lock_windows_default (br_lck=0x154421330, plock=0x7fffd7df4250) at ../../source3/locking/brlock.c:457
#25 0x00007fffa150b70c in vfswrap_brl_lock_windows (handle=<optimized out>, br_lck=<optimized out>, plock=<optimized out>) at ../../source3/modules/vfs_default.c:3424
#26 0x00007fffa1561910 in smb_vfs_call_brl_lock_windows (handle=<optimized out>, br_lck=<optimized out>, plock=<optimized out>) at ../../source3/smbd/vfs.c:2686
#27 0x00007fff9c0a7350 in smb_time_audit_brl_lock_windows (handle=<optimized out>, br_lck=0x154421330, plock=0x7fffd7df4250) at ../../source3/modules/vfs_time_audit.c:1740
#28 0x00007fffa1561910 in smb_vfs_call_brl_lock_windows (handle=<optimized out>, br_lck=<optimized out>, plock=<optimized out>) at ../../source3/smbd/vfs.c:2686
#29 0x00007fffa14ed410 in brl_lock (br_lck=0x154421330, smblctx=3102281601, pid=..., start=0, size=18446744073709551615, lock_type=<optimized out>, lock_flav=WINDOWS_LOCK, blocker_pid=0x7fffd7df4540, psmblctx=0x7fffd7df4558) at ../../source3/locking/brlock.c:1004
#30 0x00007fffa14e7b18 in do_lock_fn (lck=<optimized out>, private_data=0x7fffd7df4508) at ../../source3/locking/locking.c:271
#31 0x00007fffa14fcd94 in _share_mode_do_locked_vfs_allowed (id=..., fn=0x7fffa14e7a60 <do_lock_fn>, private_data=0x7fffd7df4508, location=<optimized out>) at ../../source3/locking/share_mode_lock.c:2927
#32 0x00007fffa14e918c in do_lock (fsp=0x15433c550, req_mem_ctx=<optimized out>, req_guid=<optimized out>, smblctx=<optimized out>, count=18446744073709551615, offset=0, lock_type=<optimized out>, lock_flav=<optimized out>, pblocker_pid=0x7fffd7df46f0,
psmblctx=0x7fffd7df46d8) at ../../source3/locking/locking.c:335
#33 0x00007fffa155381c in smbd_do_locks_try (fsp=0x15433c550, num_locks=<optimized out>, locks=0x1543bc310, blocker_idx=0x7fffd7df46d6, blocking_pid=0x7fffd7df46f0, blocking_smblctx=0x7fffd7df46d8) at ../../source3/smbd/blocking.c:46
#34 0x00007fffa159dc90 in smbd_smb2_lock_try (req=req at entry=0x1543bc080) at ../../source3/smbd/smb2_lock.c:590
#35 0x00007fffa159ee8c in smbd_smb2_lock_send (in_locks=<optimized out>, in_lock_count=1, in_lock_sequence=<optimized out>, fsp=0x15433c550, smb2req=0x1543532e0, ev=0x154328120, mem_ctx=0x1543532e0) at ../../source3/smbd/smb2_lock.c:488
#36 smbd_smb2_request_process_lock (req=0x1543532e0) at ../../source3/smbd/smb2_lock.c:150
#37 0x00007fffa158a368 in smbd_smb2_request_dispatch (req=0x1543532e0) at ../../source3/smbd/smb2_server.c:3515
#38 0x00007fffa158c540 in smbd_smb2_io_handler (fde_flags=<optimized out>, xconn=0x154313f30) at ../../source3/smbd/smb2_server.c:5112
#39 smbd_smb2_connection_handler (ev=<optimized out>, fde=<optimized out>, flags=<optimized out>, private_data=<optimized out>) at ../../source3/smbd/smb2_server.c:5150
#40 0x00007fffa1198b2c in tevent_common_invoke_fd_handler (fde=0x1543670f0, flags=<optimized out>, removed=0x0) at ../../lib/tevent/tevent_fd.c:158
#41 0x00007fffa11a2b9c in epoll_event_loop (tvalp=0x7fffd7df4b28, epoll_ev=0x1543b4e80) at ../../lib/tevent/tevent_epoll.c:730
#42 epoll_event_loop_once (ev=<optimized out>, location=<optimized out>) at ../../lib/tevent/tevent_epoll.c:946
#43 0x00007fffa11a0090 in std_event_loop_once (ev=0x154328120, location=0x7fffa1668db8 "../../source3/smbd/smb2_process.c:2158") at ../../lib/tevent/tevent_standard.c:110
#44 0x00007fffa119744c in _tevent_loop_once (ev=0x154328120, location=0x7fffa1668db8 "../../source3/smbd/smb2_process.c:2158") at ../../lib/tevent/tevent.c:823
#45 0x00007fffa1197884 in tevent_common_loop_wait (ev=<optimized out>, location=<optimized out>) at ../../lib/tevent/tevent.c:950
#46 0x00007fffa119ffc0 in std_event_loop_wait (ev=0x154328120, location=0x7fffa1668db8 "../../source3/smbd/smb2_process.c:2158") at ../../lib/tevent/tevent_standard.c:141
#47 0x00007fffa1197978 in _tevent_loop_wait (ev=<optimized out>, location=<optimized out>) at ../../lib/tevent/tevent.c:971
#48 0x00007fffa15737fc in smbd_process (ev_ctx=0x154328120, msg_ctx=<optimized out>, sock_fd=<optimized out>, interactive=<optimized out>) at ../../source3/smbd/smb2_process.c:2158
#49 0x000000011db5c554 in smbd_accept_connection (ev=0x154328120, fde=<optimized out>, flags=<optimized out>, private_data=<optimized out>) at ../../source3/smbd/server.c:1150
#50 0x00007fffa1198b2c in tevent_common_invoke_fd_handler (fde=0x1543ac2d0, flags=<optimized out>, removed=0x0) at ../../lib/tevent/tevent_fd.c:158
#51 0x00007fffa11a2b9c in epoll_event_loop (tvalp=0x7fffd7df4f98, epoll_ev=0x154328350) at ../../lib/tevent/tevent_epoll.c:730
#52 epoll_event_loop_once (ev=<optimized out>, location=<optimized out>) at ../../lib/tevent/tevent_epoll.c:946
#53 0x00007fffa11a0090 in std_event_loop_once (ev=0x154328120, location=0x11db60b50 "../../source3/smbd/server.c:1499") at ../../lib/tevent/tevent_standard.c:110
#54 0x00007fffa119744c in _tevent_loop_once (ev=0x154328120, location=0x11db60b50 "../../source3/smbd/server.c:1499") at ../../lib/tevent/tevent.c:823
#55 0x00007fffa1197884 in tevent_common_loop_wait (ev=<optimized out>, location=<optimized out>) at ../../lib/tevent/tevent.c:950
#56 0x00007fffa119ffc0 in std_event_loop_wait (ev=0x154328120, location=0x11db60b50 "../../source3/smbd/server.c:1499") at ../../lib/tevent/tevent_standard.c:141
#57 0x00007fffa1197978 in _tevent_loop_wait (ev=<optimized out>, location=<optimized out>) at ../../lib/tevent/tevent.c:971
#58 0x000000011db58c54 in smbd_parent_loop (parent=<optimized out>, ev_ctx=0x154328120) at ../../source3/smbd/server.c:1499
#59 main (argc=<optimized out>, argv=<optimized out>) at ../../source3/smbd/server.c:2258
[2]
Full SBT:
#0 0x00007fffa0cecbb0 in __pthread_mutex_lock_full () from /lib64/glibc-hwcaps/power9/libpthread-2.28.so
#1 0x00007fffa0a73cf8 in chain_mutex_lock (m=<optimized out>, m at entry=0x7fff9b3a71b0, waitflag=<optimized out>, waitflag at entry=true) at ../../lib/tdb/common/mutex.c:182
#2 0x00007fffa0a7432c in tdb_mutex_lock (tdb=0x1543c6900, rw=<optimized out>, off=<optimized out>, len=<optimized out>, waitflag=<optimized out>, pret=0x7fffd7df2e28) at ../../lib/tdb/common/mutex.c:234
#3 0x00007fffa0a6812c in fcntl_lock (waitflag=<optimized out>, len=1, off=376608, rw=0, tdb=0x1543c6900) at ../../lib/tdb/common/lock.c:200
#4 tdb_brlock (tdb=0x1543c6900, rw_type=<optimized out>, offset=<optimized out>, len=1, flags=<optimized out>) at ../../lib/tdb/common/lock.c:200
#5 0x00007fffa0a68af8 in tdb_nest_lock (flags=<optimized out>, ltype=0, offset=<optimized out>, tdb=0x1543c6900) at ../../lib/tdb/common/lock.c:390
#6 tdb_nest_lock (tdb=0x1543c6900, offset=<optimized out>, ltype=<optimized out>, flags=<optimized out>) at ../../lib/tdb/common/lock.c:336
#7 0x00007fffa0a69088 in tdb_lock_list (tdb=0x1543c6900, list=<optimized out>, ltype=<optimized out>, waitflag=<optimized out>) at ../../lib/tdb/common/lock.c:482
#8 0x00007fffa0a69198 in tdb_lock (tdb=0x1543c6900, list=<optimized out>, ltype=<optimized out>) at ../../lib/tdb/common/lock.c:500
#9 0x00007fffa0a64b50 in tdb_find_lock_hash (tdb=<optimized out>, tdb at entry=0x1543c6900, key=..., hash=<optimized out>, locktype=<optimized out>, locktype at entry=0, rec=<optimized out>, rec at entry=0x7fffd7df3080) at ../../lib/tdb/common/tdb.c:165
#10 0x00007fffa0a64ed0 in tdb_parse_record (tdb=0x1543c6900, key=..., parser=0x7fffa0e74470 <db_ctdb_ltdb_parser>, private_data=0x7fffd7df30e8) at ../../lib/tdb/common/tdb.c:329
#11 0x00007fffa0e74cbc in db_ctdb_ltdb_parse (db=<optimized out>, private_data=0x7fffd7df3140, parser=0x7fffa0e76470 <db_ctdb_parse_record_parser_nonpersistent>, key=...) at ../../source3/lib/dbwrap/dbwrap_ctdb.c:170
#12 db_ctdb_try_parse_local_record (ctx=ctx at entry=0x154328fc0, key=..., state=state at entry=0x7fffd7df3140) at ../../source3/lib/dbwrap/dbwrap_ctdb.c:1385
#13 0x00007fffa0e76024 in db_ctdb_parse_record (db=<optimized out>, key=..., parser=0x7fffa14ec820 <brl_get_locks_readonly_parser>, private_data=0x7fffd7df3218) at ../../source3/lib/dbwrap/dbwrap_ctdb.c:1425
#14 0x00007fffa0884760 in dbwrap_parse_record (db=<optimized out>, key=..., parser=<optimized out>, private_data=<optimized out>) at ../../lib/dbwrap/dbwrap.c:454
#15 0x00007fffa14ef5bc in brl_get_locks_readonly (fsp=0x1543d01e0) at ../../source3/locking/brlock.c:1884
#16 0x00007fffa1546968 in file_has_brlocks (fsp=0x1543d01e0) at ../../source3/smbd/open.c:2232
#17 delay_for_oplock (pgranted=<synthetic pointer>, poplock_type=<synthetic pointer>, first_open_attempt=<optimized out>, create_disposition=1, have_sharing_violation=false, lck=0x7fffd7df3ce8, lease=0x0, oplock_request=0, fsp=0x1543d01e0) at ../../source3/smbd/open.c:2749
#18 handle_share_mode_lease (pgranted=<synthetic pointer>, poplock_type=<synthetic pointer>, first_open_attempt=<optimized out>, lease=0x0, oplock_request=0, share_access=7, access_mask=131201, create_disposition=1, lck=0x7fffd7df3ce8, fsp=0x1543d01e0) at ../../source3/smbd/open.c:2865
#19 check_and_store_share_mode (first_open_attempt=<optimized out>, lease=0x0, oplock_request=0, share_access=7, access_mask=131201, create_disposition=1, lck=0x7fffd7df3ce8, req=0x154414800, fsp=0x1543d01e0) at ../../source3/smbd/open.c:3333
#20 open_ntcreate_lock_add_entry (lck=0x7fffd7df3ce8, keep_locked=0x7fffd7df3ad0, private_data=0x7fffd7df3cc8) at ../../source3/smbd/open.c:3688
#21 0x00007fffa14f6248 in share_mode_entry_prepare_lock_fn (glck=0x7fffd7df35b8, cb_private=0x7fffd7df3a88) at ../../source3/locking/share_mode_lock.c:2978
#22 0x00007fffa1317680 in g_lock_lock_cb_run_and_store (cb_state=cb_state at entry=0x7fffd7df35b8) at ../../source3/lib/g_lock.c:597
#23 0x00007fffa1319df8 in g_lock_lock_simple_fn (rec=0x7fffd7df3798, value=..., private_data=0x7fffd7df39a0) at ../../source3/lib/g_lock.c:1212
#24 0x00007fffa13160e0 in dbwrap_watched_do_locked_fn (backend_rec=<optimized out>, backend_value=..., private_data=0x7fffd7df3768) at ../../source3/lib/dbwrap/dbwrap_watch.c:458
#25 0x00007fffa0884e48 in dbwrap_do_locked (db=<optimized out>, key=..., fn=0x7fffa1316080 <dbwrap_watched_do_locked_fn>, private_data=0x7fffd7df3768) at ../../lib/dbwrap/dbwrap.c:602
#26 0x00007fffa1315274 in dbwrap_watched_do_locked (db=0x1543a7160, key=..., fn=0x7fffa1319ca0 <g_lock_lock_simple_fn>, private_data=0x7fffd7df39a0) at ../../source3/lib/dbwrap/dbwrap_watch.c:480
#27 0x00007fffa0884d60 in dbwrap_do_locked (db=<optimized out>, key=..., fn=<optimized out>, private_data=<optimized out>) at ../../lib/dbwrap/dbwrap.c:582
#28 0x00007fffa131b458 in g_lock_lock (ctx=0x1543cc630, key=..., type=<optimized out>, timeout=..., cb_fn=0x7fffa14f6190 <share_mode_entry_prepare_lock_fn>, cb_private=0x7fffd7df3a88) at ../../source3/lib/g_lock.c:1267
#29 0x00007fffa14fd060 in _share_mode_entry_prepare_lock (prepare_state=0x7fffd7df3cc8, id=..., servicepath=<optimized out>, smb_fname=<optimized out>, old_write_time=<optimized out>, fn=<optimized out>, private_data=0x7fffd7df3cc8, location=0x7fffa165b880 "../../source3/smbd/open.c:4292") at ../../source3/locking/share_mode_lock.c:3033
#30 0x00007fffa15491e0 in open_file_ntcreate (conn=conn at entry=0x154382050, req=req at entry=0x154414800, access_mask=<optimized out>, access_mask at entry=131201, share_access=share_access at entry=7, create_disposition=create_disposition at entry=1, create_options=create_options at entry=0, new_dos_attributes=<optimized out>, new_dos_attributes at entry=128, oplock_request=oplock_request at entry=0, lease=<optimized out>, lease at entry=0x0, private_flags=<optimized out>, private_flags at entry=0, parent_dir_fname=<optimized out>, smb_fname_atname=<optimized out>, pinfo=<optimized out>, pinfo at entry=0x7fffd7df3f1c, fsp=<optimized out>, fsp at entry=0x1543d01e0) at ../../source3/smbd/open.c:4286
#31 0x00007fffa154b94c in create_file_unixpath (conn=conn at entry=0x154382050, req=req at entry=0x154414800, dirfsp=dirfsp at entry=0x15439a7f0, smb_fname=smb_fname at entry=0x154416300, access_mask=access_mask at entry=131201, share_access=share_access at entry=7, create_disposition=create_disposition at entry=1, create_options=create_options at entry=0, file_attributes=file_attributes at entry=128, oplock_request=<optimized out>, oplock_request at entry=0, lease=<optimized out>, lease at entry=0x0, allocation_size=allocation_size at entry=0, private_flags=private_flags at entry=0, sd=sd at entry=0x0, ea_list=ea_list at entry=0x0, result=result at entry=0x7fffd7df4168, pinfo=pinfo at entry=0x7fffd7df4160) at ../../source3/smbd/open.c:6290
#32 0x00007fffa154dfac in create_file_default (conn=0x154382050, req=0x154414800, dirfsp=0x15439a7f0, smb_fname=0x154416300, access_mask=<optimized out>, share_access=<optimized out>, create_disposition=<optimized out>, create_options=<optimized out>, file_attributes=128, oplock_request=0, lease=0x0, allocation_size=0, private_flags=0, sd=0x0, ea_list=0x0, result=0x1544144e8, pinfo=0x1544144fc, in_context_blobs=0x7fffd7df4798, out_context_blobs=0x154414710) at ../../source3/smbd/open.c:6609
#33 0x00007fffa150972c in vfswrap_create_file (handle=<optimized out>, req=<optimized out>, dirfsp=<optimized out>, smb_fname=<optimized out>, access_mask=<optimized out>, share_access=<optimized out>, create_disposition=<optimized out>, create_options=<optimized out>, file_attributes=128, oplock_request=0, lease=0x0, allocation_size=0, private_flags=0, sd=0x0, ea_list=0x0, result=0x1544144e8, pinfo=0x1544144fc, in_context_blobs=0x7fffd7df4798, out_context_blobs=0x154414710) at ../../source3/modules/vfs_default.c:776
#34 0x00007fffa1559cbc in smb_vfs_call_create_file (handle=<optimized out>, req=<optimized out>, dirfsp=<optimized out>, smb_fname=<optimized out>, access_mask=<optimized out>, share_access=<optimized out>, create_disposition=<optimized out>, create_options=<optimized out>, file_attributes=128, oplock_request=0, lease=0x0, allocation_size=0, private_flags=0, sd=0x0, ea_list=0x0, result=0x1544144e8, pinfo=0x1544144fc, in_context_blobs=0x7fffd7df4798, out_context_blobs=0x154414710) at ../../source3/smbd/vfs.c:1560
#35 0x00007fff9c0a9ec4 in smb_time_audit_create_file (handle=0x154426820, req=0x154414800, dirfsp=0x15439a7f0, fname=0x154416300, access_mask=<optimized out>, share_access=<optimized out>, create_disposition=<optimized out>, create_options=<optimized out>, file_attributes=128, oplock_request=0, lease=0x0, allocation_size=0, private_flags=0, sd=0x0, ea_list=0x0, result_fsp=0x1544144e8, pinfo=0x1544144fc, in_context_blobs=0x7fffd7df4798, out_context_blobs=0x154414710) at ../../source3/modules/vfs_time_audit.c:634
#36 0x00007fffa1559cbc in smb_vfs_call_create_file (handle=<optimized out>, req=<optimized out>, dirfsp=<optimized out>, smb_fname=<optimized out>, access_mask=<optimized out>, share_access=<optimized out>, create_disposition=<optimized out>, create_options=<optimized out>, file_attributes=128, oplock_request=0, lease=0x0, allocation_size=0, private_flags=0, sd=0x0, ea_list=0x0, result=0x1544144e8, pinfo=0x1544144fc, in_context_blobs=0x7fffd7df4798, out_context_blobs=0x154414710) at ../../source3/smbd/vfs.c:1560
#37 0x00007fffa1597aa8 in smbd_smb2_create_send (in_context_blobs=..., in_name=0x154413ca0, in_create_options=<optimized out>, in_create_disposition=<optimized out>, in_share_access=<optimized out>, in_file_attributes=<optimized out>, in_desired_access=<optimized out>, in_impersonation_level=<optimized out>, in_oplock_level=<optimized out>, smb2req=0x154413770, ev=0x154328120, mem_ctx=0x154413770) at ../../source3/smbd/smb2_create.c:1115
#38 smbd_smb2_request_process_create (smb2req=0x154413770) at ../../source3/smbd/smb2_create.c:291
#39 0x00007fffa158a628 in smbd_smb2_request_dispatch (req=0x154413770) at ../../source3/smbd/smb2_server.c:3485
#40 0x00007fffa158c540 in smbd_smb2_io_handler (fde_flags=<optimized out>, xconn=0x154313f30) at ../../source3/smbd/smb2_server.c:5112
#41 smbd_smb2_connection_handler (ev=<optimized out>, fde=<optimized out>, flags=<optimized out>, private_data=<optimized out>) at ../../source3/smbd/smb2_server.c:5150
#42 0x00007fffa1198b2c in tevent_common_invoke_fd_handler (fde=0x15435add0, flags=<optimized out>, removed=0x0) at ../../lib/tevent/tevent_fd.c:158
#43 0x00007fffa11a2b9c in epoll_event_loop (tvalp=0x7fffd7df4b28, epoll_ev=0x1543b4e80) at ../../lib/tevent/tevent_epoll.c:730
#44 epoll_event_loop_once (ev=<optimized out>, location=<optimized out>) at ../../lib/tevent/tevent_epoll.c:946
#45 0x00007fffa11a0090 in std_event_loop_once (ev=0x154328120, location=0x7fffa1668db8 "../../source3/smbd/smb2_process.c:2158") at ../../lib/tevent/tevent_standard.c:110
#46 0x00007fffa119744c in _tevent_loop_once (ev=0x154328120, location=0x7fffa1668db8 "../../source3/smbd/smb2_process.c:2158") at ../../lib/tevent/tevent.c:823
#47 0x00007fffa1197884 in tevent_common_loop_wait (ev=<optimized out>, location=<optimized out>) at ../../lib/tevent/tevent.c:950
#48 0x00007fffa119ffc0 in std_event_loop_wait (ev=0x154328120, location=0x7fffa1668db8 "../../source3/smbd/smb2_process.c:2158") at ../../lib/tevent/tevent_standard.c:141
#49 0x00007fffa1197978 in _tevent_loop_wait (ev=<optimized out>, location=<optimized out>) at ../../lib/tevent/tevent.c:971
#50 0x00007fffa15737fc in smbd_process (ev_ctx=0x154328120, msg_ctx=<optimized out>, sock_fd=<optimized out>, interactive=<optimized out>) at ../../source3/smbd/smb2_process.c:2158
#51 0x000000011db5c554 in smbd_accept_connection (ev=0x154328120, fde=<optimized out>, flags=<optimized out>, private_data=<optimized out>) at ../../source3/smbd/server.c:1150
#52 0x00007fffa1198b2c in tevent_common_invoke_fd_handler (fde=0x1543ac2d0, flags=<optimized out>, removed=0x0) at ../../lib/tevent/tevent_fd.c:158
#53 0x00007fffa11a2b9c in epoll_event_loop (tvalp=0x7fffd7df4f98, epoll_ev=0x154328350) at ../../lib/tevent/tevent_epoll.c:730
#54 epoll_event_loop_once (ev=<optimized out>, location=<optimized out>) at ../../lib/tevent/tevent_epoll.c:946
#55 0x00007fffa11a0090 in std_event_loop_once (ev=0x154328120, location=0x11db60b50 "../../source3/smbd/server.c:1499") at ../../lib/tevent/tevent_standard.c:110
#56 0x00007fffa119744c in _tevent_loop_once (ev=0x154328120, location=0x11db60b50 "../../source3/smbd/server.c:1499") at ../../lib/tevent/tevent.c:823
#57 0x00007fffa1197884 in tevent_common_loop_wait (ev=<optimized out>, location=<optimized out>) at ../../lib/tevent/tevent.c:950
#58 0x00007fffa119ffc0 in std_event_loop_wait (ev=0x154328120, location=0x11db60b50 "../../source3/smbd/server.c:1499") at ../../lib/tevent/tevent_standard.c:141
#59 0x00007fffa1197978 in _tevent_loop_wait (ev=<optimized out>, location=<optimized out>) at ../../lib/tevent/tevent.c:971
#60 0x000000011db58c54 in smbd_parent_loop (parent=<optimized out>, ev_ctx=0x154328120) at ../../source3/smbd/server.c:1499
#61 main (argc=<optimized out>, argv=<optimized out>) at ../../source3/smbd/server.c:2258
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767
Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
Signed-off-by: Ralph Boehme <slow at samba.org>
Signed-off-by: Stefan Metzmacher <metze at samba.org>
commit 2772f147c9b13cd2160181c4f7905b54ab765054
Author: Ralph Boehme <slow at samba.org>
Date: Wed Jan 29 06:13:29 2025 +0100
s3/locking: add brl_set_modified()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 3a0c6e99de4377f44bc29766b6ceb79040caed9f
Author: Ralph Boehme <slow at samba.org>
Date: Wed Jan 8 15:43:04 2025 +0100
s3/brlock: don't increment current_lock_count if do_lock_fn() failed
Also only assign psmblctx and pblocker_pid if the lock request failed.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit e17fb732c89f8b34de00904383044de3c4f85bd0
Author: Ralph Boehme <slow at samba.org>
Date: Sat Feb 1 10:37:40 2025 +0100
s3/brlock: add share_mode_do_locked_brl()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767
Pair-Programmed-With: Stefan Metzmacher <metze at samba.org>
Signed-off-by: Ralph Boehme <slow at samba.org>
Signed-off-by: Stefan Metzmacher <metze at samba.org>
commit c9c04c7d75dee0c3e6e843b581624a3852042057
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Jan 6 17:07:11 2025 +0100
s3/brlock: add brl_req_set()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Reviewed-by: Ralph Boehme <slow at samba.org>
commit 94e7cbcc32b73e4d56e7209e04d22d4270a6eb5b
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Jan 6 15:59:27 2025 +0100
s3/brlock: split out brl_get_locks_readonly_parse()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767
Pair-Programmed-With: Ralph Boehme <slow at samba.org>
Signed-off-by: Ralph Boehme <slow at samba.org>
Signed-off-by: Stefan Metzmacher <metze at samba.org>
commit 7c60498cee7dca5770d4d1f623c472d585ae9cae
Author: Ralph Boehme <slow at samba.org>
Date: Thu Jan 9 12:27:43 2025 +0100
smbtorture: add test "open-brlock-deadlock"
smbtorture reproducer for bug 15767. As it needs a very specific setup that
can't easily be done in selftest, the test is only executed when manually called
with
--option=torture:open_brlock_deadlock_timemout=SEC
To prepare the setup for the test set:
tdb_hash_size:locking.tdb = 1
tdb_hash_size:brlock.tdb = 1
and remove both tdb from disk which is needed so the TDBs get recreated with the
new hash_size.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
commit 7eb135c42d530a16e80e165d9e8e99d920797f12
Author: Ralph Boehme <slow at samba.org>
Date: Thu Jan 9 08:57:17 2025 +0100
dbwrap: check for option "tdb_hash_size:DBNAME.tdb" in db_open()
BUG: https://bugzilla.samba.org/show_bug.cgi?id=15767
Signed-off-by: Ralph Boehme <slow at samba.org>
Reviewed-by: Stefan Metzmacher <metze at samba.org>
-----------------------------------------------------------------------
Summary of changes:
source3/lib/dbwrap/dbwrap_open.c | 5 +
source3/locking/brlock.c | 213 +++++++++----
source3/locking/locking.c | 165 +++++-----
source3/locking/proto.h | 35 ++-
source3/locking/share_mode_lock.c | 57 ++--
source3/modules/vfs_fruit.c | 91 ++++--
source3/rpc_server/srvsvc/srv_srvsvc_nt.c | 12 +-
source3/smbd/blocking.c | 202 ++++++------
source3/smbd/close.c | 26 +-
source3/smbd/durable.c | 496 ++++++++++++++++--------------
source3/smbd/proto.h | 19 +-
source3/smbd/smb2_lock.c | 77 +++--
source3/smbd/smb2_reply.c | 53 ++--
source4/torture/smb2/lock.c | 283 +++++++++++++++++
14 files changed, 1135 insertions(+), 599 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/lib/dbwrap/dbwrap_open.c b/source3/lib/dbwrap/dbwrap_open.c
index 52c8a94aeff..91556f22819 100644
--- a/source3/lib/dbwrap/dbwrap_open.c
+++ b/source3/lib/dbwrap/dbwrap_open.c
@@ -80,6 +80,11 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx,
base = name;
}
+ hash_size = lp_parm_int(GLOBAL_SECTION_SNUM,
+ "tdb_hash_size",
+ base,
+ hash_size);
+
if (tdb_flags & TDB_CLEAR_IF_FIRST) {
bool try_readonly = false;
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c
index 0c5dab19389..787c65c16f8 100644
--- a/source3/locking/brlock.c
+++ b/source3/locking/brlock.c
@@ -34,6 +34,7 @@
#include "serverid.h"
#include "messages.h"
#include "util_tdb.h"
+#include "source3/locking/share_mode_lock.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_LOCKING
@@ -84,6 +85,15 @@ struct files_struct *brl_fsp(struct byte_range_lock *brl)
return brl->fsp;
}
+
+void brl_req_set(struct byte_range_lock *br_lck,
+ TALLOC_CTX *req_mem_ctx,
+ const struct GUID *req_guid)
+{
+ br_lck->req_mem_ctx = req_mem_ctx;
+ br_lck->req_guid = req_guid;
+}
+
TALLOC_CTX *brl_req_mem_ctx(const struct byte_range_lock *brl)
{
if (brl->req_mem_ctx == NULL) {
@@ -1184,7 +1194,8 @@ bool brl_unlock(struct byte_range_lock *br_lck,
****************************************************************************/
bool brl_locktest(struct byte_range_lock *br_lck,
- const struct lock_struct *rw_probe)
+ const struct lock_struct *rw_probe,
+ bool upgradable)
{
bool ret = True;
unsigned int i;
@@ -1197,7 +1208,7 @@ bool brl_locktest(struct byte_range_lock *br_lck,
* Our own locks don't conflict.
*/
if (brl_conflict_other(&locks[i], rw_probe)) {
- if (br_lck->record == NULL) {
+ if (!upgradable) {
/* readonly */
return false;
}
@@ -1359,14 +1370,14 @@ void brl_close_fnum(struct byte_range_lock *br_lck)
}
}
-bool brl_mark_disconnected(struct files_struct *fsp)
+bool brl_mark_disconnected(struct files_struct *fsp,
+ struct byte_range_lock *br_lck)
{
uint32_t tid = fsp->conn->cnum;
uint64_t smblctx;
uint64_t fnum = fsp->fnum;
unsigned int i;
struct server_id self = messaging_server_id(fsp->conn->sconn->msg_ctx);
- struct byte_range_lock *br_lck = NULL;
if (fsp->op == NULL) {
return false;
@@ -1382,11 +1393,6 @@ bool brl_mark_disconnected(struct files_struct *fsp)
return true;
}
- br_lck = brl_get_locks(talloc_tos(), fsp);
- if (br_lck == NULL) {
- return false;
- }
-
for (i=0; i < br_lck->num_locks; i++) {
struct lock_struct *lock = &br_lck->lock_data[i];
@@ -1396,22 +1402,18 @@ bool brl_mark_disconnected(struct files_struct *fsp)
*/
if (lock->context.smblctx != smblctx) {
- TALLOC_FREE(br_lck);
return false;
}
if (lock->context.tid != tid) {
- TALLOC_FREE(br_lck);
return false;
}
if (!server_id_equal(&lock->context.pid, &self)) {
- TALLOC_FREE(br_lck);
return false;
}
if (lock->fnum != fnum) {
- TALLOC_FREE(br_lck);
return false;
}
@@ -1421,18 +1423,17 @@ bool brl_mark_disconnected(struct files_struct *fsp)
}
br_lck->modified = true;
- TALLOC_FREE(br_lck);
return true;
}
-bool brl_reconnect_disconnected(struct files_struct *fsp)
+bool brl_reconnect_disconnected(struct files_struct *fsp,
+ struct byte_range_lock *br_lck)
{
uint32_t tid = fsp->conn->cnum;
uint64_t smblctx;
uint64_t fnum = fsp->fnum;
unsigned int i;
struct server_id self = messaging_server_id(fsp->conn->sconn->msg_ctx);
- struct byte_range_lock *br_lck = NULL;
if (fsp->op == NULL) {
return false;
@@ -1450,13 +1451,7 @@ bool brl_reconnect_disconnected(struct files_struct *fsp)
* them instead.
*/
- br_lck = brl_get_locks(talloc_tos(), fsp);
- if (br_lck == NULL) {
- return false;
- }
-
if (br_lck->num_locks == 0) {
- TALLOC_FREE(br_lck);
return true;
}
@@ -1469,22 +1464,18 @@ bool brl_reconnect_disconnected(struct files_struct *fsp)
*/
if (lock->context.smblctx != smblctx) {
- TALLOC_FREE(br_lck);
return false;
}
if (lock->context.tid != TID_FIELD_INVALID) {
- TALLOC_FREE(br_lck);
return false;
}
if (!server_id_is_disconnected(&lock->context.pid)) {
- TALLOC_FREE(br_lck);
return false;
}
if (lock->fnum != FNUM_FIELD_INVALID) {
- TALLOC_FREE(br_lck);
return false;
}
@@ -1495,7 +1486,6 @@ bool brl_reconnect_disconnected(struct files_struct *fsp)
fsp->current_lock_count = br_lck->num_locks;
br_lck->modified = true;
- TALLOC_FREE(br_lck);
return true;
}
@@ -1725,25 +1715,6 @@ struct byte_range_lock *brl_get_locks(TALLOC_CTX *mem_ctx, files_struct *fsp)
return br_lck;
}
-struct byte_range_lock *brl_get_locks_for_locking(TALLOC_CTX *mem_ctx,
- files_struct *fsp,
- TALLOC_CTX *req_mem_ctx,
- const struct GUID *req_guid)
-{
- struct byte_range_lock *br_lck = NULL;
-
- br_lck = brl_get_locks(mem_ctx, fsp);
- if (br_lck == NULL) {
- return NULL;
- }
- SMB_ASSERT(req_mem_ctx != NULL);
- br_lck->req_mem_ctx = req_mem_ctx;
- SMB_ASSERT(req_guid != NULL);
- br_lck->req_guid = req_guid;
-
- return br_lck;
-}
-
struct brl_get_locks_readonly_state {
TALLOC_CTX *mem_ctx;
struct byte_range_lock **br_lock;
@@ -1770,29 +1741,18 @@ static void brl_get_locks_readonly_parser(TDB_DATA key, TDB_DATA data,
*state->br_lock = br_lck;
}
-struct byte_range_lock *brl_get_locks_readonly(files_struct *fsp)
+static struct byte_range_lock *brl_get_locks_readonly_parse(TALLOC_CTX *mem_ctx,
+ files_struct *fsp)
{
struct byte_range_lock *br_lock = NULL;
struct brl_get_locks_readonly_state state;
NTSTATUS status;
- DEBUG(10, ("seqnum=%d, fsp->brlock_seqnum=%d\n",
- dbwrap_get_seqnum(brlock_db), fsp->brlock_seqnum));
-
- if ((fsp->brlock_rec != NULL)
- && (dbwrap_get_seqnum(brlock_db) == fsp->brlock_seqnum)) {
- /*
- * We have cached the brlock_rec and the database did not
- * change.
- */
- return fsp->brlock_rec;
- }
-
/*
* Parse the record fresh from the database
*/
- state.mem_ctx = fsp;
+ state.mem_ctx = mem_ctx;
state.br_lock = &br_lock;
status = dbwrap_parse_record(
@@ -1805,7 +1765,7 @@ struct byte_range_lock *brl_get_locks_readonly(files_struct *fsp)
/*
* No locks on this file. Return an empty br_lock.
*/
- br_lock = talloc_zero(fsp, struct byte_range_lock);
+ br_lock = talloc_zero(mem_ctx, struct byte_range_lock);
if (br_lock == NULL) {
return NULL;
}
@@ -1823,6 +1783,30 @@ struct byte_range_lock *brl_get_locks_readonly(files_struct *fsp)
br_lock->modified = false;
br_lock->record = NULL;
+ return br_lock;
+}
+
+struct byte_range_lock *brl_get_locks_readonly(files_struct *fsp)
+{
+ struct byte_range_lock *br_lock = NULL;
+
+ DEBUG(10, ("seqnum=%d, fsp->brlock_seqnum=%d\n",
+ dbwrap_get_seqnum(brlock_db), fsp->brlock_seqnum));
+
+ if ((fsp->brlock_rec != NULL)
+ && (dbwrap_get_seqnum(brlock_db) == fsp->brlock_seqnum)) {
+ /*
+ * We have cached the brlock_rec and the database did not
+ * change.
+ */
+ return fsp->brlock_rec;
+ }
+
+ br_lock = brl_get_locks_readonly_parse(fsp, fsp);
+ if (br_lock == NULL) {
+ return NULL;
+ }
+
/*
* Cache the brlock struct, invalidated when the dbwrap_seqnum
* changes. See beginning of this routine.
@@ -1907,3 +1891,110 @@ done:
talloc_free(frame);
return ret;
}
+
+struct share_mode_do_locked_brl_state {
+ share_mode_do_locked_brl_fn_t cb;
+ void *cb_data;
+ struct files_struct *fsp;
+ NTSTATUS status;
+};
+
+static void share_mode_do_locked_brl_fn(struct share_mode_lock *lck,
+ void *private_data)
+{
+ struct share_mode_do_locked_brl_state *state = private_data;
+ struct byte_range_lock *br_lck = NULL;
+ TDB_DATA key = make_tdb_data((uint8_t *)&state->fsp->file_id,
+ sizeof(state->fsp->file_id));
+
+ if (lp_locking(state->fsp->conn->params) &&
+ state->fsp->fsp_flags.can_lock)
+ {
+ br_lck = brl_get_locks_readonly_parse(talloc_tos(),
+ state->fsp);
+ if (br_lck == NULL) {
+ state->status = NT_STATUS_NO_MEMORY;
+ return;
+ }
+ }
+
+ state->cb(lck, br_lck, state->cb_data);
+
+ if (br_lck == NULL || !br_lck->modified) {
+ TALLOC_FREE(br_lck);
+ return;
+ }
+
+ br_lck->record = dbwrap_fetch_locked(brlock_db, br_lck, key);
+ if (br_lck->record == NULL) {
+ DBG_ERR("Could not lock byte range lock entry for '%s'\n",
+ fsp_str_dbg(state->fsp));
+ TALLOC_FREE(br_lck);
+ state->status = NT_STATUS_INTERNAL_DB_ERROR;
+ return;
+ }
+
+ byte_range_lock_flush(br_lck);
+ share_mode_wakeup_waiters(br_lck->fsp->file_id);
+ TALLOC_FREE(br_lck);
+}
+
+/*
+ * Run cb with a glock'ed locking.tdb record, providing both a share_mode_lock
+ * and a br_lck object. An initial read-only, but upgradable, br_lck object is
+ * fetched from brlock.tdb while holding the glock on the locking.tdb record.
+ *
+ * This function only ever hold one low-level TDB chainlock at a time on either
+ * locking.tdb or brlock.tdb, so it can't run afoul any lock order violations.
+ *
+ * Note that br_lck argument in the callback might be NULL in case lp_locking()
+ * is disabled, the fsp doesn't allow locking or is a directory, so either
+ * the caller or the callback have to check for this.
+ */
+NTSTATUS share_mode_do_locked_brl(files_struct *fsp,
+ share_mode_do_locked_brl_fn_t cb,
+ void *cb_data)
+{
+ static bool recursion_guard;
+ TALLOC_CTX *frame = NULL;
+ struct share_mode_do_locked_brl_state state = {
+ .fsp = fsp,
+ .cb = cb,
+ .cb_data = cb_data,
+ };
+ NTSTATUS status;
+
+ SMB_ASSERT(!recursion_guard);
+
+ /* silently return ok on print files as we don't do locking there */
+ if (fsp->print_file) {
+ return NT_STATUS_OK;
+ }
+
+ frame = talloc_stackframe();
+
+ recursion_guard = true;
+ status = share_mode_do_locked_vfs_allowed(
+ fsp->file_id,
+ share_mode_do_locked_brl_fn,
+ &state);
+ recursion_guard = false;
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("share_mode_do_locked_vfs_allowed() failed for %s - %s\n",
+ fsp_str_dbg(fsp), nt_errstr(status));
+ TALLOC_FREE(frame);
+ return status;
+ }
+ if (!NT_STATUS_IS_OK(state.status)) {
+ TALLOC_FREE(frame);
+ return state.status;
+ }
+
+ TALLOC_FREE(frame);
+ return NT_STATUS_OK;
+}
+
+void brl_set_modified(struct byte_range_lock *br_lck, bool modified)
+{
+ br_lck->modified = modified;
+}
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index 62f3e2e8037..8c317b4c1f0 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -107,17 +107,42 @@ void init_strict_lock_struct(files_struct *fsp,
};
}
+struct strict_lock_check_state {
+ bool ret;
+ files_struct *fsp;
+ struct lock_struct *plock;
+};
+
+static void strict_lock_check_default_fn(struct share_mode_lock *lck,
+ struct byte_range_lock *br_lck,
+ void *private_data)
+{
+ struct strict_lock_check_state *state = private_data;
+
+ /*
+ * The caller has checked fsp->fsp_flags.can_lock and lp_locking so
+ * br_lck has to be there!
+ */
+ SMB_ASSERT(br_lck != NULL);
+
+ state->ret = brl_locktest(br_lck, state->plock, true);
+}
+
bool strict_lock_check_default(files_struct *fsp, struct lock_struct *plock)
{
struct byte_range_lock *br_lck;
int strict_locking = lp_strict_locking(fsp->conn->params);
+ NTSTATUS status;
bool ret = False;
if (plock->size == 0) {
return True;
}
- if (!lp_locking(fsp->conn->params) || !strict_locking) {
+ if (!lp_locking(fsp->conn->params) ||
+ !strict_locking ||
+ !fsp->fsp_flags.can_lock)
+ {
return True;
}
@@ -145,19 +170,28 @@ bool strict_lock_check_default(files_struct *fsp, struct lock_struct *plock)
if (!br_lck) {
return true;
}
- ret = brl_locktest(br_lck, plock);
-
+ ret = brl_locktest(br_lck, plock, false);
if (!ret) {
/*
* We got a lock conflict. Retry with rw locks to enable
* autocleanup. This is the slow path anyway.
*/
- br_lck = brl_get_locks(talloc_tos(), fsp);
- if (br_lck == NULL) {
- return true;
+
+ struct strict_lock_check_state state =
+ (struct strict_lock_check_state) {
+ .fsp = fsp,
+ .plock = plock,
+ };
+
+ status = share_mode_do_locked_brl(fsp,
+ strict_lock_check_default_fn,
+ &state);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("share_mode_do_locked_brl [%s] failed: %s\n",
+ fsp_str_dbg(fsp), nt_errstr(status));
+ state.ret = false;
}
- ret = brl_locktest(br_lck, plock);
- TALLOC_FREE(br_lck);
+ ret = state.ret;
}
DBG_DEBUG("flavour = %s brl start=%" PRIu64 " "
@@ -241,52 +275,7 @@ static void decrement_current_lock_count(files_struct *fsp,
Utility function called by locking requests.
****************************************************************************/
-struct do_lock_state {
- struct files_struct *fsp;
- TALLOC_CTX *req_mem_ctx;
- const struct GUID *req_guid;
- uint64_t smblctx;
- uint64_t count;
- uint64_t offset;
- enum brl_type lock_type;
- enum brl_flavour lock_flav;
-
- struct server_id blocker_pid;
- uint64_t blocker_smblctx;
- NTSTATUS status;
-};
-
-static void do_lock_fn(
- struct share_mode_lock *lck,
- void *private_data)
-{
- struct do_lock_state *state = private_data;
- struct byte_range_lock *br_lck = NULL;
--
Samba Shared Repository
More information about the samba-cvs
mailing list