1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-13 13:18:06 +03:00

r14602: Fix another logic bug in new oplock handling. Just

because lck->num_share_modes != 0 doesn't mean that
there *are* other valid share modes. They may be
all marked "UNUSED" or be deferred open entries.
In that case don't downgrade the granted oplock to
level2 needlessly - a client can have an exclusive
oplock in this case. The original code handled this
correctly in the lck->num_share_modes == 0 case but
not in the case where there were no valid share modes
but lck->num_share_modes != 0. I'll clean up my
Samba4 torture tester for this and commit it tomorrow.
Jeremy.
This commit is contained in:
Jeremy Allison 2006-03-21 06:53:49 +00:00 committed by Gerald (Jerry) Carter
parent 763f4c0148
commit 306061c93d

View File

@ -612,6 +612,7 @@ static BOOL delay_for_oplocks(struct share_mode_lock *lck, files_struct *fsp)
{
int i;
struct share_mode_entry *exclusive = NULL;
BOOL valid_entry = False;
BOOL delay_it = False;
BOOL have_level2 = False;
@ -620,33 +621,36 @@ static BOOL delay_for_oplocks(struct share_mode_lock *lck, files_struct *fsp)
return False;
}
if (lck->num_share_modes == 0) {
/* No files open at all: Directly grant whatever the client
* wants. */
if (fsp->oplock_type == NO_OPLOCK) {
/* Store a level2 oplock, but don't tell the client */
fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
}
return False;
}
for (i=0; i<lck->num_share_modes; i++) {
if (!is_valid_share_mode_entry(&lck->share_modes[i])) {
continue;
}
/* At least one entry is not an invalid or deferred entry. */
valid_entry = True;
if (EXCLUSIVE_OPLOCK_TYPE(lck->share_modes[i].op_type)) {
SMB_ASSERT(exclusive == NULL);
exclusive = &lck->share_modes[i];
}
if (lck->share_modes[i].op_type == LEVEL_II_OPLOCK) {
SMB_ASSERT(exclusive == NULL);
have_level2 = True;
}
}
if (!valid_entry) {
/* All entries are placeholders or deferred.
* Directly grant whatever the client wants. */
if (fsp->oplock_type == NO_OPLOCK) {
/* Store a level2 oplock, but don't tell the client */
fsp->oplock_type = FAKE_LEVEL_II_OPLOCK;
}
return False;
}
if (exclusive != NULL) { /* Found an exclusive oplock */
SMB_ASSERT(!have_level2);
delay_it = is_delete_request(fsp) ?
@ -654,7 +658,8 @@ static BOOL delay_for_oplocks(struct share_mode_lock *lck, files_struct *fsp)
}
if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
/* We can at most grant level2 */
/* We can at most grant level2 as there are other
* level2 or NO_OPLOCK entries. */
fsp->oplock_type = LEVEL_II_OPLOCK;
}