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:
parent
763f4c0148
commit
306061c93d
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user