IN VOID *Buffer\r
)\r
{\r
- return EFI_NO_MEDIA;\r
+ VIRTIO_FS_FILE *VirtioFsFile;\r
+ VIRTIO_FS *VirtioFs;\r
+ EFI_STATUS Status;\r
+ UINTN Transferred;\r
+ UINTN Left;\r
+\r
+ VirtioFsFile = VIRTIO_FS_FILE_FROM_SIMPLE_FILE (This);\r
+ VirtioFs = VirtioFsFile->OwnerFs;\r
+\r
+ if (VirtioFsFile->IsDirectory) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ if (!VirtioFsFile->IsOpenForWriting) {\r
+ return EFI_ACCESS_DENIED;\r
+ }\r
+\r
+ Status = EFI_SUCCESS;\r
+ Transferred = 0;\r
+ Left = *BufferSize;\r
+ while (Left > 0) {\r
+ UINT32 WriteSize;\r
+\r
+ //\r
+ // Honor the write buffer size limit.\r
+ //\r
+ WriteSize = (UINT32)MIN ((UINTN)VirtioFs->MaxWrite, Left);\r
+ Status = VirtioFsFuseWrite (\r
+ VirtioFs,\r
+ VirtioFsFile->NodeId,\r
+ VirtioFsFile->FuseHandle,\r
+ VirtioFsFile->FilePosition + Transferred,\r
+ &WriteSize,\r
+ (UINT8 *)Buffer + Transferred\r
+ );\r
+ if (!EFI_ERROR (Status) && WriteSize == 0) {\r
+ //\r
+ // Progress should have been made.\r
+ //\r
+ Status = EFI_DEVICE_ERROR;\r
+ }\r
+ if (EFI_ERROR (Status)) {\r
+ break;\r
+ }\r
+ Transferred += WriteSize;\r
+ Left -= WriteSize;\r
+ }\r
+\r
+ *BufferSize = Transferred;\r
+ VirtioFsFile->FilePosition += Transferred;\r
+ //\r
+ // According to the UEFI spec,\r
+ //\r
+ // - 'Partial writes only occur when there has been a data error during the\r
+ // write attempt (such as "file space full")', and\r
+ //\r
+ // - (as an example) EFI_VOLUME_FULL is returned when 'The volume is full'.\r
+ //\r
+ // These together imply that after a partial write, we have to return an\r
+ // error. In other words, (Transferred > 0) is inconsequential for the return\r
+ // value.\r
+ //\r
+ return Status;\r
}\r