mirror of https://github.com/acidanthera/audk.git
FatPkg/EnhancedFatDxe: Ensure traverse of subtasks is delete-safe
Within function FatQueueTask(), the traverse of FAT subtasks for executing the disk read/write is not delete-safe. For the below case: FatDiskIo(): When non-blocking access, creates subtasks and creates event (FatOnAccessComplete, NOTIFY level) when subtasks finish. FatQueueTask(): Traverses the subtasks and submits them one by one at Tpl lower than NOTIFY. Disk R/W completes really quick. FatOnAccessComplete(): Removes the finished subtask, causing the traverse in FatQueueTask() broken. This commits will refine the subtask traverse in FatQueueTask() to be delete-safe. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Hao Wu <hao.a.wu@intel.com> Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
This commit is contained in:
parent
104bbee55e
commit
2551014719
|
@ -132,6 +132,7 @@ FatQueueTask (
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
LIST_ENTRY *Link;
|
LIST_ENTRY *Link;
|
||||||
|
LIST_ENTRY *NextLink;
|
||||||
FAT_SUBTASK *Subtask;
|
FAT_SUBTASK *Subtask;
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -149,9 +150,17 @@ FatQueueTask (
|
||||||
EfiReleaseLock (&FatTaskLock);
|
EfiReleaseLock (&FatTaskLock);
|
||||||
|
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
for ( Link = GetFirstNode (&Task->Subtasks)
|
//
|
||||||
; !IsNull (&Task->Subtasks, Link)
|
// Use NextLink to store the next link of the list, because Link might be remove from the
|
||||||
; Link = GetNextNode (&Task->Subtasks, Link)
|
// doubly-linked list and get freed in the end of current loop.
|
||||||
|
//
|
||||||
|
// Also, list operation APIs like IsNull() and GetNextNode() are avoided during the loop, since
|
||||||
|
// they may check the validity of doubly-linked lists by traversing them. These APIs cannot
|
||||||
|
// handle list elements being removed during the traverse.
|
||||||
|
//
|
||||||
|
for ( Link = GetFirstNode (&Task->Subtasks), NextLink = GetNextNode (&Task->Subtasks, Link)
|
||||||
|
; Link != &Task->Subtasks
|
||||||
|
; Link = NextLink, NextLink = Link->ForwardLink
|
||||||
) {
|
) {
|
||||||
Subtask = CR (Link, FAT_SUBTASK, Link, FAT_SUBTASK_SIGNATURE);
|
Subtask = CR (Link, FAT_SUBTASK, Link, FAT_SUBTASK_SIGNATURE);
|
||||||
if (Subtask->Write) {
|
if (Subtask->Write) {
|
||||||
|
|
Loading…
Reference in New Issue