From c4edb49b4f074f8d22a9c5e8f337dc29658de01c Mon Sep 17 00:00:00 2001 From: Laszlo Ersek Date: Wed, 16 Dec 2020 22:11:08 +0100 Subject: [PATCH] OvmfPkg/VirtioFsDxe: implement EFI_FILE_PROTOCOL.GetPosition, .SetPosition MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Using the functions introduced previously, we can now implement VirtioFsSimpleFileGetPosition() and VirtioFsSimpleFileSetPosition(). Cc: Ard Biesheuvel Cc: Jordan Justen Cc: Philippe Mathieu-Daudé Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3097 Signed-off-by: Laszlo Ersek Message-Id: <20201216211125.19496-32-lersek@redhat.com> Acked-by: Ard Biesheuvel --- OvmfPkg/VirtioFsDxe/SimpleFsGetPosition.c | 9 ++++- OvmfPkg/VirtioFsDxe/SimpleFsOpen.c | 1 + OvmfPkg/VirtioFsDxe/SimpleFsOpenVolume.c | 1 + OvmfPkg/VirtioFsDxe/SimpleFsSetPosition.c | 40 ++++++++++++++++++++++- OvmfPkg/VirtioFsDxe/VirtioFsDxe.h | 1 + 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/OvmfPkg/VirtioFsDxe/SimpleFsGetPosition.c b/OvmfPkg/VirtioFsDxe/SimpleFsGetPosition.c index 2f40d2be26..53212621e9 100644 --- a/OvmfPkg/VirtioFsDxe/SimpleFsGetPosition.c +++ b/OvmfPkg/VirtioFsDxe/SimpleFsGetPosition.c @@ -16,5 +16,12 @@ VirtioFsSimpleFileGetPosition ( OUT UINT64 *Position ) { - return EFI_DEVICE_ERROR; + VIRTIO_FS_FILE *VirtioFsFile; + + VirtioFsFile = VIRTIO_FS_FILE_FROM_SIMPLE_FILE (This); + if (VirtioFsFile->IsDirectory) { + return EFI_UNSUPPORTED; + } + *Position = VirtioFsFile->FilePosition; + return EFI_SUCCESS; } diff --git a/OvmfPkg/VirtioFsDxe/SimpleFsOpen.c b/OvmfPkg/VirtioFsDxe/SimpleFsOpen.c index 2649c796ac..7c50ce9c0e 100644 --- a/OvmfPkg/VirtioFsDxe/SimpleFsOpen.c +++ b/OvmfPkg/VirtioFsDxe/SimpleFsOpen.c @@ -479,6 +479,7 @@ VirtioFsSimpleFileOpen ( NewVirtioFsFile->IsOpenForWriting = OpenForWriting; NewVirtioFsFile->OwnerFs = VirtioFs; NewVirtioFsFile->CanonicalPathname = NewCanonicalPath; + NewVirtioFsFile->FilePosition = 0; NewVirtioFsFile->NodeId = NewNodeId; NewVirtioFsFile->FuseHandle = NewFuseHandle; diff --git a/OvmfPkg/VirtioFsDxe/SimpleFsOpenVolume.c b/OvmfPkg/VirtioFsDxe/SimpleFsOpenVolume.c index 9c0ab434c1..1181191d27 100644 --- a/OvmfPkg/VirtioFsDxe/SimpleFsOpenVolume.c +++ b/OvmfPkg/VirtioFsDxe/SimpleFsOpenVolume.c @@ -72,6 +72,7 @@ VirtioFsOpenVolume ( VirtioFsFile->IsOpenForWriting = FALSE; VirtioFsFile->OwnerFs = VirtioFs; VirtioFsFile->CanonicalPathname = CanonicalPathname; + VirtioFsFile->FilePosition = 0; VirtioFsFile->NodeId = VIRTIO_FS_FUSE_ROOT_DIR_NODE_ID; VirtioFsFile->FuseHandle = RootDirHandle; diff --git a/OvmfPkg/VirtioFsDxe/SimpleFsSetPosition.c b/OvmfPkg/VirtioFsDxe/SimpleFsSetPosition.c index ee8cb1f4e4..ac62853026 100644 --- a/OvmfPkg/VirtioFsDxe/SimpleFsSetPosition.c +++ b/OvmfPkg/VirtioFsDxe/SimpleFsSetPosition.c @@ -16,5 +16,43 @@ VirtioFsSimpleFileSetPosition ( IN UINT64 Position ) { - return EFI_DEVICE_ERROR; + VIRTIO_FS_FILE *VirtioFsFile; + VIRTIO_FS *VirtioFs; + EFI_STATUS Status; + VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE FuseAttr; + + VirtioFsFile = VIRTIO_FS_FILE_FROM_SIMPLE_FILE (This); + + // + // Directories can only be rewound, per spec. + // + if (VirtioFsFile->IsDirectory) { + if (Position != 0) { + return EFI_UNSUPPORTED; + } + VirtioFsFile->FilePosition = 0; + return EFI_SUCCESS; + } + + // + // Regular file. + // + if (Position < MAX_UINT64) { + // + // Caller is requesting absolute file position. + // + VirtioFsFile->FilePosition = Position; + return EFI_SUCCESS; + } + + // + // Caller is requesting a seek to EOF. + // + VirtioFs = VirtioFsFile->OwnerFs; + Status = VirtioFsFuseGetAttr (VirtioFs, VirtioFsFile->NodeId, &FuseAttr); + if (EFI_ERROR (Status)) { + return Status; + } + VirtioFsFile->FilePosition = FuseAttr.Size; + return EFI_SUCCESS; } diff --git a/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h b/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h index d1b746c0d8..948fcfb6b6 100644 --- a/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h +++ b/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h @@ -139,6 +139,7 @@ typedef struct { VIRTIO_FS *OwnerFs; LIST_ENTRY OpenFilesEntry; CHAR8 *CanonicalPathname; + UINT64 FilePosition; // // In the FUSE wire protocol, every request except FUSE_INIT refers to a // file, namely by the "VIRTIO_FS_FUSE_REQUEST.NodeId" field; that is, by the -- 2.39.2