]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/VirtioFsDxe/SimpleFsRead.c
OvmfPkg/VirtioFsDxe: implement EFI_FILE_PROTOCOL.Read() for regular files
[mirror_edk2.git] / OvmfPkg / VirtioFsDxe / SimpleFsRead.c
CommitLineData
334c13e1
LE
1/** @file\r
2 EFI_FILE_PROTOCOL.Read() member function for the Virtio Filesystem driver.\r
3\r
4 Copyright (C) 2020, Red Hat, Inc.\r
5\r
6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
7**/\r
8\r
9#include "VirtioFsDxe.h"\r
10\r
1c05df69
LE
11/**\r
12 Read from a regular file.\r
13**/\r
14STATIC\r
15EFI_STATUS\r
16ReadRegularFile (\r
17 IN OUT VIRTIO_FS_FILE *VirtioFsFile,\r
18 IN OUT UINTN *BufferSize,\r
19 OUT VOID *Buffer\r
20 )\r
21{\r
22 VIRTIO_FS *VirtioFs;\r
23 EFI_STATUS Status;\r
24 VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE FuseAttr;\r
25 UINTN Transferred;\r
26 UINTN Left;\r
27\r
28 VirtioFs = VirtioFsFile->OwnerFs;\r
29 //\r
30 // The UEFI spec forbids reads that start beyond the end of the file.\r
31 //\r
32 Status = VirtioFsFuseGetAttr (VirtioFs, VirtioFsFile->NodeId, &FuseAttr);\r
33 if (EFI_ERROR (Status) || VirtioFsFile->FilePosition > FuseAttr.Size) {\r
34 return EFI_DEVICE_ERROR;\r
35 }\r
36\r
37 Status = EFI_SUCCESS;\r
38 Transferred = 0;\r
39 Left = *BufferSize;\r
40 while (Left > 0) {\r
41 UINT32 ReadSize;\r
42\r
43 //\r
44 // FUSE_READ cannot express a >=4GB buffer size.\r
45 //\r
46 ReadSize = (UINT32)MIN ((UINTN)MAX_UINT32, Left);\r
47 Status = VirtioFsFuseReadFileOrDir (\r
48 VirtioFs,\r
49 VirtioFsFile->NodeId,\r
50 VirtioFsFile->FuseHandle,\r
51 FALSE, // IsDir\r
52 VirtioFsFile->FilePosition + Transferred,\r
53 &ReadSize,\r
54 (UINT8 *)Buffer + Transferred\r
55 );\r
56 if (EFI_ERROR (Status) || ReadSize == 0) {\r
57 break;\r
58 }\r
59 Transferred += ReadSize;\r
60 Left -= ReadSize;\r
61 }\r
62\r
63 *BufferSize = Transferred;\r
64 VirtioFsFile->FilePosition += Transferred;\r
65 //\r
66 // If we managed to read some data, return success. If zero bytes were\r
67 // transferred due to zero-sized buffer on input or due to EOF on first read,\r
68 // return SUCCESS. Otherwise, return the error due to which zero bytes were\r
69 // transferred.\r
70 //\r
71 return (Transferred > 0) ? EFI_SUCCESS : Status;\r
72}\r
73\r
334c13e1
LE
74EFI_STATUS\r
75EFIAPI\r
76VirtioFsSimpleFileRead (\r
77 IN EFI_FILE_PROTOCOL *This,\r
78 IN OUT UINTN *BufferSize,\r
79 OUT VOID *Buffer\r
80 )\r
81{\r
1c05df69
LE
82 VIRTIO_FS_FILE *VirtioFsFile;\r
83 EFI_STATUS Status;\r
84\r
85 VirtioFsFile = VIRTIO_FS_FILE_FROM_SIMPLE_FILE (This);\r
86\r
87 if (VirtioFsFile->IsDirectory) {\r
88 Status = EFI_NO_MEDIA;\r
89 } else {\r
90 Status = ReadRegularFile (VirtioFsFile, BufferSize, Buffer);\r
91 }\r
92 return Status;\r
334c13e1 93}\r