summaryrefslogtreecommitdiff
path: root/OvmfPkg
diff options
context:
space:
mode:
authorLaszlo Ersek <lersek@redhat.com>2020-12-16 22:10:58 +0100
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2020-12-21 17:16:23 +0000
commitcd473d41dd8ba0cf400d2f4f4d4803f5dc56068e (patch)
tree68c341ac8c3c6dcb374a404f569e868ee9ab5e9e /OvmfPkg
parenta70860f4499571669f3795adf52ccb0fa02cdac1 (diff)
downloadedk2-cd473d41dd8ba0cf400d2f4f4d4803f5dc56068e.zip
edk2-cd473d41dd8ba0cf400d2f4f4d4803f5dc56068e.tar.gz
edk2-cd473d41dd8ba0cf400d2f4f4d4803f5dc56068e.tar.bz2
OvmfPkg/VirtioFsDxe: convert FUSE inode attributes to EFI_FILE_INFO
Introduce the VirtioFsFuseAttrToEfiFileInfo() function, for converting FUSE inode attributes to EFI_FILE_INFO. The EpochToEfiTime() function from EmbeddedPkg's TimeBaseLib proves invaluable for converting the file access times. This is the first time we consume TimeBaseLib in OvmfPkg, so add the necessary lib class resolution. We need not modify any ArmVirtPkg DSC files: see commit af5fed90bfbf ("ArmPlatformPkg,ArmVirtPkg: delete redundant PL031 functions", 2017-05-10). 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-22-lersek@redhat.com> Acked-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
Diffstat (limited to 'OvmfPkg')
-rw-r--r--OvmfPkg/Include/IndustryStandard/VirtioFs.h3
-rw-r--r--OvmfPkg/OvmfPkgIa32.dsc1
-rw-r--r--OvmfPkg/OvmfPkgIa32X64.dsc1
-rw-r--r--OvmfPkg/OvmfPkgX64.dsc1
-rw-r--r--OvmfPkg/VirtioFsDxe/Helpers.c119
-rw-r--r--OvmfPkg/VirtioFsDxe/VirtioFsDxe.h7
-rw-r--r--OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf2
7 files changed, 134 insertions, 0 deletions
diff --git a/OvmfPkg/Include/IndustryStandard/VirtioFs.h b/OvmfPkg/Include/IndustryStandard/VirtioFs.h
index 63aced2..5d1d990 100644
--- a/OvmfPkg/Include/IndustryStandard/VirtioFs.h
+++ b/OvmfPkg/Include/IndustryStandard/VirtioFs.h
@@ -84,6 +84,9 @@ typedef struct {
//
// File mode bitmasks.
//
+#define VIRTIO_FS_FUSE_MODE_TYPE_MASK 0170000u
+#define VIRTIO_FS_FUSE_MODE_TYPE_REG 0100000u
+#define VIRTIO_FS_FUSE_MODE_TYPE_DIR 0040000u
#define VIRTIO_FS_FUSE_MODE_PERM_RWXU 0000700u
#define VIRTIO_FS_FUSE_MODE_PERM_RUSR 0000400u
#define VIRTIO_FS_FUSE_MODE_PERM_WUSR 0000200u
diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 4ff7067..26a013e 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -125,6 +125,7 @@
BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
+ TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf
SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index d40a591..10579fe 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -129,6 +129,7 @@
BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
+ TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf
SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index ec78862..c9235e4 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -129,6 +129,7 @@
BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRepStr.inf
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
+ TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf
SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
diff --git a/OvmfPkg/VirtioFsDxe/Helpers.c b/OvmfPkg/VirtioFsDxe/Helpers.c
index 8ffdabf..e9582e4 100644
--- a/OvmfPkg/VirtioFsDxe/Helpers.c
+++ b/OvmfPkg/VirtioFsDxe/Helpers.c
@@ -9,6 +9,7 @@
#include <Library/BaseLib.h> // StrLen()
#include <Library/BaseMemoryLib.h> // CopyMem()
#include <Library/MemoryAllocationLib.h> // AllocatePool()
+#include <Library/TimeBaseLib.h> // EpochToEfiTime()
#include <Library/VirtioLib.h> // Virtio10WriteFeatures()
#include "VirtioFsDxe.h"
@@ -1589,3 +1590,121 @@ FreeRhsPath8:
FreePool (RhsPath8);
return Status;
}
+
+/**
+ Convert select fields of a VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE object to
+ corresponding fields in EFI_FILE_INFO.
+
+ @param[in] FuseAttr The VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE object to
+ convert the relevant fields from.
+
+ @param[out] FileInfo The EFI_FILE_INFO structure to modify. Importantly, the
+ FileInfo->Size and FileInfo->FileName fields are not
+ overwritten.
+
+ @retval EFI_SUCCESS Conversion successful.
+
+ @retval EFI_UNSUPPORTED The allocated size of the file is inexpressible in
+ EFI_FILE_INFO.
+
+ @retval EFI_UNSUPPORTED One of the file access times is inexpressible in
+ EFI_FILE_INFO.
+
+ @retval EFI_UNSUPPORTED The file type is inexpressible in EFI_FILE_INFO.
+
+ @retval EFI_UNSUPPORTED The file is a regular file that has multiple names
+ on the host side (i.e., its hard link count is
+ greater than one).
+**/
+EFI_STATUS
+VirtioFsFuseAttrToEfiFileInfo (
+ IN VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE *FuseAttr,
+ OUT EFI_FILE_INFO *FileInfo
+ )
+{
+ UINT64 EpochTime[3];
+ EFI_TIME *ConvertedTime[ARRAY_SIZE (EpochTime)];
+ UINTN Idx;
+
+ FileInfo->FileSize = FuseAttr->Size;
+
+ //
+ // The unit for FuseAttr->Blocks is 512B.
+ //
+ if (FuseAttr->Blocks >= BIT55) {
+ return EFI_UNSUPPORTED;
+ }
+ FileInfo->PhysicalSize = LShiftU64 (FuseAttr->Blocks, 9);
+
+ //
+ // Convert the timestamps. File creation time is not tracked by the Virtio
+ // Filesystem device, so set FileInfo->CreateTime from FuseAttr->Mtime as
+ // well.
+ //
+ EpochTime[0] = FuseAttr->Mtime;
+ EpochTime[1] = FuseAttr->Atime;
+ EpochTime[2] = FuseAttr->Mtime;
+ ConvertedTime[0] = &FileInfo->CreateTime;
+ ConvertedTime[1] = &FileInfo->LastAccessTime;
+ ConvertedTime[2] = &FileInfo->ModificationTime;
+
+ for (Idx = 0; Idx < ARRAY_SIZE (EpochTime); Idx++) {
+ //
+ // EpochToEfiTime() takes a UINTN for seconds.
+ //
+ if (EpochTime[Idx] > MAX_UINTN) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Set the following fields in the converted time: Year, Month, Day, Hour,
+ // Minute, Second, Nanosecond.
+ //
+ EpochToEfiTime ((UINTN)EpochTime[Idx], ConvertedTime[Idx]);
+ //
+ // The times are all expressed in UTC. Consequently, they are not affected
+ // by daylight saving.
+ //
+ ConvertedTime[Idx]->TimeZone = 0;
+ ConvertedTime[Idx]->Daylight = 0;
+ //
+ // Clear the padding fields.
+ //
+ ConvertedTime[Idx]->Pad1 = 0;
+ ConvertedTime[Idx]->Pad2 = 0;
+ }
+
+ //
+ // Set the attributes.
+ //
+ switch (FuseAttr->Mode & VIRTIO_FS_FUSE_MODE_TYPE_MASK) {
+ case VIRTIO_FS_FUSE_MODE_TYPE_DIR:
+ FileInfo->Attribute = EFI_FILE_DIRECTORY;
+ break;
+ case VIRTIO_FS_FUSE_MODE_TYPE_REG:
+ FileInfo->Attribute = 0;
+ break;
+ default:
+ //
+ // Other file types are not supported.
+ //
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Report the regular file or directory as read-only if all classes lack
+ // write permission.
+ //
+ if ((FuseAttr->Mode & (VIRTIO_FS_FUSE_MODE_PERM_WUSR |
+ VIRTIO_FS_FUSE_MODE_PERM_WGRP |
+ VIRTIO_FS_FUSE_MODE_PERM_WOTH)) == 0) {
+ FileInfo->Attribute |= EFI_FILE_READ_ONLY;
+ }
+
+ //
+ // A hard link count greater than 1 is not supported for regular files.
+ //
+ if ((FileInfo->Attribute & EFI_FILE_DIRECTORY) == 0 && FuseAttr->Nlink > 1) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h b/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h
index 795cf4e..6cc5257 100644
--- a/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h
+++ b/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h
@@ -11,6 +11,7 @@
#define VIRTIO_FS_DXE_H_
#include <Base.h> // SIGNATURE_64()
+#include <Guid/FileInfo.h> // EFI_FILE_INFO
#include <IndustryStandard/VirtioFs.h> // VIRTIO_FS_TAG_BYTES
#include <Library/DebugLib.h> // CR()
#include <Protocol/SimpleFileSystem.h> // EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
@@ -225,6 +226,12 @@ VirtioFsAppendPath (
OUT BOOLEAN *RootEscape
);
+EFI_STATUS
+VirtioFsFuseAttrToEfiFileInfo (
+ IN VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE *FuseAttr,
+ OUT EFI_FILE_INFO *FileInfo
+ );
+
//
// Wrapper functions for FUSE commands (primitives).
//
diff --git a/OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf b/OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf
index b942baa..7d72721 100644
--- a/OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf
+++ b/OvmfPkg/VirtioFsDxe/VirtioFsDxe.inf
@@ -77,6 +77,7 @@
ENTRY_POINT = VirtioFsEntryPoint
[Packages]
+ EmbeddedPkg/EmbeddedPkg.dec
MdePkg/MdePkg.dec
OvmfPkg/OvmfPkg.dec
@@ -110,6 +111,7 @@
BaseMemoryLib
DebugLib
MemoryAllocationLib
+ TimeBaseLib
UefiBootServicesTableLib
UefiDriverEntryPoint
VirtioLib