MdeModulePkg/Variable/RuntimeDxe: Fix return status from Reclaim()

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2844

Update Reclaim() to return the error status from the reclaim
operation and not the status of SynchronizeRuntimeVariableCache()
that can be EFI_SUCCESS even through the status from reclaim
is an error.  Without this change, the return status from
SetVariable() can be EFI_SUCCESS even though the variable was
not actually set.  This occurs if the variable store is full
and a Reclaim() is invoked to free up space and even after all
possible space is freed, there is still not enough room for
the variable being set.  This condition should return
EFI_OUT_OF_RESOURCES.

Cc: Hao A Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Reviewed-by: Hao A Wu <hao.a.wu@intel.com>
Reviewed-by: Jian J Wang <jian.j.wang@intel.com>
This commit is contained in:
Michael D Kinney 2020-07-09 19:41:15 -07:00 committed by mergify[bot]
parent 9c6f3545ae
commit 256c4470f8

View File

@ -531,6 +531,7 @@ Reclaim (
VOID *Point1;
BOOLEAN FoundAdded;
EFI_STATUS Status;
EFI_STATUS DoneStatus;
UINTN CommonVariableTotalSize;
UINTN CommonUserVariableTotalSize;
UINTN HwErrVariableTotalSize;
@ -774,25 +775,30 @@ Reclaim (
}
Done:
DoneStatus = EFI_SUCCESS;
if (IsVolatile || mVariableModuleGlobal->VariableGlobal.EmuNvMode) {
Status = SynchronizeRuntimeVariableCache (
&mVariableModuleGlobal->VariableGlobal.VariableRuntimeCacheContext.VariableRuntimeVolatileCache,
0,
VariableStoreHeader->Size
);
ASSERT_EFI_ERROR (Status);
DoneStatus = SynchronizeRuntimeVariableCache (
&mVariableModuleGlobal->VariableGlobal.VariableRuntimeCacheContext.VariableRuntimeVolatileCache,
0,
VariableStoreHeader->Size
);
ASSERT_EFI_ERROR (DoneStatus);
FreePool (ValidBuffer);
} else {
//
// For NV variable reclaim, we use mNvVariableCache as the buffer, so copy the data back.
//
CopyMem (mNvVariableCache, (UINT8 *) (UINTN) VariableBase, VariableStoreHeader->Size);
Status = SynchronizeRuntimeVariableCache (
&mVariableModuleGlobal->VariableGlobal.VariableRuntimeCacheContext.VariableRuntimeNvCache,
0,
VariableStoreHeader->Size
);
ASSERT_EFI_ERROR (Status);
DoneStatus = SynchronizeRuntimeVariableCache (
&mVariableModuleGlobal->VariableGlobal.VariableRuntimeCacheContext.VariableRuntimeNvCache,
0,
VariableStoreHeader->Size
);
ASSERT_EFI_ERROR (DoneStatus);
}
if (!EFI_ERROR (Status) && EFI_ERROR (DoneStatus)) {
Status = DoneStatus;
}
return Status;