| /** @file | |
| FUSE_FORGET wrapper for the Virtio Filesystem device. | |
| Copyright (C) 2020, Red Hat, Inc. | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| **/ | |
| #include "VirtioFsDxe.h" | |
| /** | |
| Make the Virtio Filesysem device drop one reference count from a NodeId that | |
| the driver looked up by filename. | |
| Send the FUSE_FORGET request to the Virtio Filesysem device for this. Unlike | |
| most other FUSE requests, FUSE_FORGET doesn't elicit a response, not even the | |
| common VIRTIO_FS_FUSE_RESPONSE header. | |
| The function may only be called after VirtioFsFuseInitSession() returns | |
| successfully and before VirtioFsUninit() is called. | |
| @param[in,out] VirtioFs The Virtio Filesystem device to send the FUSE_FORGET | |
| request to. On output, the FUSE request counter | |
| "VirtioFs->RequestId" will have been incremented. | |
| @param[in] NodeId The inode number that the client learned by way of | |
| lookup, and that the server should now un-reference | |
| exactly once. | |
| @retval EFI_SUCCESS The FUSE_FORGET request has been submitted. | |
| @return Error codes propagated from VirtioFsSgListsValidate(), | |
| VirtioFsFuseNewRequest(), VirtioFsSgListsSubmit(). | |
| **/ | |
| EFI_STATUS | |
| VirtioFsFuseForget ( | |
| IN OUT VIRTIO_FS *VirtioFs, | |
| IN UINT64 NodeId | |
| ) | |
| { | |
| VIRTIO_FS_FUSE_REQUEST CommonReq; | |
| VIRTIO_FS_FUSE_FORGET_REQUEST ForgetReq; | |
| VIRTIO_FS_IO_VECTOR ReqIoVec[2]; | |
| VIRTIO_FS_SCATTER_GATHER_LIST ReqSgList; | |
| EFI_STATUS Status; | |
| // | |
| // Set up the scatter-gather list (note: only request). | |
| // | |
| ReqIoVec[0].Buffer = &CommonReq; | |
| ReqIoVec[0].Size = sizeof CommonReq; | |
| ReqIoVec[1].Buffer = &ForgetReq; | |
| ReqIoVec[1].Size = sizeof ForgetReq; | |
| ReqSgList.IoVec = ReqIoVec; | |
| ReqSgList.NumVec = ARRAY_SIZE (ReqIoVec); | |
| // | |
| // Validate the scatter-gather list (request only); calculate the total | |
| // transfer size. | |
| // | |
| Status = VirtioFsSgListsValidate (VirtioFs, &ReqSgList, NULL); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| // | |
| // Populate the common request header. | |
| // | |
| Status = VirtioFsFuseNewRequest ( | |
| VirtioFs, | |
| &CommonReq, | |
| ReqSgList.TotalSize, | |
| VirtioFsFuseOpForget, | |
| NodeId | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| // | |
| // Populate the FUSE_FORGET-specific fields. | |
| // | |
| ForgetReq.NumberOfLookups = 1; | |
| // | |
| // Submit the request. There's not going to be a response. | |
| // | |
| Status = VirtioFsSgListsSubmit (VirtioFs, &ReqSgList, NULL); | |
| return Status; | |
| } |