OvmfPkg/VirtioFsDxe: add helper for determining access time updates
Add the VirtioFsGetFuseTimeUpdates() function, for determining whether an EFI_FILE_PROTOCOL.SetInfo() invocation requests access time updates. Cc: Ard Biesheuvel <ard.biesheuvel@arm.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Philippe Mathieu-Daudé <philmd@redhat.com> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3097 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Message-Id: <20201216211125.19496-47-lersek@redhat.com> Acked-by: Ard Biesheuvel <ard.biesheuvel@arm.com> [lersek@redhat.com: suppress bogus VS2019 warning about lack of initialization for ZeroTime]
This commit is contained in:
parent
6c33d7b2b1
commit
3cbd54b92f
|
@ -2213,3 +2213,109 @@ VirtioFsGetFuseSizeUpdate (
|
||||||
*Update = TRUE;
|
*Update = TRUE;
|
||||||
*Size = NewInfo->FileSize;
|
*Size = NewInfo->FileSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Given an EFI_FILE_INFO object received in an EFI_FILE_PROTOCOL.SetInfo()
|
||||||
|
call, determine whether updating the last access time and/or the last
|
||||||
|
modification time of the file is necessary, relative to an EFI_FILE_INFO
|
||||||
|
object describing the current state of the file.
|
||||||
|
|
||||||
|
@param[in] Info The EFI_FILE_INFO describing the current state of
|
||||||
|
the file. The caller is responsible for populating
|
||||||
|
Info on input with VirtioFsFuseAttrToEfiFileInfo(),
|
||||||
|
from the current FUSE attributes of the file. The
|
||||||
|
Info->Size and Info->FileName members are ignored.
|
||||||
|
|
||||||
|
@param[in] NewInfo The EFI_FILE_INFO object received in the
|
||||||
|
EFI_FILE_PROTOCOL.SetInfo() call.
|
||||||
|
|
||||||
|
@param[out] UpdateAtime Set to TRUE on output if the last access time needs
|
||||||
|
to be updated. Set to FALSE otherwise.
|
||||||
|
|
||||||
|
@param[out] UpdateMtime Set to TRUE on output if the last modification time
|
||||||
|
needs to be updated. Set to FALSE otherwise.
|
||||||
|
|
||||||
|
@param[out] Atime If UpdateAtime is set to TRUE, then Atime provides
|
||||||
|
the last access timestamp to set (as seconds since
|
||||||
|
the Epoch). Otherwise, Atime is not written to.
|
||||||
|
|
||||||
|
@param[out] Mtime If UpdateMtime is set to TRUE, then Mtime provides
|
||||||
|
the last modification timestamp to set (as seconds
|
||||||
|
since the Epoch). Otherwise, Mtime is not written
|
||||||
|
to.
|
||||||
|
|
||||||
|
@retval EFI_SUCCESS Output parameters have been set successfully.
|
||||||
|
|
||||||
|
@retval EFI_ACCESS_DENIED NewInfo requests changing both CreateTime and
|
||||||
|
ModificationTime, but to values that differ from
|
||||||
|
each other. The Virtio Filesystem device does not
|
||||||
|
support this.
|
||||||
|
**/
|
||||||
|
EFI_STATUS
|
||||||
|
VirtioFsGetFuseTimeUpdates (
|
||||||
|
IN EFI_FILE_INFO *Info,
|
||||||
|
IN EFI_FILE_INFO *NewInfo,
|
||||||
|
OUT BOOLEAN *UpdateAtime,
|
||||||
|
OUT BOOLEAN *UpdateMtime,
|
||||||
|
OUT UINT64 *Atime,
|
||||||
|
OUT UINT64 *Mtime
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_TIME *Time[3];
|
||||||
|
EFI_TIME *NewTime[ARRAY_SIZE (Time)];
|
||||||
|
UINTN Idx;
|
||||||
|
STATIC CONST EFI_TIME ZeroTime = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
BOOLEAN Change[ARRAY_SIZE (Time)];
|
||||||
|
UINT64 Seconds[ARRAY_SIZE (Time)];
|
||||||
|
|
||||||
|
Time[0] = &Info->CreateTime;
|
||||||
|
Time[1] = &Info->LastAccessTime;
|
||||||
|
Time[2] = &Info->ModificationTime;
|
||||||
|
NewTime[0] = &NewInfo->CreateTime;
|
||||||
|
NewTime[1] = &NewInfo->LastAccessTime;
|
||||||
|
NewTime[2] = &NewInfo->ModificationTime;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Determine which timestamps differ from the current state. (A zero time
|
||||||
|
// means "don't update", per UEFI spec.) For each timestamp that's being
|
||||||
|
// changed, calculate the seconds since the Epoch.
|
||||||
|
//
|
||||||
|
for (Idx = 0; Idx < ARRAY_SIZE (Time); Idx++) {
|
||||||
|
if (CompareMem (NewTime[Idx], &ZeroTime, sizeof (EFI_TIME)) == 0 ||
|
||||||
|
CompareMem (NewTime[Idx], Time[Idx], sizeof (EFI_TIME)) == 0) {
|
||||||
|
Change[Idx] = FALSE;
|
||||||
|
} else {
|
||||||
|
Change[Idx] = TRUE;
|
||||||
|
Seconds[Idx] = EfiTimeToEpoch (NewTime[Idx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// If a change is requested for exactly one of CreateTime and
|
||||||
|
// ModificationTime, we'll change the last modification time. If changes are
|
||||||
|
// requested for both, and to the same timestamp, we'll similarly update the
|
||||||
|
// last modification time. If changes are requested for both, but to
|
||||||
|
// different timestamps, we reject the request.
|
||||||
|
//
|
||||||
|
if (Change[0] && Change[2] && Seconds[0] != Seconds[2]) {
|
||||||
|
return EFI_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
*UpdateAtime = FALSE;
|
||||||
|
*UpdateMtime = FALSE;
|
||||||
|
|
||||||
|
if (Change[0]) {
|
||||||
|
*UpdateMtime = TRUE;
|
||||||
|
*Mtime = Seconds[0];
|
||||||
|
}
|
||||||
|
if (Change[1]) {
|
||||||
|
*UpdateAtime = TRUE;
|
||||||
|
*Atime = Seconds[1];
|
||||||
|
}
|
||||||
|
if (Change[2]) {
|
||||||
|
*UpdateMtime = TRUE;
|
||||||
|
*Mtime = Seconds[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
return EFI_SUCCESS;
|
||||||
|
}
|
||||||
|
|
|
@ -290,6 +290,16 @@ VirtioFsGetFuseSizeUpdate (
|
||||||
OUT UINT64 *Size
|
OUT UINT64 *Size
|
||||||
);
|
);
|
||||||
|
|
||||||
|
EFI_STATUS
|
||||||
|
VirtioFsGetFuseTimeUpdates (
|
||||||
|
IN EFI_FILE_INFO *Info,
|
||||||
|
IN EFI_FILE_INFO *NewInfo,
|
||||||
|
OUT BOOLEAN *UpdateAtime,
|
||||||
|
OUT BOOLEAN *UpdateMtime,
|
||||||
|
OUT UINT64 *Atime,
|
||||||
|
OUT UINT64 *Mtime
|
||||||
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Wrapper functions for FUSE commands (primitives).
|
// Wrapper functions for FUSE commands (primitives).
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in New Issue