/** @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; }