2 FUSE_MKDIR wrapper for the Virtio Filesystem device.
4 Copyright (C) 2020, Red Hat, Inc.
6 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include <Library/BaseLib.h> // AsciiStrSize()
11 #include "VirtioFsDxe.h"
14 Send a FUSE_MKDIR request to the Virtio Filesystem device, for creating a
17 The function may only be called after VirtioFsFuseInitSession() returns
18 successfully and before VirtioFsUninit() is called.
20 @param[in,out] VirtioFs The Virtio Filesystem device to send the FUSE_MKDIR
21 request to. On output, the FUSE request counter
22 "VirtioFs->RequestId" will have been incremented.
24 @param[in] ParentNodeId The inode number of the direct parent directory of
25 the directory to create.
27 @param[in] Name The single-component filename of the directory to
28 create, under the parent directory identified by
31 @param[out] NodeId The inode number of the new directory.
33 @retval EFI_SUCCESS The directory has been created.
35 @return The "errno" value mapped to an EFI_STATUS code, if the
36 Virtio Filesystem device explicitly reported an error.
38 @return Error codes propagated from VirtioFsSgListsValidate(),
39 VirtioFsFuseNewRequest(), VirtioFsSgListsSubmit(),
40 VirtioFsFuseCheckResponse().
44 IN OUT VIRTIO_FS
*VirtioFs
,
45 IN UINT64 ParentNodeId
,
50 VIRTIO_FS_FUSE_REQUEST CommonReq
;
51 VIRTIO_FS_FUSE_MKDIR_REQUEST MkDirReq
;
52 VIRTIO_FS_IO_VECTOR ReqIoVec
[3];
53 VIRTIO_FS_SCATTER_GATHER_LIST ReqSgList
;
54 VIRTIO_FS_FUSE_RESPONSE CommonResp
;
55 VIRTIO_FS_FUSE_NODE_RESPONSE NodeResp
;
56 VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE AttrResp
;
57 VIRTIO_FS_IO_VECTOR RespIoVec
[3];
58 VIRTIO_FS_SCATTER_GATHER_LIST RespSgList
;
62 // Set up the scatter-gather lists.
64 ReqIoVec
[0].Buffer
= &CommonReq
;
65 ReqIoVec
[0].Size
= sizeof CommonReq
;
66 ReqIoVec
[1].Buffer
= &MkDirReq
;
67 ReqIoVec
[1].Size
= sizeof MkDirReq
;
68 ReqIoVec
[2].Buffer
= Name
;
69 ReqIoVec
[2].Size
= AsciiStrSize (Name
);
70 ReqSgList
.IoVec
= ReqIoVec
;
71 ReqSgList
.NumVec
= ARRAY_SIZE (ReqIoVec
);
73 RespIoVec
[0].Buffer
= &CommonResp
;
74 RespIoVec
[0].Size
= sizeof CommonResp
;
75 RespIoVec
[1].Buffer
= &NodeResp
;
76 RespIoVec
[1].Size
= sizeof NodeResp
;
77 RespIoVec
[2].Buffer
= &AttrResp
;
78 RespIoVec
[2].Size
= sizeof AttrResp
;
79 RespSgList
.IoVec
= RespIoVec
;
80 RespSgList
.NumVec
= ARRAY_SIZE (RespIoVec
);
83 // Validate the scatter-gather lists; calculate the total transfer sizes.
85 Status
= VirtioFsSgListsValidate (VirtioFs
, &ReqSgList
, &RespSgList
);
86 if (EFI_ERROR (Status
)) {
91 // Populate the common request header.
93 Status
= VirtioFsFuseNewRequest (
100 if (EFI_ERROR (Status
)) {
105 // Populate the FUSE_MKDIR-specific fields.
107 MkDirReq
.Mode
= (VIRTIO_FS_FUSE_MODE_PERM_RWXU
|
108 VIRTIO_FS_FUSE_MODE_PERM_RWXG
|
109 VIRTIO_FS_FUSE_MODE_PERM_RWXO
);
113 // Submit the request.
115 Status
= VirtioFsSgListsSubmit (VirtioFs
, &ReqSgList
, &RespSgList
);
116 if (EFI_ERROR (Status
)) {
121 // Verify the response (all response buffers are fixed size).
123 Status
= VirtioFsFuseCheckResponse (&RespSgList
, CommonReq
.Unique
, NULL
);
124 if (EFI_ERROR (Status
)) {
125 if (Status
== EFI_DEVICE_ERROR
) {
128 "%a: Label=\"%s\" ParentNodeId=%Lu Name=\"%a\" "
136 Status
= VirtioFsErrnoToEfiStatus (CommonResp
.Error
);
143 // Output the NodeId of the new directory.
145 *NodeId
= NodeResp
.NodeId
;