diff options
author | Volker Lendecke <vl@samba.org> | 2013-09-25 18:41:07 -0700 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2013-10-12 01:56:18 +0200 |
commit | 7a6d240b7fa5ac365af3b615f154017ac83d0942 (patch) | |
tree | 1ef40232d8b16320bac1888b90f526766bd72a69 /source3/smbd | |
parent | 672c22831032b862a11259ddb1e0cc8ef9ba0d26 (diff) | |
download | samba-7a6d240b7fa5ac365af3b615f154017ac83d0942.tar.gz samba-7a6d240b7fa5ac365af3b615f154017ac83d0942.tar.bz2 samba-7a6d240b7fa5ac365af3b615f154017ac83d0942.zip |
smbd: Fix the extended *.oplock.doc1 tests
We need to check for DELETE_PENDING before the first oplock break
Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Sat Oct 12 01:56:18 CEST 2013 on sn-devel-104
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/open.c | 59 |
1 files changed, 33 insertions, 26 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 5024c90285..6255180ad1 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -1093,6 +1093,26 @@ bool is_stat_open(uint32 access_mask) ((access_mask & ~stat_open_bits) == 0)); } +static bool has_delete_on_close(struct share_mode_lock *lck, + uint32_t name_hash) +{ + struct share_mode_data *d = lck->data; + uint32_t i; + + if (d->num_share_modes == 0) { + return false; + } + if (!is_delete_on_close_set(lck, name_hash)) { + return false; + } + for (i=0; i<d->num_share_modes; i++) { + if (!share_mode_stale_pid(d, i)) { + return true; + } + } + return false; +} + /**************************************************************************** Deal with share modes Invarient: Share mode must be locked on entry and exit. @@ -1113,25 +1133,6 @@ static NTSTATUS open_mode_check(connection_struct *conn, return NT_STATUS_OK; } - /* A delete on close prohibits everything */ - - if (is_delete_on_close_set(lck, name_hash)) { - /* - * Check the delete on close token - * is valid. It could have been left - * after a server crash. - */ - for(i = 0; i < lck->data->num_share_modes; i++) { - if (!share_mode_stale_pid(lck->data, i)) { - - *file_existed = true; - - return NT_STATUS_DELETE_PENDING; - } - } - return NT_STATUS_OK; - } - if (is_stat_open(access_mask)) { /* Stat open that doesn't trigger oplock breaks or share mode * checks... ! JRA. */ @@ -2416,6 +2417,12 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, &got_level2_oplock, &got_a_none_oplock); + if (has_delete_on_close(lck, fsp->name_hash)) { + TALLOC_FREE(lck); + fd_close(fsp); + return NT_STATUS_DELETE_PENDING; + } + /* First pass - send break only on batch oplocks. */ if ((req != NULL) && delay_for_batch_oplocks(fsp, @@ -2450,13 +2457,6 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn, } } - if (NT_STATUS_EQUAL(status, NT_STATUS_DELETE_PENDING)) { - /* DELETE_PENDING is not deferred for a second */ - TALLOC_FREE(lck); - fd_close(fsp); - return status; - } - if (!NT_STATUS_IS_OK(status)) { uint32 can_access_mask; bool can_access = True; @@ -3166,6 +3166,13 @@ static NTSTATUS open_directory(connection_struct *conn, return NT_STATUS_SHARING_VIOLATION; } + if (has_delete_on_close(lck, fsp->name_hash)) { + TALLOC_FREE(lck); + fd_close(fsp); + file_free(req, fsp); + return NT_STATUS_DELETE_PENDING; + } + status = open_mode_check(conn, lck, fsp->name_hash, access_mask, share_access, create_options, &dir_existed); |