123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- /** @file
- EFI_FILE_PROTOCOL.Write() member function for the Virtio Filesystem driver.
- Copyright (C) 2020, Red Hat, Inc.
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "VirtioFsDxe.h"
- EFI_STATUS
- EFIAPI
- VirtioFsSimpleFileWrite (
- IN EFI_FILE_PROTOCOL *This,
- IN OUT UINTN *BufferSize,
- IN VOID *Buffer
- )
- {
- 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;
- }
|