]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/VirtioFsDxe/SimpleFsGetInfo.c
OvmfPkg/VirtioFsDxe: implement EFI_FILE_PROTOCOL.GetInfo()
[mirror_edk2.git] / OvmfPkg / VirtioFsDxe / SimpleFsGetInfo.c
CommitLineData
334c13e1
LE
1/** @file\r
2 EFI_FILE_PROTOCOL.GetInfo() 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
b6b240f9
LE
9#include <Guid/FileSystemInfo.h> // gEfiFileSystemInfoGuid\r
10#include <Guid/FileSystemVolumeLabelInfo.h> // gEfiFileSystemVolumeLabelInfo...\r
11#include <Library/BaseLib.h> // StrSize()\r
12#include <Library/BaseMemoryLib.h> // CompareGuid()\r
13\r
334c13e1
LE
14#include "VirtioFsDxe.h"\r
15\r
b6b240f9
LE
16/**\r
17 Provide EFI_FILE_INFO about this particular file.\r
18**/\r
19STATIC\r
20EFI_STATUS\r
21GetFileInfo (\r
22 IN EFI_FILE_PROTOCOL *This,\r
23 IN OUT UINTN *BufferSize,\r
24 OUT VOID *Buffer\r
25 )\r
26{\r
27 VIRTIO_FS_FILE *VirtioFsFile;\r
28 VIRTIO_FS *VirtioFs;\r
29 UINTN AllocSize;\r
30 UINTN BasenameSize;\r
31 EFI_STATUS Status;\r
32 EFI_FILE_INFO *FileInfo;\r
33 VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE FuseAttr;\r
34\r
35 VirtioFsFile = VIRTIO_FS_FILE_FROM_SIMPLE_FILE (This);\r
36 VirtioFs = VirtioFsFile->OwnerFs;\r
37\r
38 AllocSize = *BufferSize;\r
39\r
40 //\r
41 // Calculate the needed size.\r
42 //\r
43 BasenameSize = 0;\r
44 Status = VirtioFsGetBasename (VirtioFsFile->CanonicalPathname, NULL,\r
45 &BasenameSize);\r
46 ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
47 *BufferSize = OFFSET_OF (EFI_FILE_INFO, FileName) + BasenameSize;\r
48\r
49 if (*BufferSize > AllocSize) {\r
50 return EFI_BUFFER_TOO_SMALL;\r
51 }\r
52\r
53 //\r
54 // Set the structure size, and store the basename.\r
55 //\r
56 FileInfo = Buffer;\r
57 FileInfo->Size = *BufferSize;\r
58 Status = VirtioFsGetBasename (VirtioFsFile->CanonicalPathname,\r
59 FileInfo->FileName, &BasenameSize);\r
60 ASSERT_EFI_ERROR (Status);\r
61\r
62 //\r
63 // Fetch the file attributes, and convert them into the caller's buffer.\r
64 //\r
65 Status = VirtioFsFuseGetAttr (VirtioFs, VirtioFsFile->NodeId, &FuseAttr);\r
66 if (!EFI_ERROR (Status)) {\r
67 Status = VirtioFsFuseAttrToEfiFileInfo (&FuseAttr, FileInfo);\r
68 }\r
69 return (Status == EFI_BUFFER_TOO_SMALL) ? EFI_DEVICE_ERROR : Status;\r
70}\r
71\r
72/**\r
73 Provide EFI_FILE_SYSTEM_INFO about the filesystem this file lives on.\r
74**/\r
75STATIC\r
76EFI_STATUS\r
77GetFileSystemInfo (\r
78 IN EFI_FILE_PROTOCOL *This,\r
79 IN OUT UINTN *BufferSize,\r
80 OUT VOID *Buffer\r
81 )\r
82{\r
83 VIRTIO_FS_FILE *VirtioFsFile;\r
84 VIRTIO_FS *VirtioFs;\r
85 UINTN AllocSize;\r
86 UINTN LabelSize;\r
87 EFI_STATUS Status;\r
88 VIRTIO_FS_FUSE_STATFS_RESPONSE FilesysAttr;\r
89 UINT64 MaxBlocks;\r
90 EFI_FILE_SYSTEM_INFO *FilesysInfo;\r
91\r
92 VirtioFsFile = VIRTIO_FS_FILE_FROM_SIMPLE_FILE (This);\r
93 VirtioFs = VirtioFsFile->OwnerFs;\r
94\r
95 AllocSize = *BufferSize;\r
96\r
97 //\r
98 // Calculate the needed size.\r
99 //\r
100 LabelSize = StrSize (VirtioFs->Label);\r
101 *BufferSize = OFFSET_OF (EFI_FILE_SYSTEM_INFO, VolumeLabel) + LabelSize;\r
102\r
103 if (*BufferSize > AllocSize) {\r
104 return EFI_BUFFER_TOO_SMALL;\r
105 }\r
106\r
107 //\r
108 // Fetch the filesystem attributes.\r
109 //\r
110 Status = VirtioFsFuseStatFs (VirtioFs, VirtioFsFile->NodeId, &FilesysAttr);\r
111 if (EFI_ERROR (Status)) {\r
112 return (Status == EFI_BUFFER_TOO_SMALL) ? EFI_DEVICE_ERROR : Status;\r
113 }\r
114 //\r
115 // Sanity checks...\r
116 //\r
117 if (FilesysAttr.Frsize != FilesysAttr.Bsize) {\r
118 return EFI_UNSUPPORTED;\r
119 }\r
120 if (FilesysAttr.Frsize == 0 || FilesysAttr.Blocks == 0 ||\r
121 FilesysAttr.Bavail > FilesysAttr.Blocks) {\r
122 return EFI_DEVICE_ERROR;\r
123 }\r
124 MaxBlocks = DivU64x32 (MAX_UINT64, FilesysAttr.Frsize);\r
125 if (FilesysAttr.Blocks > MaxBlocks || FilesysAttr.Bavail > MaxBlocks) {\r
126 return EFI_DEVICE_ERROR;\r
127 }\r
128\r
129 //\r
130 // Fill in EFI_FILE_SYSTEM_INFO.\r
131 //\r
132 FilesysInfo = Buffer;\r
133 FilesysInfo->Size = *BufferSize;\r
134 FilesysInfo->ReadOnly = FALSE;\r
135 FilesysInfo->VolumeSize = MultU64x32 (FilesysAttr.Blocks,\r
136 FilesysAttr.Frsize);\r
137 FilesysInfo->FreeSpace = MultU64x32 (FilesysAttr.Bavail,\r
138 FilesysAttr.Frsize);\r
139 FilesysInfo->BlockSize = FilesysAttr.Frsize;\r
140 CopyMem (FilesysInfo->VolumeLabel, VirtioFs->Label, LabelSize);\r
141\r
142 return EFI_SUCCESS;\r
143}\r
144\r
145/**\r
146 Return the filesystem label as EFI_FILE_SYSTEM_VOLUME_LABEL.\r
147**/\r
148STATIC\r
149EFI_STATUS\r
150GetFileSystemVolumeLabelInfo (\r
151 IN EFI_FILE_PROTOCOL *This,\r
152 IN OUT UINTN *BufferSize,\r
153 OUT VOID *Buffer\r
154 )\r
155{\r
156 VIRTIO_FS_FILE *VirtioFsFile;\r
157 VIRTIO_FS *VirtioFs;\r
158 UINTN AllocSize;\r
159 UINTN LabelSize;\r
160 EFI_FILE_SYSTEM_VOLUME_LABEL *FilesysVolumeLabel;\r
161\r
162 VirtioFsFile = VIRTIO_FS_FILE_FROM_SIMPLE_FILE (This);\r
163 VirtioFs = VirtioFsFile->OwnerFs;\r
164\r
165 AllocSize = *BufferSize;\r
166\r
167 //\r
168 // Calculate the needed size.\r
169 //\r
170 LabelSize = StrSize (VirtioFs->Label);\r
171 *BufferSize = (OFFSET_OF (EFI_FILE_SYSTEM_VOLUME_LABEL, VolumeLabel) +\r
172 LabelSize);\r
173\r
174 if (*BufferSize > AllocSize) {\r
175 return EFI_BUFFER_TOO_SMALL;\r
176 }\r
177\r
178 //\r
179 // Store the label.\r
180 //\r
181 FilesysVolumeLabel = Buffer;\r
182 CopyMem (FilesysVolumeLabel->VolumeLabel, VirtioFs->Label, LabelSize);\r
183\r
184 return EFI_SUCCESS;\r
185}\r
186\r
334c13e1
LE
187EFI_STATUS\r
188EFIAPI\r
189VirtioFsSimpleFileGetInfo (\r
190 IN EFI_FILE_PROTOCOL *This,\r
191 IN EFI_GUID *InformationType,\r
192 IN OUT UINTN *BufferSize,\r
193 OUT VOID *Buffer\r
194 )\r
195{\r
b6b240f9
LE
196 if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {\r
197 return GetFileInfo (This, BufferSize, Buffer);\r
198 }\r
199\r
200 if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {\r
201 return GetFileSystemInfo (This, BufferSize, Buffer);\r
202 }\r
203\r
204 if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {\r
205 return GetFileSystemVolumeLabelInfo (This, BufferSize, Buffer);\r
206 }\r
207\r
208 return EFI_UNSUPPORTED;\r
334c13e1 209}\r