summaryrefslogtreecommitdiffstats
path: root/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h
diff options
context:
space:
mode:
authorLaszlo Ersek <lersek@redhat.com>2020-12-16 22:10:48 +0100
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2020-12-21 17:16:23 +0000
commit334c13e106ebad35a8e620f3b0f1179a1a6eaa54 (patch)
treef451f9c97671155b6935dfd66517aec0175a6919 /OvmfPkg/VirtioFsDxe/VirtioFsDxe.h
parent72d4f133e9674e25d8fbbeda1b6746f9bd29ad7f (diff)
downloadedk2-334c13e106ebad35a8e620f3b0f1179a1a6eaa54.tar.gz
edk2-334c13e106ebad35a8e620f3b0f1179a1a6eaa54.tar.bz2
edk2-334c13e106ebad35a8e620f3b0f1179a1a6eaa54.zip
OvmfPkg/VirtioFsDxe: implement EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume()
With the help of the VirtioFsFuseOpenDir() and VirtioFsFuseReleaseFileOrDir() functions introduced previously, we can now open and close the root directory. So let's implement EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume(). OpenVolume() creates a new EFI_FILE_PROTOCOL object -- a reference to the root directory of the filesystem. Thus, we have to start tracking references to EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, lest we unbind the virtio-fs device while files are open. There are two methods that release an EFI_FILE_PROTOCOL object: the Close() and the Delete() member functions. In particular, they are not allowed to fail with regard to resource management -- they must release resources unconditionally. Thus, for rolling back the resource accounting that we do in EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume(), we have to implement the first versions of EFI_FILE_PROTOCOL.Close() and EFI_FILE_PROTOCOL.Delete() in this patch as well. With this patch applied, the UEFI shell can enter the root directory of the Virtio Filesystem (such as with the "FS3:" shell command), and the "DIR" shell command exercises FUSE_OPENDIR and FUSE_RELEASEDIR, according to the virtiofsd log. The "DIR" command reports the root directory as if it were empty; probably because at this time, we only allow the shell to open and to close the root directory, but not to read it. Cc: Ard Biesheuvel <ard.biesheuvel@arm.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Philippe Mathieu-Daudé <philmd@redhat.com> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3097 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Message-Id: <20201216211125.19496-12-lersek@redhat.com> Acked-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
Diffstat (limited to 'OvmfPkg/VirtioFsDxe/VirtioFsDxe.h')
-rw-r--r--OvmfPkg/VirtioFsDxe/VirtioFsDxe.h117
1 files changed, 117 insertions, 0 deletions
diff --git a/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h b/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h
index a99625d047..34574d0596 100644
--- a/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h
+++ b/OvmfPkg/VirtioFsDxe/VirtioFsDxe.h
@@ -19,6 +19,9 @@
#define VIRTIO_FS_SIG SIGNATURE_64 ('V', 'I', 'R', 'T', 'I', 'O', 'F', 'S')
+#define VIRTIO_FS_FILE_SIG \
+ SIGNATURE_64 ('V', 'I', 'O', 'F', 'S', 'F', 'I', 'L')
+
//
// Filesystem label encoded in UCS-2, transformed from the UTF-8 representation
// in "VIRTIO_FS_CONFIG.Tag", and NUL-terminated. Only the printable ASCII code
@@ -46,6 +49,7 @@ typedef struct {
VOID *RingMap; // VirtioRingMap 2
UINT64 RequestId; // FuseInitSession 1
EFI_EVENT ExitBoot; // DriverBindingStart 0
+ LIST_ENTRY OpenFiles; // DriverBindingStart 0
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFs; // DriverBindingStart 0
} VIRTIO_FS;
@@ -99,6 +103,39 @@ typedef struct {
} VIRTIO_FS_SCATTER_GATHER_LIST;
//
+// Private context structure that exposes EFI_FILE_PROTOCOL on top of an open
+// FUSE file reference.
+//
+typedef struct {
+ UINT64 Signature;
+ EFI_FILE_PROTOCOL SimpleFile;
+ BOOLEAN IsDirectory;
+ VIRTIO_FS *OwnerFs;
+ LIST_ENTRY OpenFilesEntry;
+ //
+ // 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
+ // inode number of the file. However, some of the FUSE requests that we need
+ // for some of the EFI_FILE_PROTOCOL member functions require an open file
+ // handle *in addition* to the inode number. For simplicity, whenever a
+ // VIRTIO_FS_FILE object is created, primarily defined by its NodeId field,
+ // we also *open* the referenced file at once, and save the returned file
+ // handle in the FuseHandle field. This way, when an EFI_FILE_PROTOCOL member
+ // function must send a FUSE request that needs the file handle *in addition*
+ // to the inode number, FuseHandle will be at our disposal at once.
+ //
+ UINT64 NodeId;
+ UINT64 FuseHandle;
+} VIRTIO_FS_FILE;
+
+#define VIRTIO_FS_FILE_FROM_SIMPLE_FILE(SimpleFileReference) \
+ CR (SimpleFileReference, VIRTIO_FS_FILE, SimpleFile, VIRTIO_FS_FILE_SIG);
+
+#define VIRTIO_FS_FILE_FROM_OPEN_FILES_ENTRY(OpenFilesEntryReference) \
+ CR (OpenFilesEntryReference, VIRTIO_FS_FILE, OpenFilesEntry, \
+ VIRTIO_FS_FILE_SIG);
+
+//
// Initialization and helper routines for the Virtio Filesystem device.
//
@@ -190,4 +227,84 @@ VirtioFsOpenVolume (
OUT EFI_FILE_PROTOCOL **Root
);
+//
+// EFI_FILE_PROTOCOL member functions for the Virtio Filesystem driver.
+//
+
+EFI_STATUS
+EFIAPI
+VirtioFsSimpleFileClose (
+ IN EFI_FILE_PROTOCOL *This
+ );
+
+EFI_STATUS
+EFIAPI
+VirtioFsSimpleFileDelete (
+ IN EFI_FILE_PROTOCOL *This
+ );
+
+EFI_STATUS
+EFIAPI
+VirtioFsSimpleFileFlush (
+ IN EFI_FILE_PROTOCOL *This
+ );
+
+EFI_STATUS
+EFIAPI
+VirtioFsSimpleFileGetInfo (
+ IN EFI_FILE_PROTOCOL *This,
+ IN EFI_GUID *InformationType,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+VirtioFsSimpleFileGetPosition (
+ IN EFI_FILE_PROTOCOL *This,
+ OUT UINT64 *Position
+ );
+
+EFI_STATUS
+EFIAPI
+VirtioFsSimpleFileOpen (
+ IN EFI_FILE_PROTOCOL *This,
+ OUT EFI_FILE_PROTOCOL **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
+ );
+
+EFI_STATUS
+EFIAPI
+VirtioFsSimpleFileRead (
+ IN EFI_FILE_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+VirtioFsSimpleFileSetInfo (
+ IN EFI_FILE_PROTOCOL *This,
+ IN EFI_GUID *InformationType,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ );
+
+EFI_STATUS
+EFIAPI
+VirtioFsSimpleFileSetPosition (
+ IN EFI_FILE_PROTOCOL *This,
+ IN UINT64 Position
+ );
+
+EFI_STATUS
+EFIAPI
+VirtioFsSimpleFileWrite (
+ IN EFI_FILE_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ );
+
#endif // VIRTIO_FS_DXE_H_