SimpleFsGetInfo.c 6.2 KB

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