summaryrefslogtreecommitdiffstats
path: root/OvmfPkg/VirtioFsDxe/SimpleFsOpenVolume.c
blob: 058e7a41ab03ab6f0af1aede068c57462a2f5c38 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/** @file
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.OpenVolume() member function for the Virtio
  Filesystem driver.

  Copyright (C) 2020, Red Hat, Inc.

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Library/BaseLib.h>             // InsertTailList()
#include <Library/MemoryAllocationLib.h> // AllocatePool()

#include "VirtioFsDxe.h"

/**
  Open the root directory on the Virtio Filesystem.

  Refer to EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME for the interface
  contract.
**/
EFI_STATUS
EFIAPI
VirtioFsOpenVolume (
  IN  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
  OUT EFI_FILE_PROTOCOL               **Root
  )
{
  VIRTIO_FS      *VirtioFs;
  VIRTIO_FS_FILE *VirtioFsFile;
  EFI_STATUS     Status;
  CHAR8          *CanonicalPathname;
  UINT64         RootDirHandle;

  VirtioFs = VIRTIO_FS_FROM_SIMPLE_FS (This);

  VirtioFsFile = AllocatePool (sizeof *VirtioFsFile);
  if (VirtioFsFile == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  CanonicalPathname = AllocateCopyPool (sizeof "/", "/");
  if (CanonicalPathname == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto FreeVirtioFsFile;
  }

  //
  // Open the root directory.
  //
  Status = VirtioFsFuseOpenDir (VirtioFs, VIRTIO_FS_FUSE_ROOT_DIR_NODE_ID,
             &RootDirHandle);
  if (EFI_ERROR (Status)) {
    goto FreeCanonicalPathname;
  }

  //
  // Populate the new VIRTIO_FS_FILE object.
  //
  VirtioFsFile->Signature              = VIRTIO_FS_FILE_SIG;
  VirtioFsFile->SimpleFile.Revision    = EFI_FILE_PROTOCOL_REVISION;
  VirtioFsFile->SimpleFile.Open        = VirtioFsSimpleFileOpen;
  VirtioFsFile->SimpleFile.Close       = VirtioFsSimpleFileClose;
  VirtioFsFile->SimpleFile.Delete      = VirtioFsSimpleFileDelete;
  VirtioFsFile->SimpleFile.Read        = VirtioFsSimpleFileRead;
  VirtioFsFile->SimpleFile.Write       = VirtioFsSimpleFileWrite;
  VirtioFsFile->SimpleFile.GetPosition = VirtioFsSimpleFileGetPosition;
  VirtioFsFile->SimpleFile.SetPosition = VirtioFsSimpleFileSetPosition;
  VirtioFsFile->SimpleFile.GetInfo     = VirtioFsSimpleFileGetInfo;
  VirtioFsFile->SimpleFile.SetInfo     = VirtioFsSimpleFileSetInfo;
  VirtioFsFile->SimpleFile.Flush       = VirtioFsSimpleFileFlush;
  VirtioFsFile->IsDirectory            = TRUE;
  VirtioFsFile->IsOpenForWriting       = FALSE;
  VirtioFsFile->OwnerFs                = VirtioFs;
  VirtioFsFile->CanonicalPathname      = CanonicalPathname;
  VirtioFsFile->FilePosition           = 0;
  VirtioFsFile->NodeId                 = VIRTIO_FS_FUSE_ROOT_DIR_NODE_ID;
  VirtioFsFile->FuseHandle             = RootDirHandle;
  VirtioFsFile->FileInfoArray          = NULL;
  VirtioFsFile->SingleFileInfoSize     = 0;
  VirtioFsFile->NumFileInfo            = 0;
  VirtioFsFile->NextFileInfo           = 0;

  //
  // One more file open for the filesystem.
  //
  InsertTailList (&VirtioFs->OpenFiles, &VirtioFsFile->OpenFilesEntry);

  *Root = &VirtioFsFile->SimpleFile;
  return EFI_SUCCESS;

FreeCanonicalPathname:
  FreePool (CanonicalPathname);

FreeVirtioFsFile:
  FreePool (VirtioFsFile);

  return Status;
}