SimpleFsWrite.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /** @file
  2. EFI_FILE_PROTOCOL.Write() member function for the Virtio Filesystem driver.
  3. Copyright (C) 2020, Red Hat, Inc.
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include "VirtioFsDxe.h"
  7. EFI_STATUS
  8. EFIAPI
  9. VirtioFsSimpleFileWrite (
  10. IN EFI_FILE_PROTOCOL *This,
  11. IN OUT UINTN *BufferSize,
  12. IN VOID *Buffer
  13. )
  14. {
  15. VIRTIO_FS_FILE *VirtioFsFile;
  16. VIRTIO_FS *VirtioFs;
  17. EFI_STATUS Status;
  18. UINTN Transferred;
  19. UINTN Left;
  20. VirtioFsFile = VIRTIO_FS_FILE_FROM_SIMPLE_FILE (This);
  21. VirtioFs = VirtioFsFile->OwnerFs;
  22. if (VirtioFsFile->IsDirectory) {
  23. return EFI_UNSUPPORTED;
  24. }
  25. if (!VirtioFsFile->IsOpenForWriting) {
  26. return EFI_ACCESS_DENIED;
  27. }
  28. Status = EFI_SUCCESS;
  29. Transferred = 0;
  30. Left = *BufferSize;
  31. while (Left > 0) {
  32. UINT32 WriteSize;
  33. //
  34. // Honor the write buffer size limit.
  35. //
  36. WriteSize = (UINT32)MIN ((UINTN)VirtioFs->MaxWrite, Left);
  37. Status = VirtioFsFuseWrite (
  38. VirtioFs,
  39. VirtioFsFile->NodeId,
  40. VirtioFsFile->FuseHandle,
  41. VirtioFsFile->FilePosition + Transferred,
  42. &WriteSize,
  43. (UINT8 *)Buffer + Transferred
  44. );
  45. if (!EFI_ERROR (Status) && (WriteSize == 0)) {
  46. //
  47. // Progress should have been made.
  48. //
  49. Status = EFI_DEVICE_ERROR;
  50. }
  51. if (EFI_ERROR (Status)) {
  52. break;
  53. }
  54. Transferred += WriteSize;
  55. Left -= WriteSize;
  56. }
  57. *BufferSize = Transferred;
  58. VirtioFsFile->FilePosition += Transferred;
  59. //
  60. // According to the UEFI spec,
  61. //
  62. // - 'Partial writes only occur when there has been a data error during the
  63. // write attempt (such as "file space full")', and
  64. //
  65. // - (as an example) EFI_VOLUME_FULL is returned when 'The volume is full'.
  66. //
  67. // These together imply that after a partial write, we have to return an
  68. // error. In other words, (Transferred > 0) is inconsequential for the return
  69. // value.
  70. //
  71. return Status;
  72. }