]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/VirtioFsDxe/FuseMkDir.c
OvmfPkg/VirtioFsDxe: implement the wrapper function for FUSE_MKDIR
[mirror_edk2.git] / OvmfPkg / VirtioFsDxe / FuseMkDir.c
CommitLineData
f058cb69
LE
1/** @file\r
2 FUSE_MKDIR wrapper for the Virtio Filesystem device.\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
9#include <Library/BaseLib.h> // AsciiStrSize()\r
10\r
11#include "VirtioFsDxe.h"\r
12\r
13/**\r
14 Send a FUSE_MKDIR request to the Virtio Filesystem device, for creating a\r
15 directory.\r
16\r
17 The function may only be called after VirtioFsFuseInitSession() returns\r
18 successfully and before VirtioFsUninit() is called.\r
19\r
20 @param[in,out] VirtioFs The Virtio Filesystem device to send the FUSE_MKDIR\r
21 request to. On output, the FUSE request counter\r
22 "VirtioFs->RequestId" will have been incremented.\r
23\r
24 @param[in] ParentNodeId The inode number of the direct parent directory of\r
25 the directory to create.\r
26\r
27 @param[in] Name The single-component filename of the directory to\r
28 create, under the parent directory identified by\r
29 ParentNodeId.\r
30\r
31 @param[out] NodeId The inode number of the new directory.\r
32\r
33 @retval EFI_SUCCESS The directory has been created.\r
34\r
35 @return The "errno" value mapped to an EFI_STATUS code, if the\r
36 Virtio Filesystem device explicitly reported an error.\r
37\r
38 @return Error codes propagated from VirtioFsSgListsValidate(),\r
39 VirtioFsFuseNewRequest(), VirtioFsSgListsSubmit(),\r
40 VirtioFsFuseCheckResponse().\r
41**/\r
42EFI_STATUS\r
43VirtioFsFuseMkDir (\r
44 IN OUT VIRTIO_FS *VirtioFs,\r
45 IN UINT64 ParentNodeId,\r
46 IN CHAR8 *Name,\r
47 OUT UINT64 *NodeId\r
48 )\r
49{\r
50 VIRTIO_FS_FUSE_REQUEST CommonReq;\r
51 VIRTIO_FS_FUSE_MKDIR_REQUEST MkDirReq;\r
52 VIRTIO_FS_IO_VECTOR ReqIoVec[3];\r
53 VIRTIO_FS_SCATTER_GATHER_LIST ReqSgList;\r
54 VIRTIO_FS_FUSE_RESPONSE CommonResp;\r
55 VIRTIO_FS_FUSE_NODE_RESPONSE NodeResp;\r
56 VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE AttrResp;\r
57 VIRTIO_FS_IO_VECTOR RespIoVec[3];\r
58 VIRTIO_FS_SCATTER_GATHER_LIST RespSgList;\r
59 EFI_STATUS Status;\r
60\r
61 //\r
62 // Set up the scatter-gather lists.\r
63 //\r
64 ReqIoVec[0].Buffer = &CommonReq;\r
65 ReqIoVec[0].Size = sizeof CommonReq;\r
66 ReqIoVec[1].Buffer = &MkDirReq;\r
67 ReqIoVec[1].Size = sizeof MkDirReq;\r
68 ReqIoVec[2].Buffer = Name;\r
69 ReqIoVec[2].Size = AsciiStrSize (Name);\r
70 ReqSgList.IoVec = ReqIoVec;\r
71 ReqSgList.NumVec = ARRAY_SIZE (ReqIoVec);\r
72\r
73 RespIoVec[0].Buffer = &CommonResp;\r
74 RespIoVec[0].Size = sizeof CommonResp;\r
75 RespIoVec[1].Buffer = &NodeResp;\r
76 RespIoVec[1].Size = sizeof NodeResp;\r
77 RespIoVec[2].Buffer = &AttrResp;\r
78 RespIoVec[2].Size = sizeof AttrResp;\r
79 RespSgList.IoVec = RespIoVec;\r
80 RespSgList.NumVec = ARRAY_SIZE (RespIoVec);\r
81\r
82 //\r
83 // Validate the scatter-gather lists; calculate the total transfer sizes.\r
84 //\r
85 Status = VirtioFsSgListsValidate (VirtioFs, &ReqSgList, &RespSgList);\r
86 if (EFI_ERROR (Status)) {\r
87 return Status;\r
88 }\r
89\r
90 //\r
91 // Populate the common request header.\r
92 //\r
93 Status = VirtioFsFuseNewRequest (VirtioFs, &CommonReq, ReqSgList.TotalSize,\r
94 VirtioFsFuseOpMkDir, ParentNodeId);\r
95 if (EFI_ERROR (Status)) {\r
96 return Status;\r
97 }\r
98\r
99 //\r
100 // Populate the FUSE_MKDIR-specific fields.\r
101 //\r
102 MkDirReq.Mode = (VIRTIO_FS_FUSE_MODE_PERM_RWXU |\r
103 VIRTIO_FS_FUSE_MODE_PERM_RWXG |\r
104 VIRTIO_FS_FUSE_MODE_PERM_RWXO);\r
105 MkDirReq.Umask = 0;\r
106\r
107 //\r
108 // Submit the request.\r
109 //\r
110 Status = VirtioFsSgListsSubmit (VirtioFs, &ReqSgList, &RespSgList);\r
111 if (EFI_ERROR (Status)) {\r
112 return Status;\r
113 }\r
114\r
115 //\r
116 // Verify the response (all response buffers are fixed size).\r
117 //\r
118 Status = VirtioFsFuseCheckResponse (&RespSgList, CommonReq.Unique, NULL);\r
119 if (EFI_ERROR (Status)) {\r
120 if (Status == EFI_DEVICE_ERROR) {\r
121 DEBUG ((DEBUG_ERROR, "%a: Label=\"%s\" ParentNodeId=%Lu Name=\"%a\" "\r
122 "Errno=%d\n", __FUNCTION__, VirtioFs->Label, ParentNodeId, Name,\r
123 CommonResp.Error));\r
124 Status = VirtioFsErrnoToEfiStatus (CommonResp.Error);\r
125 }\r
126 return Status;\r
127 }\r
128\r
129 //\r
130 // Output the NodeId of the new directory.\r
131 //\r
132 *NodeId = NodeResp.NodeId;\r
133 return EFI_SUCCESS;\r
134}\r