2 FUSE_OPENDIR wrapper for the Virtio Filesystem device.
4 Copyright (C) 2020, Red Hat, Inc.
6 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "VirtioFsDxe.h"
12 Send a FUSE_OPENDIR request to the Virtio Filesystem device, for opening a
15 The function may only be called after VirtioFsFuseInitSession() returns
16 successfully and before VirtioFsUninit() is called.
18 @param[in,out] VirtioFs The Virtio Filesystem device to send the
19 FUSE_OPENDIR request to. On output, the FUSE request
20 counter "VirtioFs->RequestId" will have been
23 @param[in] NodeId The inode number of the directory to open.
25 @param[out] FuseHandle The open file handle returned by the Virtio
28 @retval EFI_SUCCESS The directory has been opened.
30 @return The "errno" value mapped to an EFI_STATUS code, if the
31 Virtio Filesystem device explicitly reported an error.
33 @return Error codes propagated from VirtioFsSgListsValidate(),
34 VirtioFsFuseNewRequest(), VirtioFsSgListsSubmit(),
35 VirtioFsFuseCheckResponse().
39 IN OUT VIRTIO_FS
*VirtioFs
,
41 OUT UINT64
*FuseHandle
44 VIRTIO_FS_FUSE_REQUEST CommonReq
;
45 VIRTIO_FS_FUSE_OPEN_REQUEST OpenReq
;
46 VIRTIO_FS_IO_VECTOR ReqIoVec
[2];
47 VIRTIO_FS_SCATTER_GATHER_LIST ReqSgList
;
48 VIRTIO_FS_FUSE_RESPONSE CommonResp
;
49 VIRTIO_FS_FUSE_OPEN_RESPONSE OpenResp
;
50 VIRTIO_FS_IO_VECTOR RespIoVec
[2];
51 VIRTIO_FS_SCATTER_GATHER_LIST RespSgList
;
55 // Set up the scatter-gather lists.
57 ReqIoVec
[0].Buffer
= &CommonReq
;
58 ReqIoVec
[0].Size
= sizeof CommonReq
;
59 ReqIoVec
[1].Buffer
= &OpenReq
;
60 ReqIoVec
[1].Size
= sizeof OpenReq
;
61 ReqSgList
.IoVec
= ReqIoVec
;
62 ReqSgList
.NumVec
= ARRAY_SIZE (ReqIoVec
);
64 RespIoVec
[0].Buffer
= &CommonResp
;
65 RespIoVec
[0].Size
= sizeof CommonResp
;
66 RespIoVec
[1].Buffer
= &OpenResp
;
67 RespIoVec
[1].Size
= sizeof OpenResp
;
68 RespSgList
.IoVec
= RespIoVec
;
69 RespSgList
.NumVec
= ARRAY_SIZE (RespIoVec
);
72 // Validate the scatter-gather lists; calculate the total transfer sizes.
74 Status
= VirtioFsSgListsValidate (VirtioFs
, &ReqSgList
, &RespSgList
);
75 if (EFI_ERROR (Status
)) {
80 // Populate the common request header.
82 Status
= VirtioFsFuseNewRequest (
86 VirtioFsFuseOpOpenDir
,
89 if (EFI_ERROR (Status
)) {
94 // Populate the FUSE_OPENDIR-specific fields.
100 // Submit the request.
102 Status
= VirtioFsSgListsSubmit (VirtioFs
, &ReqSgList
, &RespSgList
);
103 if (EFI_ERROR (Status
)) {
108 // Verify the response (all response buffers are fixed size).
110 Status
= VirtioFsFuseCheckResponse (&RespSgList
, CommonReq
.Unique
, NULL
);
111 if (EFI_ERROR (Status
)) {
112 if (Status
== EFI_DEVICE_ERROR
) {
115 "%a: Label=\"%s\" NodeId=%Lu Errno=%d\n",
121 Status
= VirtioFsErrnoToEfiStatus (CommonResp
.Error
);
128 // Output the open file handle.
130 *FuseHandle
= OpenResp
.FileHandle
;