]> git.proxmox.com Git - mirror_edk2.git/commitdiff
OvmfPkg/VirtioFsDxe: handle attribute updates in EFI_FILE_PROTOCOL.SetInfo
authorLaszlo Ersek <lersek@redhat.com>
Wed, 16 Dec 2020 21:11:25 +0000 (22:11 +0100)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Mon, 21 Dec 2020 17:16:23 +0000 (17:16 +0000)
Using the functions introduced previously, we can now update file
attributes in VirtioFsSimpleFileSetInfo().

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-49-lersek@redhat.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
OvmfPkg/VirtioFsDxe/SimpleFsSetInfo.c

index 55169dde78b70a133d01d41495451d5ce42850fa..e7cc3d5dc3990fb0e182e631ba251655d5f1486a 100644 (file)
@@ -308,6 +308,111 @@ FreeDestination:
   return Status;\r
 }\r
 \r
+/**\r
+  Update the attributes of a VIRTIO_FS_FILE as requested in EFI_FILE_INFO.\r
+\r
+  @param[in,out] VirtioFsFile  The VIRTIO_FS_FILE to update the attributes of.\r
+\r
+  @param[in] NewFileInfo       The new attributes requested by\r
+                               EFI_FILE_PROTOCOL.SetInfo(). NewFileInfo->Size\r
+                               and NewFileInfo->FileName are ignored.\r
+\r
+  @retval EFI_SUCCESS        No attributes had to be updated.\r
+\r
+  @retval EFI_SUCCESS        The required set of attribute updates has been\r
+                             determined and performed successfully.\r
+\r
+  @retval EFI_ACCESS_DENIED  NewFileInfo requests an update to a property\r
+                             different from the EFI_FILE_READ_ONLY bit in the\r
+                             Attribute field, but VirtioFsFile is not open for\r
+                             writing.\r
+\r
+  @return                    Error codes propagated from underlying functions.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+UpdateAttributes (\r
+  IN OUT VIRTIO_FS_FILE *VirtioFsFile,\r
+  IN     EFI_FILE_INFO  *NewFileInfo\r
+  )\r
+{\r
+  VIRTIO_FS                          *VirtioFs;\r
+  EFI_STATUS                         Status;\r
+  VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE FuseAttr;\r
+  EFI_FILE_INFO                      FileInfo;\r
+  BOOLEAN                            UpdateFileSize;\r
+  UINT64                             FileSize;\r
+  BOOLEAN                            UpdateAtime;\r
+  BOOLEAN                            UpdateMtime;\r
+  UINT64                             Atime;\r
+  UINT64                             Mtime;\r
+  BOOLEAN                            UpdateMode;\r
+  UINT32                             Mode;\r
+\r
+  VirtioFs = VirtioFsFile->OwnerFs;\r
+\r
+  //\r
+  // Fetch the current attributes first, so we can build the difference between\r
+  // them and NewFileInfo.\r
+  //\r
+  Status = VirtioFsFuseGetAttr (VirtioFs, VirtioFsFile->NodeId, &FuseAttr);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  Status = VirtioFsFuseAttrToEfiFileInfo (&FuseAttr, &FileInfo);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  //\r
+  // Collect the updates.\r
+  //\r
+  if (VirtioFsFile->IsDirectory) {\r
+    UpdateFileSize = FALSE;\r
+  } else {\r
+    VirtioFsGetFuseSizeUpdate (&FileInfo, NewFileInfo, &UpdateFileSize,\r
+      &FileSize);\r
+  }\r
+\r
+  Status = VirtioFsGetFuseTimeUpdates (&FileInfo, NewFileInfo, &UpdateAtime,\r
+             &UpdateMtime, &Atime, &Mtime);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Status = VirtioFsGetFuseModeUpdate (&FileInfo, NewFileInfo, &UpdateMode,\r
+             &Mode);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // If no attribute updates are necessary, we're done.\r
+  //\r
+  if (!UpdateFileSize && !UpdateAtime && !UpdateMtime && !UpdateMode) {\r
+    return EFI_SUCCESS;\r
+  }\r
+  //\r
+  // If the file is not open for writing, then only Mode may be updated (for\r
+  // toggling EFI_FILE_READ_ONLY).\r
+  //\r
+  if (!VirtioFsFile->IsOpenForWriting &&\r
+      (UpdateFileSize || UpdateAtime || UpdateMtime)) {\r
+    return EFI_ACCESS_DENIED;\r
+  }\r
+  //\r
+  // Send the FUSE_SETATTR request now.\r
+  //\r
+  Status = VirtioFsFuseSetAttr (\r
+             VirtioFs,\r
+             VirtioFsFile->NodeId,\r
+             UpdateFileSize ? &FileSize : NULL,\r
+             UpdateAtime    ? &Atime    : NULL,\r
+             UpdateMtime    ? &Mtime    : NULL,\r
+             UpdateMode     ? &Mode     : NULL\r
+             );\r
+  return Status;\r
+}\r
+\r
 /**\r
   Process an EFI_FILE_INFO setting request.\r
 **/\r
@@ -350,7 +455,7 @@ SetFileInfo (
   //\r
   // Update any attributes requested.\r
   //\r
-  Status = EFI_UNSUPPORTED;\r
+  Status = UpdateAttributes (VirtioFsFile, FileInfo);\r
   //\r
   // The UEFI spec does not speak about partial failure in\r
   // EFI_FILE_PROTOCOL.SetInfo(); we won't try to roll back the rename (if\r