Using the functions introduced previously, we can now implement VirtioFsSimpleFileWrite().
Cc: Ard Biesheuvel <[email protected]> Cc: Jordan Justen <[email protected]> Cc: Philippe Mathieu-Daudé <[email protected]> Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3097 Signed-off-by: Laszlo Ersek <[email protected]> --- OvmfPkg/VirtioFsDxe/SimpleFsWrite.c | 63 +++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/OvmfPkg/VirtioFsDxe/SimpleFsWrite.c b/OvmfPkg/VirtioFsDxe/SimpleFsWrite.c index 90d82bd722b1..8ae317c88e43 100644 --- a/OvmfPkg/VirtioFsDxe/SimpleFsWrite.c +++ b/OvmfPkg/VirtioFsDxe/SimpleFsWrite.c @@ -11,10 +11,71 @@ EFI_STATUS EFIAPI VirtioFsSimpleFileWrite ( IN EFI_FILE_PROTOCOL *This, IN OUT UINTN *BufferSize, IN VOID *Buffer ) { - return EFI_NO_MEDIA; + VIRTIO_FS_FILE *VirtioFsFile; + VIRTIO_FS *VirtioFs; + EFI_STATUS Status; + UINTN Transferred; + UINTN Left; + + VirtioFsFile = VIRTIO_FS_FILE_FROM_SIMPLE_FILE (This); + VirtioFs = VirtioFsFile->OwnerFs; + + if (VirtioFsFile->IsDirectory) { + return EFI_UNSUPPORTED; + } + if (!VirtioFsFile->IsOpenForWriting) { + return EFI_ACCESS_DENIED; + } + + Status = EFI_SUCCESS; + Transferred = 0; + Left = *BufferSize; + while (Left > 0) { + UINT32 WriteSize; + + // + // Honor the write buffer size limit. + // + WriteSize = (UINT32)MIN ((UINTN)VirtioFs->MaxWrite, Left); + Status = VirtioFsFuseWrite ( + VirtioFs, + VirtioFsFile->NodeId, + VirtioFsFile->FuseHandle, + VirtioFsFile->FilePosition + Transferred, + &WriteSize, + (UINT8 *)Buffer + Transferred + ); + if (!EFI_ERROR (Status) && WriteSize == 0) { + // + // Progress should have been made. + // + Status = EFI_DEVICE_ERROR; + } + if (EFI_ERROR (Status)) { + break; + } + Transferred += WriteSize; + Left -= WriteSize; + } + + *BufferSize = Transferred; + VirtioFsFile->FilePosition += Transferred; + // + // According to the UEFI spec, + // + // - 'Partial writes only occur when there has been a data error during the + // write attempt (such as "file space full")', and + // + // - (as an example) EFI_VOLUME_FULL is returned when 'The volume is full'. + // + // These together imply that after a partial write, we have to return an + // error. In other words, (Transferred > 0) is inconsequential for the return + // value. + // + return Status; } -- 2.19.1.3.g30247aa5d201 _______________________________________________ Virtio-fs mailing list [email protected] https://www.redhat.com/mailman/listinfo/virtio-fs
