VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/OvmfPkg/VirtioFsDxe/FuseWrite.c@ 94264

Last change on this file since 94264 was 89983, checked in by vboxsync, 3 years ago

Devices/EFI: Merge edk-stable202105 and openssl 1.1.1j and make it build, bugref:4643

  • Property svn:eol-style set to native
File size: 4.8 KB
Line 
1/** @file
2 FUSE_WRITE wrapper for the Virtio Filesystem device.
3
4 Copyright (C) 2020, Red Hat, Inc.
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7**/
8
9#include "VirtioFsDxe.h"
10
11/**
12 Write a chunk to a regular file, by sending the FUSE_WRITE request to the
13 Virtio Filesystem device.
14
15 The function may only be called after VirtioFsFuseInitSession() returns
16 successfully and before VirtioFsUninit() is called.
17
18 @param[in,out] VirtioFs The Virtio Filesystem device to send the FUSE_WRITE
19 request to. On output, the FUSE request counter
20 "VirtioFs->RequestId" will have been incremented.
21
22 @param[in] NodeId The inode number of the regular file to write to.
23
24 @param[in] FuseHandle The open handle to the regular file to write to.
25
26 @param[in] Offset The absolute file position at which to start
27 writing.
28
29 @param[in,out] Size On input, the number of bytes to write. On
30 successful return, the number of bytes actually
31 written, which may be smaller than the value on
32 input.
33
34 @param[in] Data The buffer to write to the regular file.
35
36 @retval EFI_SUCCESS Write successful. The caller is responsible for
37 checking Size to learn the actual byte count
38 transferred.
39
40 @retval EFI_BAD_BUFFER_SIZE On input, Size is larger than
41 "VirtioFs->MaxWrite".
42
43 @return The "errno" value mapped to an EFI_STATUS code,
44 if the Virtio Filesystem device explicitly
45 reported an error.
46
47 @return Error codes propagated from
48 VirtioFsSgListsValidate(),
49 VirtioFsFuseNewRequest(),
50 VirtioFsSgListsSubmit(),
51 VirtioFsFuseCheckResponse().
52**/
53EFI_STATUS
54VirtioFsFuseWrite (
55 IN OUT VIRTIO_FS *VirtioFs,
56 IN UINT64 NodeId,
57 IN UINT64 FuseHandle,
58 IN UINT64 Offset,
59 IN OUT UINT32 *Size,
60 IN VOID *Data
61 )
62{
63 VIRTIO_FS_FUSE_REQUEST CommonReq;
64 VIRTIO_FS_FUSE_WRITE_REQUEST WriteReq;
65 VIRTIO_FS_IO_VECTOR ReqIoVec[3];
66 VIRTIO_FS_SCATTER_GATHER_LIST ReqSgList;
67 VIRTIO_FS_FUSE_RESPONSE CommonResp;
68 VIRTIO_FS_FUSE_WRITE_RESPONSE WriteResp;
69 VIRTIO_FS_IO_VECTOR RespIoVec[2];
70 VIRTIO_FS_SCATTER_GATHER_LIST RespSgList;
71 EFI_STATUS Status;
72
73 //
74 // Honor the write buffer size limit of the Virtio Filesystem device.
75 //
76 if (*Size > VirtioFs->MaxWrite) {
77 return EFI_BAD_BUFFER_SIZE;
78 }
79
80 //
81 // Set up the scatter-gather lists.
82 //
83 ReqIoVec[0].Buffer = &CommonReq;
84 ReqIoVec[0].Size = sizeof CommonReq;
85 ReqIoVec[1].Buffer = &WriteReq;
86 ReqIoVec[1].Size = sizeof WriteReq;
87 ReqIoVec[2].Buffer = Data;
88 ReqIoVec[2].Size = *Size;
89 ReqSgList.IoVec = ReqIoVec;
90 ReqSgList.NumVec = ARRAY_SIZE (ReqIoVec);
91
92 RespIoVec[0].Buffer = &CommonResp;
93 RespIoVec[0].Size = sizeof CommonResp;
94 RespIoVec[1].Buffer = &WriteResp;
95 RespIoVec[1].Size = sizeof WriteResp;
96 RespSgList.IoVec = RespIoVec;
97 RespSgList.NumVec = ARRAY_SIZE (RespIoVec);
98
99 //
100 // Validate the scatter-gather lists; calculate the total transfer sizes.
101 //
102 Status = VirtioFsSgListsValidate (VirtioFs, &ReqSgList, &RespSgList);
103 if (EFI_ERROR (Status)) {
104 return Status;
105 }
106
107 //
108 // Populate the common request header.
109 //
110 Status = VirtioFsFuseNewRequest (VirtioFs, &CommonReq, ReqSgList.TotalSize,
111 VirtioFsFuseOpWrite, NodeId);
112 if (EFI_ERROR (Status)) {
113 return Status;
114 }
115
116 //
117 // Populate the FUSE_WRITE-specific fields.
118 //
119 WriteReq.FileHandle = FuseHandle;
120 WriteReq.Offset = Offset;
121 WriteReq.Size = *Size;
122 WriteReq.WriteFlags = 0;
123 WriteReq.LockOwner = 0;
124 WriteReq.Flags = 0;
125 WriteReq.Padding = 0;
126
127 //
128 // Submit the request.
129 //
130 Status = VirtioFsSgListsSubmit (VirtioFs, &ReqSgList, &RespSgList);
131 if (EFI_ERROR (Status)) {
132 return Status;
133 }
134
135 //
136 // Verify the response (all response buffers are fixed size).
137 //
138 Status = VirtioFsFuseCheckResponse (&RespSgList, CommonReq.Unique, NULL);
139 if (EFI_ERROR (Status)) {
140 if (Status == EFI_DEVICE_ERROR) {
141 DEBUG ((DEBUG_ERROR, "%a: Label=\"%s\" NodeId=%Lu FuseHandle=%Lu "
142 "Offset=0x%Lx Size=0x%x Data@%p Errno=%d\n", __FUNCTION__,
143 VirtioFs->Label, NodeId, FuseHandle, Offset, *Size, Data,
144 CommonResp.Error));
145 Status = VirtioFsErrnoToEfiStatus (CommonResp.Error);
146 }
147 return Status;
148 }
149
150 //
151 // Report the actual transfer size.
152 //
153 *Size = WriteResp.Size;
154 return EFI_SUCCESS;
155}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette