1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-26 10:04:02 +03:00

s3: Fix an assert to trigger in close_remove_share_mode

In case we have a left-over entry in the share mode entry array,
the SMB_ASSERT(got_tokens) is likely to kick in. It happens when
we are about to delete a file with initial delete on close. We don't
have a delete on close token set in the locking.tdb record. We see
the fsp->initial_delete_on_close set, add the delete_on_close token
to lck. Then "delete_file" is being set to true. Then later on we
do the notify_deferred_opens. This walks the list, also checking
for share_mode_stale_pid. We have already deleted our own share
mode entry, share_mode_stale_pid() sees the left-over entry. It not
also deletes that one but also the delete on close token. This leads
to a different view of "delete_file" a.k.a. "got_tokens" further
down in close_remove_share_mode, leading the SMB_ASSERT to fire.

This patch attempts to fix the issue by keeping around our own share
mode entry for almost the whole routine, preventing share_mode_stale_pid()
from removing the delete tokens.

Pair-Programmed-With: Volker Lendecke <vl@samba.org>
This commit is contained in:
Stefan Metzmacher 2012-06-01 16:29:51 +02:00
parent b9e11bd63e
commit d792f59aeb

View File

@ -332,6 +332,7 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
enum file_close_type close_type)
{
connection_struct *conn = fsp->conn;
struct server_id self = messaging_server_id(conn->sconn->msg_ctx);
bool delete_file = false;
bool changed_user = false;
struct share_mode_lock *lck = NULL;
@ -386,12 +387,6 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
}
}
if (!del_share_mode(lck, fsp)) {
DEBUG(0, ("close_remove_share_mode: Could not delete share "
"entry for file %s\n",
fsp_str_dbg(fsp)));
}
if (fsp->initial_delete_on_close &&
!is_delete_on_close_set(lck, fsp->name_hash)) {
bool became_user = False;
@ -432,6 +427,10 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
&& (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
continue;
}
if (procid_equal(&self, &e->pid) &&
(e->share_file_id == fsp->fh->gen_id)) {
continue;
}
if (share_mode_stale_pid(lck->data, i)) {
continue;
}
@ -452,6 +451,13 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
normal_close = (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE);
if (!normal_close || !delete_file) {
if (!del_share_mode(lck, fsp)) {
DEBUG(0, ("close_remove_share_mode: Could not delete "
"share entry for file %s\n",
fsp_str_dbg(fsp)));
}
TALLOC_FREE(lck);
return NT_STATUS_OK;
}
@ -571,6 +577,11 @@ static NTSTATUS close_remove_share_mode(files_struct *fsp,
pop_sec_ctx();
}
if (!del_share_mode(lck, fsp)) {
DEBUG(0, ("close_remove_share_mode: Could not delete share "
"entry for file %s\n", fsp_str_dbg(fsp)));
}
TALLOC_FREE(lck);
if (delete_file) {