OvmfPkg/VirtioFsDxe: flush, sync, release and forget in Close() / Delete()
The two member functions that free the EFI_FILE_PROTOCOL object are Close() and Delete(). Before we create VIRTIO_FS_FILE objects with EFI_FILE_PROTOCOL.Open() later in this patch series, extend each of these "destructor" functions to get rid of the FuseHandle and NodeId resources properly -- in a way that matches each function's own purpose. For the time being, VirtioFsSimpleFileDelete() only gets a reminder about its core task (namely, removing the file), as the needed machinery will become only later. But we can already outline the "task list", and deal with the FuseHandle and NodeId resources. The "task list" of VirtioFsSimpleFileDelete() is different from that of VirtioFsSimpleFileClose(), thus both destructors diverge at this point. Cc: Ard Biesheuvel <ard.biesheuvel@arm.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Philippe Mathieu-Daudé <philmd@redhat.com> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3097 Signed-off-by: Laszlo Ersek <lersek@redhat.com> Message-Id: <20201216211125.19496-16-lersek@redhat.com> Acked-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
This commit is contained in:
committed by
mergify[bot]
parent
d047439952
commit
28092a3938
@@ -24,20 +24,36 @@ VirtioFsSimpleFileClose (
|
||||
VirtioFs = VirtioFsFile->OwnerFs;
|
||||
|
||||
//
|
||||
// At this point, the implementation is only suitable for closing the
|
||||
// VIRTIO_FS_FILE that was created by VirtioFsOpenVolume().
|
||||
// All actions in this function are "best effort"; the UEFI spec requires
|
||||
// EFI_FILE_PROTOCOL.Close() to sync all data to the device, but it also
|
||||
// requires EFI_FILE_PROTOCOL.Close() to release resources unconditionally,
|
||||
// and to return EFI_SUCCESS unconditionally.
|
||||
//
|
||||
ASSERT (VirtioFsFile->IsDirectory);
|
||||
ASSERT (VirtioFsFile->NodeId == VIRTIO_FS_FUSE_ROOT_DIR_NODE_ID);
|
||||
//
|
||||
// Close the root directory.
|
||||
//
|
||||
// Ignore any errors, because EFI_FILE_PROTOCOL.Close() is required to
|
||||
// release the EFI_FILE_PROTOCOL object unconditionally.
|
||||
// Flush, sync, release, and (if needed) forget. If any action fails, we
|
||||
// still try the others.
|
||||
//
|
||||
if (VirtioFsFile->IsOpenForWriting) {
|
||||
if (!VirtioFsFile->IsDirectory) {
|
||||
VirtioFsFuseFlush (VirtioFs, VirtioFsFile->NodeId,
|
||||
VirtioFsFile->FuseHandle);
|
||||
}
|
||||
|
||||
VirtioFsFuseFsyncFileOrDir (VirtioFs, VirtioFsFile->NodeId,
|
||||
VirtioFsFile->FuseHandle, VirtioFsFile->IsDirectory);
|
||||
}
|
||||
|
||||
VirtioFsFuseReleaseFileOrDir (VirtioFs, VirtioFsFile->NodeId,
|
||||
VirtioFsFile->FuseHandle, VirtioFsFile->IsDirectory);
|
||||
|
||||
//
|
||||
// VirtioFsFile->FuseHandle is gone at this point, but VirtioFsFile->NodeId
|
||||
// is still valid. If we've known VirtioFsFile->NodeId from a lookup, then
|
||||
// now we should ask the server to forget it *once*.
|
||||
//
|
||||
if (VirtioFsFile->NodeId != VIRTIO_FS_FUSE_ROOT_DIR_NODE_ID) {
|
||||
VirtioFsFuseForget (VirtioFs, VirtioFsFile->NodeId);
|
||||
}
|
||||
|
||||
//
|
||||
// One fewer file left open for the owner filesystem.
|
||||
//
|
||||
|
Reference in New Issue
Block a user