[NTOSKRNL/fsrtl]

- Remove the right element from the list when uninitializing a file lock
- Do not modify the content of the table range while looping on its elements
- Fix rebuilding the table when unlocking a shared range
Thanks go to Pierre for the hint for where to look at
CORE-6615 #comment fixed by r57798 #resolve
CIRE-6535 #comment fixed by r55798 #resolve

svn path=/trunk/; revision=57798
This commit is contained in:
Jérôme Gardou 2012-12-04 12:09:59 +00:00
parent 39fda7c469
commit 327c78d386

View file

@ -514,8 +514,9 @@ FsRtlPrivateLock(IN PFILE_LOCK FileLock,
} }
return FALSE; return FALSE;
} }
else }
{ }
DPRINT("Overlapping shared lock %wZ %08x%08x %08x%08x\n", DPRINT("Overlapping shared lock %wZ %08x%08x %08x%08x\n",
&FileObject->FileName, &FileObject->FileName,
Conflict->Exclusive.FileLock.StartingByte.HighPart, Conflict->Exclusive.FileLock.StartingByte.HighPart,
@ -538,10 +539,6 @@ FsRtlPrivateLock(IN PFILE_LOCK FileLock,
&Status, &Status,
FileObject); FileObject);
} }
break;
}
}
}
} }
/* We got here because there were only overlapping shared locks */ /* We got here because there were only overlapping shared locks */
@ -567,8 +564,8 @@ FsRtlPrivateLock(IN PFILE_LOCK FileLock,
return FALSE; return FALSE;
} }
DPRINT("Adding shared lock %wZ\n", &FileObject->FileName); DPRINT("Adding shared lock %wZ\n", &FileObject->FileName);
NewSharedRange->Start = ToInsert.Exclusive.FileLock.StartingByte; NewSharedRange->Start = *FileOffset;
NewSharedRange->End = ToInsert.Exclusive.FileLock.EndingByte; NewSharedRange->End.QuadPart = FileOffset->QuadPart + Length->QuadPart;
NewSharedRange->Key = Key; NewSharedRange->Key = Key;
NewSharedRange->ProcessId = ToInsert.Exclusive.FileLock.ProcessId; NewSharedRange->ProcessId = ToInsert.Exclusive.FileLock.ProcessId;
InsertTailList(&LockInfo->SharedLocks, &NewSharedRange->Entry); InsertTailList(&LockInfo->SharedLocks, &NewSharedRange->Entry);
@ -639,10 +636,10 @@ FsRtlPrivateLock(IN PFILE_LOCK FileLock,
return FALSE; return FALSE;
} }
DPRINT("Adding shared lock %wZ\n", &FileObject->FileName); DPRINT("Adding shared lock %wZ\n", &FileObject->FileName);
NewSharedRange->Start = ToInsert.Exclusive.FileLock.StartingByte; NewSharedRange->Start = *FileOffset;
NewSharedRange->End = ToInsert.Exclusive.FileLock.EndingByte; NewSharedRange->End.QuadPart = FileOffset->QuadPart + Length->QuadPart;
NewSharedRange->Key = Key; NewSharedRange->Key = Key;
NewSharedRange->ProcessId = ToInsert.Exclusive.FileLock.ProcessId; NewSharedRange->ProcessId = Process->UniqueProcessId;
InsertTailList(&LockInfo->SharedLocks, &NewSharedRange->Entry); InsertTailList(&LockInfo->SharedLocks, &NewSharedRange->Entry);
} }
@ -918,12 +915,7 @@ FsRtlFastUnlockSingle(IN PFILE_LOCK FileLock,
} }
if (FoundShared) if (FoundShared)
{ {
PLIST_ENTRY SharedRangeEntry; /* Remove the found range from the shared range lists */
PLOCK_SHARED_RANGE WatchSharedRange;
COMBINED_LOCK_ELEMENT RemadeElement;
Find.Exclusive.FileLock.StartingByte = SharedRange->Start;
Find.Exclusive.FileLock.EndingByte = SharedRange->End;
SharedEntry = SharedRange->Entry.Flink;
RemoveEntryList(&SharedRange->Entry); RemoveEntryList(&SharedRange->Entry);
ExFreePoolWithTag(SharedRange, 'FSRA'); ExFreePoolWithTag(SharedRange, 'FSRA');
/* We need to rebuild the list of shared ranges. */ /* We need to rebuild the list of shared ranges. */
@ -933,19 +925,25 @@ FsRtlFastUnlockSingle(IN PFILE_LOCK FileLock,
Entry->Exclusive.FileLock.StartingByte.LowPart, Entry->Exclusive.FileLock.StartingByte.LowPart,
Entry->Exclusive.FileLock.EndingByte.HighPart, Entry->Exclusive.FileLock.EndingByte.HighPart,
Entry->Exclusive.FileLock.EndingByte.LowPart); Entry->Exclusive.FileLock.EndingByte.LowPart);
/* Copy */
RemadeElement = *Entry; /* Remember what was in there and remove it from the table */
RtlDeleteElementGenericTable(&InternalInfo->RangeTable, Entry); Find = *Entry;
RtlDeleteElementGenericTable(&InternalInfo->RangeTable, &Find);
/* Put shared locks back in place */ /* Put shared locks back in place */
for (SharedRangeEntry = InternalInfo->SharedLocks.Flink; for (SharedEntry = InternalInfo->SharedLocks.Flink;
SharedRangeEntry != &InternalInfo->SharedLocks; SharedEntry != &InternalInfo->SharedLocks;
SharedRangeEntry = SharedRangeEntry->Flink) SharedEntry = SharedEntry->Flink)
{ {
COMBINED_LOCK_ELEMENT LockElement; COMBINED_LOCK_ELEMENT LockElement;
WatchSharedRange = CONTAINING_RECORD(SharedRangeEntry, LOCK_SHARED_RANGE, Entry); SharedRange = CONTAINING_RECORD(SharedEntry, LOCK_SHARED_RANGE, Entry);
LockElement.Exclusive.FileLock.StartingByte = WatchSharedRange->Start; LockElement.Exclusive.FileLock.FileObject = FileObject;
LockElement.Exclusive.FileLock.EndingByte = WatchSharedRange->End; LockElement.Exclusive.FileLock.StartingByte = SharedRange->Start;
if (LockCompare(&InternalInfo->RangeTable, &RemadeElement, &LockElement) != GenericEqual) LockElement.Exclusive.FileLock.EndingByte = SharedRange->End;
LockElement.Exclusive.FileLock.ProcessId = SharedRange->ProcessId;
LockElement.Exclusive.FileLock.Key = SharedRange->Key;
LockElement.Exclusive.FileLock.ExclusiveLock = FALSE;
if (LockCompare(&InternalInfo->RangeTable, &Find, &LockElement) != GenericEqual)
{ {
DPRINT("Skipping range %08x%08x:%08x%08x\n", DPRINT("Skipping range %08x%08x:%08x%08x\n",
LockElement.Exclusive.FileLock.StartingByte.HighPart, LockElement.Exclusive.FileLock.StartingByte.HighPart,
@ -959,10 +957,7 @@ FsRtlFastUnlockSingle(IN PFILE_LOCK FileLock,
LockElement.Exclusive.FileLock.StartingByte.LowPart, LockElement.Exclusive.FileLock.StartingByte.LowPart,
LockElement.Exclusive.FileLock.EndingByte.HighPart, LockElement.Exclusive.FileLock.EndingByte.HighPart,
LockElement.Exclusive.FileLock.EndingByte.LowPart); LockElement.Exclusive.FileLock.EndingByte.LowPart);
RtlZeroMemory(&RemadeElement, sizeof(RemadeElement)); FsRtlpRebuildSharedLockRange(FileLock, InternalInfo, &LockElement);
RemadeElement.Exclusive.FileLock.StartingByte = WatchSharedRange->Start;
RemadeElement.Exclusive.FileLock.EndingByte = WatchSharedRange->End;
FsRtlpRebuildSharedLockRange(FileLock, InternalInfo, &RemadeElement);
} }
} }
else else
@ -971,6 +966,7 @@ FsRtlFastUnlockSingle(IN PFILE_LOCK FileLock,
} }
} }
#ifndef NDEBUG
DPRINT("Lock still has:\n"); DPRINT("Lock still has:\n");
for (SharedEntry = InternalInfo->SharedLocks.Flink; for (SharedEntry = InternalInfo->SharedLocks.Flink;
SharedEntry != &InternalInfo->SharedLocks; SharedEntry != &InternalInfo->SharedLocks;
@ -985,6 +981,7 @@ FsRtlFastUnlockSingle(IN PFILE_LOCK FileLock,
SharedRange->End.LowPart, SharedRange->End.LowPart,
SharedRange->Key); SharedRange->Key);
} }
#endif
// this is definitely the thing we want // this is definitely the thing we want
InternalInfo->Generation++; InternalInfo->Generation++;
@ -1286,7 +1283,7 @@ FsRtlUninitializeFileLock(IN PFILE_LOCK FileLock)
{ {
SharedRange = CONTAINING_RECORD(SharedEntry, LOCK_SHARED_RANGE, Entry); SharedRange = CONTAINING_RECORD(SharedEntry, LOCK_SHARED_RANGE, Entry);
SharedEntry = SharedEntry->Flink; SharedEntry = SharedEntry->Flink;
RemoveEntryList(SharedEntry); RemoveEntryList(&SharedRange->Entry);
ExFreePoolWithTag(SharedRange, 'FSRA'); ExFreePoolWithTag(SharedRange, 'FSRA');
} }
while ((Entry = RtlGetElementGenericTable(&InternalInfo->RangeTable, 0)) != NULL) while ((Entry = RtlGetElementGenericTable(&InternalInfo->RangeTable, 0)) != NULL)