]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/VirtioFsDxe/SimpleFsDelete.c
OvmfPkg/VirtioFsDxe: convert FUSE dirent filename to EFI_FILE_INFO
[mirror_edk2.git] / OvmfPkg / VirtioFsDxe / SimpleFsDelete.c
CommitLineData
334c13e1
LE
1/** @file\r
2 EFI_FILE_PROTOCOL.Delete() 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
28092a39
LE
9#include <Library/BaseLib.h> // RemoveEntryList()\r
10#include <Library/MemoryAllocationLib.h> // FreePool()\r
11\r
334c13e1
LE
12#include "VirtioFsDxe.h"\r
13\r
14EFI_STATUS\r
15EFIAPI\r
16VirtioFsSimpleFileDelete (\r
17 IN EFI_FILE_PROTOCOL *This\r
18 )\r
19{\r
28092a39
LE
20 VIRTIO_FS_FILE *VirtioFsFile;\r
21 VIRTIO_FS *VirtioFs;\r
22 EFI_STATUS Status;\r
23\r
24 VirtioFsFile = VIRTIO_FS_FILE_FROM_SIMPLE_FILE (This);\r
25 VirtioFs = VirtioFsFile->OwnerFs;\r
26\r
27 //\r
28 // All actions in this function are "best effort"; the UEFI spec requires\r
29 // EFI_FILE_PROTOCOL.Delete() to release resources unconditionally. If a step\r
30 // related to removing the file fails, it's only reflected in the return\r
31 // status (EFI_WARN_DELETE_FAILURE rather than EFI_SUCCESS).\r
32 //\r
33 // Release, remove, and (if needed) forget. We don't waste time flushing and\r
34 // syncing; if the EFI_FILE_PROTOCOL user cares enough, they should keep the\r
35 // parent directory open until after this function call returns, and then\r
36 // force a sync on *that* EFI_FILE_PROTOCOL instance, using either the\r
37 // Flush() member function, or the Close() member function.\r
38 //\r
39 // If any action fails below, we still try the others.\r
40 //\r
41 VirtioFsFuseReleaseFileOrDir (VirtioFs, VirtioFsFile->NodeId,\r
42 VirtioFsFile->FuseHandle, VirtioFsFile->IsDirectory);\r
43\r
44 //\r
45 // VirtioFsFile->FuseHandle is gone at this point, but VirtioFsFile->NodeId\r
46 // is still valid. Continue with removing the file or directory. The result\r
47 // of this operation determines the return status of the function.\r
334c13e1 48 //\r
c09441c3
LE
49 if (VirtioFsFile->IsOpenForWriting) {\r
50 UINT64 ParentNodeId;\r
51 CHAR8 *LastComponent;\r
52\r
53 //\r
54 // Split our canonical pathname into most specific parent directory\r
55 // (identified by NodeId), and single-component filename within that\r
56 // directory. If This stands for the root directory "/", then the following\r
57 // function call will gracefully fail.\r
58 //\r
59 Status = VirtioFsLookupMostSpecificParentDir (\r
60 VirtioFs,\r
61 VirtioFsFile->CanonicalPathname,\r
62 &ParentNodeId,\r
63 &LastComponent\r
64 );\r
65 if (!EFI_ERROR (Status)) {\r
66 //\r
67 // Attempt the actual removal. Regardless of the outcome, ParentNodeId\r
68 // must be forgotten right after (unless it stands for the root\r
69 // directory).\r
70 //\r
71 Status = VirtioFsFuseRemoveFileOrDir (\r
72 VirtioFs,\r
73 ParentNodeId,\r
74 LastComponent,\r
75 VirtioFsFile->IsDirectory\r
76 );\r
77 if (ParentNodeId != VIRTIO_FS_FUSE_ROOT_DIR_NODE_ID) {\r
78 VirtioFsFuseForget (VirtioFs, ParentNodeId);\r
79 }\r
80 }\r
81 if (EFI_ERROR (Status)) {\r
82 //\r
83 // Map any failure to the spec-mandated warning code.\r
84 //\r
85 Status = EFI_WARN_DELETE_FAILURE;\r
86 }\r
87 } else {\r
88 Status = EFI_WARN_DELETE_FAILURE;\r
89 }\r
28092a39 90\r
334c13e1 91 //\r
28092a39
LE
92 // Finally, if we've known VirtioFsFile->NodeId from a lookup, then we should\r
93 // also ask the server to forget it *once*.\r
334c13e1 94 //\r
28092a39
LE
95 if (VirtioFsFile->NodeId != VIRTIO_FS_FUSE_ROOT_DIR_NODE_ID) {\r
96 VirtioFsFuseForget (VirtioFs, VirtioFsFile->NodeId);\r
97 }\r
98\r
99 //\r
100 // One fewer file left open for the owner filesystem.\r
101 //\r
102 RemoveEntryList (&VirtioFsFile->OpenFilesEntry);\r
103\r
7e8c83f7 104 FreePool (VirtioFsFile->CanonicalPathname);\r
28092a39
LE
105 FreePool (VirtioFsFile);\r
106 return Status;\r
334c13e1 107}\r