VirtioFsDxe.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. /** @file
  2. Internal macro definitions, type definitions, and function declarations for
  3. the Virtio Filesystem device driver.
  4. Copyright (C) 2020, Red Hat, Inc.
  5. SPDX-License-Identifier: BSD-2-Clause-Patent
  6. **/
  7. #ifndef VIRTIO_FS_DXE_H_
  8. #define VIRTIO_FS_DXE_H_
  9. #include <Base.h> // SIGNATURE_64()
  10. #include <Guid/FileInfo.h> // EFI_FILE_INFO
  11. #include <IndustryStandard/VirtioFs.h> // VIRTIO_FS_TAG_BYTES
  12. #include <Library/DebugLib.h> // CR()
  13. #include <Protocol/SimpleFileSystem.h> // EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
  14. #include <Protocol/VirtioDevice.h> // VIRTIO_DEVICE_PROTOCOL
  15. #include <Uefi/UefiBaseType.h> // EFI_EVENT
  16. #define VIRTIO_FS_SIG SIGNATURE_64 ('V', 'I', 'R', 'T', 'I', 'O', 'F', 'S')
  17. #define VIRTIO_FS_FILE_SIG \
  18. SIGNATURE_64 ('V', 'I', 'O', 'F', 'S', 'F', 'I', 'L')
  19. //
  20. // The following limit applies to two kinds of pathnames.
  21. //
  22. // - The length of a POSIX-style, canonical pathname *at rest* never exceeds
  23. // VIRTIO_FS_MAX_PATHNAME_LENGTH. (Length is defined as the number of CHAR8
  24. // elements in the canonical pathname, excluding the terminating '\0'.) This
  25. // is an invariant that is ensured for canonical pathnames created, and that
  26. // is assumed about canonical pathname inputs (which all originate
  27. // internally).
  28. //
  29. // - If the length of a UEFI-style pathname *argument*, originating directly or
  30. // indirectly from the EFI_FILE_PROTOCOL caller, exceeds
  31. // VIRTIO_FS_MAX_PATHNAME_LENGTH, then the argument is rejected. (Length is
  32. // defined as the number of CHAR16 elements in the UEFI-style pathname,
  33. // excluding the terminating L'\0'.) This is a restriction that's checked on
  34. // external UEFI-style pathname inputs.
  35. //
  36. // The limit is not expected to be a practical limitation; it's only supposed
  37. // to prevent attempts at overflowing size calculations. For both kinds of
  38. // pathnames, separate limits could be used; a common limit is used purely for
  39. // simplicity.
  40. //
  41. #define VIRTIO_FS_MAX_PATHNAME_LENGTH ((UINTN)65535)
  42. //
  43. // Maximum value for VIRTIO_FS_FILE.NumFileInfo.
  44. //
  45. #define VIRTIO_FS_FILE_MAX_FILE_INFO 256
  46. //
  47. // Filesystem label encoded in UCS-2, transformed from the UTF-8 representation
  48. // in "VIRTIO_FS_CONFIG.Tag", and NUL-terminated. Only the printable ASCII code
  49. // points (U+0020 through U+007E) are supported.
  50. //
  51. typedef CHAR16 VIRTIO_FS_LABEL[VIRTIO_FS_TAG_BYTES + 1];
  52. //
  53. // Main context structure, expressing an EFI_SIMPLE_FILE_SYSTEM_PROTOCOL
  54. // interface on top of the Virtio Filesystem device.
  55. //
  56. typedef struct {
  57. //
  58. // Parts of this structure are initialized / torn down in various functions
  59. // at various call depths. The table to the right should make it easier to
  60. // track them.
  61. //
  62. // field init function init depth
  63. // ----------- ------------------ ----------
  64. UINT64 Signature; // DriverBindingStart 0
  65. VIRTIO_DEVICE_PROTOCOL *Virtio; // DriverBindingStart 0
  66. VIRTIO_FS_LABEL Label; // VirtioFsInit 1
  67. UINT16 QueueSize; // VirtioFsInit 1
  68. VRING Ring; // VirtioRingInit 2
  69. VOID *RingMap; // VirtioRingMap 2
  70. UINT64 RequestId; // FuseInitSession 1
  71. UINT32 MaxWrite; // FuseInitSession 1
  72. EFI_EVENT ExitBoot; // DriverBindingStart 0
  73. LIST_ENTRY OpenFiles; // DriverBindingStart 0
  74. EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFs; // DriverBindingStart 0
  75. } VIRTIO_FS;
  76. #define VIRTIO_FS_FROM_SIMPLE_FS(SimpleFsReference) \
  77. CR (SimpleFsReference, VIRTIO_FS, SimpleFs, VIRTIO_FS_SIG);
  78. //
  79. // Structure for describing a contiguous buffer, potentially mapped for Virtio
  80. // transfer.
  81. //
  82. typedef struct {
  83. //
  84. // The following fields originate from the owner of the buffer.
  85. //
  86. VOID *Buffer;
  87. UINTN Size;
  88. //
  89. // All of the fields below, until the end of the structure, are
  90. // zero-initialized when the structure is initially validated.
  91. //
  92. // Mapped, MappedAddress and Mapping are updated when the buffer is mapped
  93. // for VirtioOperationBusMasterRead or VirtioOperationBusMasterWrite. They
  94. // are again updated when the buffer is unmapped.
  95. //
  96. BOOLEAN Mapped;
  97. EFI_PHYSICAL_ADDRESS MappedAddress;
  98. VOID *Mapping;
  99. //
  100. // Transferred is updated after VirtioFlush() returns successfully:
  101. // - for VirtioOperationBusMasterRead, Transferred is set to Size;
  102. // - for VirtioOperationBusMasterWrite, Transferred is calculated from the
  103. // UsedLen output parameter of VirtioFlush().
  104. //
  105. UINTN Transferred;
  106. } VIRTIO_FS_IO_VECTOR;
  107. //
  108. // Structure for describing a list of IO Vectors.
  109. //
  110. typedef struct {
  111. //
  112. // The following fields originate from the owner of the buffers.
  113. //
  114. VIRTIO_FS_IO_VECTOR *IoVec;
  115. UINTN NumVec;
  116. //
  117. // TotalSize is calculated when the scatter-gather list is initially
  118. // validated.
  119. //
  120. UINT32 TotalSize;
  121. } VIRTIO_FS_SCATTER_GATHER_LIST;
  122. //
  123. // Private context structure that exposes EFI_FILE_PROTOCOL on top of an open
  124. // FUSE file reference.
  125. //
  126. typedef struct {
  127. UINT64 Signature;
  128. EFI_FILE_PROTOCOL SimpleFile;
  129. BOOLEAN IsDirectory;
  130. BOOLEAN IsOpenForWriting;
  131. VIRTIO_FS *OwnerFs;
  132. LIST_ENTRY OpenFilesEntry;
  133. CHAR8 *CanonicalPathname;
  134. UINT64 FilePosition;
  135. //
  136. // In the FUSE wire protocol, every request except FUSE_INIT refers to a
  137. // file, namely by the "VIRTIO_FS_FUSE_REQUEST.NodeId" field; that is, by the
  138. // inode number of the file. However, some of the FUSE requests that we need
  139. // for some of the EFI_FILE_PROTOCOL member functions require an open file
  140. // handle *in addition* to the inode number. For simplicity, whenever a
  141. // VIRTIO_FS_FILE object is created, primarily defined by its NodeId field,
  142. // we also *open* the referenced file at once, and save the returned file
  143. // handle in the FuseHandle field. This way, when an EFI_FILE_PROTOCOL member
  144. // function must send a FUSE request that needs the file handle *in addition*
  145. // to the inode number, FuseHandle will be at our disposal at once.
  146. //
  147. UINT64 NodeId;
  148. UINT64 FuseHandle;
  149. //
  150. // EFI_FILE_INFO objects cached for an in-flight directory read.
  151. //
  152. // For reading through a directory stream with tolerable performance, we have
  153. // to call FUSE_READDIRPLUS each time with such a buffer that can deliver a
  154. // good number of variable size records (VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE
  155. // elements). Every time we do that, we turn the whole bunch into an array of
  156. // EFI_FILE_INFOs immediately. EFI_FILE_PROTOCOL.Read() invocations (on
  157. // directories) will be served from this EFI_FILE_INFO cache.
  158. //
  159. UINT8 *FileInfoArray;
  160. UINTN SingleFileInfoSize;
  161. UINTN NumFileInfo;
  162. UINTN NextFileInfo;
  163. } VIRTIO_FS_FILE;
  164. #define VIRTIO_FS_FILE_FROM_SIMPLE_FILE(SimpleFileReference) \
  165. CR (SimpleFileReference, VIRTIO_FS_FILE, SimpleFile, VIRTIO_FS_FILE_SIG);
  166. #define VIRTIO_FS_FILE_FROM_OPEN_FILES_ENTRY(OpenFilesEntryReference) \
  167. CR (OpenFilesEntryReference, VIRTIO_FS_FILE, OpenFilesEntry, \
  168. VIRTIO_FS_FILE_SIG);
  169. //
  170. // Initialization and helper routines for the Virtio Filesystem device.
  171. //
  172. EFI_STATUS
  173. VirtioFsInit (
  174. IN OUT VIRTIO_FS *VirtioFs
  175. );
  176. VOID
  177. VirtioFsUninit (
  178. IN OUT VIRTIO_FS *VirtioFs
  179. );
  180. VOID
  181. EFIAPI
  182. VirtioFsExitBoot (
  183. IN EFI_EVENT ExitBootEvent,
  184. IN VOID *VirtioFsAsVoid
  185. );
  186. EFI_STATUS
  187. VirtioFsSgListsValidate (
  188. IN VIRTIO_FS *VirtioFs,
  189. IN OUT VIRTIO_FS_SCATTER_GATHER_LIST *RequestSgList,
  190. IN OUT VIRTIO_FS_SCATTER_GATHER_LIST *ResponseSgList OPTIONAL
  191. );
  192. EFI_STATUS
  193. VirtioFsSgListsSubmit (
  194. IN OUT VIRTIO_FS *VirtioFs,
  195. IN OUT VIRTIO_FS_SCATTER_GATHER_LIST *RequestSgList,
  196. IN OUT VIRTIO_FS_SCATTER_GATHER_LIST *ResponseSgList OPTIONAL
  197. );
  198. EFI_STATUS
  199. VirtioFsFuseNewRequest (
  200. IN OUT VIRTIO_FS *VirtioFs,
  201. OUT VIRTIO_FS_FUSE_REQUEST *Request,
  202. IN UINT32 RequestSize,
  203. IN VIRTIO_FS_FUSE_OPCODE Opcode,
  204. IN UINT64 NodeId
  205. );
  206. EFI_STATUS
  207. VirtioFsFuseCheckResponse (
  208. IN VIRTIO_FS_SCATTER_GATHER_LIST *ResponseSgList,
  209. IN UINT64 RequestId,
  210. OUT UINTN *TailBufferFill
  211. );
  212. EFI_STATUS
  213. VirtioFsErrnoToEfiStatus (
  214. IN INT32 Errno
  215. );
  216. EFI_STATUS
  217. VirtioFsAppendPath (
  218. IN CHAR8 *LhsPath8,
  219. IN CHAR16 *RhsPath16,
  220. OUT CHAR8 **ResultPath8,
  221. OUT BOOLEAN *RootEscape
  222. );
  223. EFI_STATUS
  224. VirtioFsLookupMostSpecificParentDir (
  225. IN OUT VIRTIO_FS *VirtioFs,
  226. IN OUT CHAR8 *Path,
  227. OUT UINT64 *DirNodeId,
  228. OUT CHAR8 **LastComponent
  229. );
  230. EFI_STATUS
  231. VirtioFsGetBasename (
  232. IN CHAR8 *Path,
  233. OUT CHAR16 *Basename OPTIONAL,
  234. IN OUT UINTN *BasenameSize
  235. );
  236. EFI_STATUS
  237. VirtioFsComposeRenameDestination (
  238. IN CHAR8 *LhsPath8,
  239. IN CHAR16 *RhsPath16,
  240. OUT CHAR8 **ResultPath8,
  241. OUT BOOLEAN *RootEscape
  242. );
  243. EFI_STATUS
  244. VirtioFsFuseAttrToEfiFileInfo (
  245. IN VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE *FuseAttr,
  246. OUT EFI_FILE_INFO *FileInfo
  247. );
  248. EFI_STATUS
  249. VirtioFsFuseDirentPlusToEfiFileInfo (
  250. IN VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE *FuseDirent,
  251. IN OUT EFI_FILE_INFO *FileInfo
  252. );
  253. VOID
  254. VirtioFsGetFuseSizeUpdate (
  255. IN EFI_FILE_INFO *Info,
  256. IN EFI_FILE_INFO *NewInfo,
  257. OUT BOOLEAN *Update,
  258. OUT UINT64 *Size
  259. );
  260. EFI_STATUS
  261. VirtioFsGetFuseTimeUpdates (
  262. IN EFI_FILE_INFO *Info,
  263. IN EFI_FILE_INFO *NewInfo,
  264. OUT BOOLEAN *UpdateAtime,
  265. OUT BOOLEAN *UpdateMtime,
  266. OUT UINT64 *Atime,
  267. OUT UINT64 *Mtime
  268. );
  269. EFI_STATUS
  270. VirtioFsGetFuseModeUpdate (
  271. IN EFI_FILE_INFO *Info,
  272. IN EFI_FILE_INFO *NewInfo,
  273. OUT BOOLEAN *Update,
  274. OUT UINT32 *Mode
  275. );
  276. //
  277. // Wrapper functions for FUSE commands (primitives).
  278. //
  279. EFI_STATUS
  280. VirtioFsFuseLookup (
  281. IN OUT VIRTIO_FS *VirtioFs,
  282. IN UINT64 DirNodeId,
  283. IN CHAR8 *Name,
  284. OUT UINT64 *NodeId,
  285. OUT VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE *FuseAttr
  286. );
  287. EFI_STATUS
  288. VirtioFsFuseForget (
  289. IN OUT VIRTIO_FS *VirtioFs,
  290. IN UINT64 NodeId
  291. );
  292. EFI_STATUS
  293. VirtioFsFuseGetAttr (
  294. IN OUT VIRTIO_FS *VirtioFs,
  295. IN UINT64 NodeId,
  296. OUT VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE *FuseAttr
  297. );
  298. EFI_STATUS
  299. VirtioFsFuseSetAttr (
  300. IN OUT VIRTIO_FS *VirtioFs,
  301. IN UINT64 NodeId,
  302. IN UINT64 *Size OPTIONAL,
  303. IN UINT64 *Atime OPTIONAL,
  304. IN UINT64 *Mtime OPTIONAL,
  305. IN UINT32 *Mode OPTIONAL
  306. );
  307. EFI_STATUS
  308. VirtioFsFuseMkDir (
  309. IN OUT VIRTIO_FS *VirtioFs,
  310. IN UINT64 ParentNodeId,
  311. IN CHAR8 *Name,
  312. OUT UINT64 *NodeId
  313. );
  314. EFI_STATUS
  315. VirtioFsFuseRemoveFileOrDir (
  316. IN OUT VIRTIO_FS *VirtioFs,
  317. IN UINT64 ParentNodeId,
  318. IN CHAR8 *Name,
  319. IN BOOLEAN IsDir
  320. );
  321. EFI_STATUS
  322. VirtioFsFuseOpen (
  323. IN OUT VIRTIO_FS *VirtioFs,
  324. IN UINT64 NodeId,
  325. IN BOOLEAN ReadWrite,
  326. OUT UINT64 *FuseHandle
  327. );
  328. EFI_STATUS
  329. VirtioFsFuseReadFileOrDir (
  330. IN OUT VIRTIO_FS *VirtioFs,
  331. IN UINT64 NodeId,
  332. IN UINT64 FuseHandle,
  333. IN BOOLEAN IsDir,
  334. IN UINT64 Offset,
  335. IN OUT UINT32 *Size,
  336. OUT VOID *Data
  337. );
  338. EFI_STATUS
  339. VirtioFsFuseWrite (
  340. IN OUT VIRTIO_FS *VirtioFs,
  341. IN UINT64 NodeId,
  342. IN UINT64 FuseHandle,
  343. IN UINT64 Offset,
  344. IN OUT UINT32 *Size,
  345. IN VOID *Data
  346. );
  347. EFI_STATUS
  348. VirtioFsFuseStatFs (
  349. IN OUT VIRTIO_FS *VirtioFs,
  350. IN UINT64 NodeId,
  351. OUT VIRTIO_FS_FUSE_STATFS_RESPONSE *FilesysAttr
  352. );
  353. EFI_STATUS
  354. VirtioFsFuseReleaseFileOrDir (
  355. IN OUT VIRTIO_FS *VirtioFs,
  356. IN UINT64 NodeId,
  357. IN UINT64 FuseHandle,
  358. IN BOOLEAN IsDir
  359. );
  360. EFI_STATUS
  361. VirtioFsFuseFsyncFileOrDir (
  362. IN OUT VIRTIO_FS *VirtioFs,
  363. IN UINT64 NodeId,
  364. IN UINT64 FuseHandle,
  365. IN BOOLEAN IsDir
  366. );
  367. EFI_STATUS
  368. VirtioFsFuseFlush (
  369. IN OUT VIRTIO_FS *VirtioFs,
  370. IN UINT64 NodeId,
  371. IN UINT64 FuseHandle
  372. );
  373. EFI_STATUS
  374. VirtioFsFuseInitSession (
  375. IN OUT VIRTIO_FS *VirtioFs
  376. );
  377. EFI_STATUS
  378. VirtioFsFuseOpenDir (
  379. IN OUT VIRTIO_FS *VirtioFs,
  380. IN UINT64 NodeId,
  381. OUT UINT64 *FuseHandle
  382. );
  383. EFI_STATUS
  384. VirtioFsFuseOpenOrCreate (
  385. IN OUT VIRTIO_FS *VirtioFs,
  386. IN UINT64 ParentNodeId,
  387. IN CHAR8 *Name,
  388. OUT UINT64 *NodeId,
  389. OUT UINT64 *FuseHandle
  390. );
  391. EFI_STATUS
  392. VirtioFsFuseRename (
  393. IN OUT VIRTIO_FS *VirtioFs,
  394. IN UINT64 OldParentNodeId,
  395. IN CHAR8 *OldName,
  396. IN UINT64 NewParentNodeId,
  397. IN CHAR8 *NewName
  398. );
  399. //
  400. // EFI_SIMPLE_FILE_SYSTEM_PROTOCOL member functions for the Virtio Filesystem
  401. // driver.
  402. //
  403. EFI_STATUS
  404. EFIAPI
  405. VirtioFsOpenVolume (
  406. IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
  407. OUT EFI_FILE_PROTOCOL **Root
  408. );
  409. //
  410. // EFI_FILE_PROTOCOL member functions for the Virtio Filesystem driver.
  411. //
  412. EFI_STATUS
  413. EFIAPI
  414. VirtioFsSimpleFileClose (
  415. IN EFI_FILE_PROTOCOL *This
  416. );
  417. EFI_STATUS
  418. EFIAPI
  419. VirtioFsSimpleFileDelete (
  420. IN EFI_FILE_PROTOCOL *This
  421. );
  422. EFI_STATUS
  423. EFIAPI
  424. VirtioFsSimpleFileFlush (
  425. IN EFI_FILE_PROTOCOL *This
  426. );
  427. EFI_STATUS
  428. EFIAPI
  429. VirtioFsSimpleFileGetInfo (
  430. IN EFI_FILE_PROTOCOL *This,
  431. IN EFI_GUID *InformationType,
  432. IN OUT UINTN *BufferSize,
  433. OUT VOID *Buffer
  434. );
  435. EFI_STATUS
  436. EFIAPI
  437. VirtioFsSimpleFileGetPosition (
  438. IN EFI_FILE_PROTOCOL *This,
  439. OUT UINT64 *Position
  440. );
  441. EFI_STATUS
  442. EFIAPI
  443. VirtioFsSimpleFileOpen (
  444. IN EFI_FILE_PROTOCOL *This,
  445. OUT EFI_FILE_PROTOCOL **NewHandle,
  446. IN CHAR16 *FileName,
  447. IN UINT64 OpenMode,
  448. IN UINT64 Attributes
  449. );
  450. EFI_STATUS
  451. EFIAPI
  452. VirtioFsSimpleFileRead (
  453. IN EFI_FILE_PROTOCOL *This,
  454. IN OUT UINTN *BufferSize,
  455. OUT VOID *Buffer
  456. );
  457. EFI_STATUS
  458. EFIAPI
  459. VirtioFsSimpleFileSetInfo (
  460. IN EFI_FILE_PROTOCOL *This,
  461. IN EFI_GUID *InformationType,
  462. IN UINTN BufferSize,
  463. IN VOID *Buffer
  464. );
  465. EFI_STATUS
  466. EFIAPI
  467. VirtioFsSimpleFileSetPosition (
  468. IN EFI_FILE_PROTOCOL *This,
  469. IN UINT64 Position
  470. );
  471. EFI_STATUS
  472. EFIAPI
  473. VirtioFsSimpleFileWrite (
  474. IN EFI_FILE_PROTOCOL *This,
  475. IN OUT UINTN *BufferSize,
  476. IN VOID *Buffer
  477. );
  478. #endif // VIRTIO_FS_DXE_H_