/** @file
  EFI_FILE_PROTOCOL.SetInfo() member function for the Virtio Filesystem driver.

  Copyright (C) 2020, Red Hat, Inc.

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Guid/FileSystemInfo.h>            // gEfiFileSystemInfoGuid
#include <Guid/FileSystemVolumeLabelInfo.h> // gEfiFileSystemVolumeLabelInfo...
#include <Library/BaseLib.h>                // StrCmp()
#include <Library/BaseMemoryLib.h>          // CompareGuid()
#include <Library/MemoryAllocationLib.h>    // FreePool()

#include "VirtioFsDxe.h"

/**
  Validate a buffer that the EFI_FILE_PROTOCOL.SetInfo() caller passes in for a
  particular InformationType GUID.

  The structure to be validated is supposed to end with a variable-length,
  NUL-terminated CHAR16 Name string.

  @param[in] SizeByProtocolCaller  The BufferSize parameter as provided by the
                                   EFI_FILE_PROTOCOL.SetInfo() caller.

  @param[in] MinimumStructSize     The minimum structure size that is required
                                   for the given InformationType GUID,
                                   including a single CHAR16 element from the
                                   trailing Name field.

  @param[in] IsSizeByInfoPresent   TRUE if and only if the expected structure
                                   starts with a UINT64 Size field that reports
                                   the actual structure size.

  @param[in] Buffer                The Buffer parameter as provided by the
                                   EFI_FILE_PROTOCOL.SetInfo() caller.

  @retval EFI_SUCCESS            Validation successful, Buffer is well-formed.

  @retval EFI_BAD_BUFFER_SIZE    The EFI_FILE_PROTOCOL.SetInfo()
                                 caller provided a BufferSize that is smaller
                                 than the minimum structure size required for
                                 the given InformationType GUID.

  @retval EFI_INVALID_PARAMETER  IsSizeByInfoPresent is TRUE, and the leading
                                 UINT64 Size field does not match the
                                 EFI_FILE_PROTOCOL.SetInfo() caller-provided
                                 BufferSize.

  @retval EFI_INVALID_PARAMETER  The trailing Name field does not consist of a
                                 whole multiple of CHAR16 elements.

  @retval EFI_INVALID_PARAMETER  The trailing Name field is not NUL-terminated.
**/
STATIC
EFI_STATUS
ValidateInfoStructure (
  IN UINTN    SizeByProtocolCaller,
  IN UINTN    MinimumStructSize,
  IN BOOLEAN  IsSizeByInfoPresent,
  IN VOID     *Buffer
  )
{
  UINTN   NameFieldByteOffset;
  UINTN   NameFieldBytes;
  UINTN   NameFieldChar16s;
  CHAR16  *NameField;

  //
  // Make sure the internal function asking for validation passes in sane
  // values.
  //
  ASSERT (MinimumStructSize >= sizeof (CHAR16));
  NameFieldByteOffset = MinimumStructSize - sizeof (CHAR16);

  if (IsSizeByInfoPresent) {
    ASSERT (MinimumStructSize >= sizeof (UINT64) + sizeof (CHAR16));
    ASSERT (NameFieldByteOffset >= sizeof (UINT64));
  }

  //
  // Check whether the protocol caller provided enough bytes for the minimum
  // size of this info structure.
  //
  if (SizeByProtocolCaller < MinimumStructSize) {
    return EFI_BAD_BUFFER_SIZE;
  }

  //
  // If the info structure starts with a UINT64 Size field, check if that
  // agrees with the protocol caller-provided size.
  //
  if (IsSizeByInfoPresent) {
    UINT64  *SizeByInfo;

    SizeByInfo = Buffer;
    if (*SizeByInfo != SizeByProtocolCaller) {
      return EFI_INVALID_PARAMETER;
    }
  }

  //
  // The CHAR16 Name field at the end of the structure must have an even number
  // of bytes.
  //
  // The subtraction below cannot underflow, and yields at least
  // sizeof(CHAR16).
  //
  ASSERT (SizeByProtocolCaller >= NameFieldByteOffset);
  NameFieldBytes = SizeByProtocolCaller - NameFieldByteOffset;
  ASSERT (NameFieldBytes >= sizeof (CHAR16));
  if (NameFieldBytes % sizeof (CHAR16) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // The CHAR16 Name field at the end of the structure must be NUL-terminated.
  //
  NameFieldChar16s = NameFieldBytes / sizeof (CHAR16);
  ASSERT (NameFieldChar16s >= 1);

  NameField = (CHAR16 *)((UINT8 *)Buffer + NameFieldByteOffset);
  if (NameField[NameFieldChar16s - 1] != L'\0') {
    return EFI_INVALID_PARAMETER;
  }

  return EFI_SUCCESS;
}

/**
  Rename a VIRTIO_FS_FILE as requested in EFI_FILE_INFO.FileName.

  @param[in,out] VirtioFsFile  The VIRTIO_FS_FILE to rename.

  @param[in] NewFileName       The new file name requested by
                               EFI_FILE_PROTOCOL.SetInfo().

  @retval EFI_SUCCESS        The canonical format destination path that is
                             determined from the input value of
                             VirtioFsFile->CanonicalPathname and from
                             NewFileName is identical to the input value of
                             VirtioFsFile->CanonicalPathname. This means that
                             EFI_FILE_INFO does not constitute a rename
                             request. VirtioFsFile has not been changed.

  @retval EFI_SUCCESS        VirtioFsFile has been renamed.
                             VirtioFsFile->CanonicalPathname has assumed the
                             destination pathname in canonical format.

  @retval EFI_ACCESS_DENIED  VirtioFsFile refers to the root directory, and
                             NewFileName expresses an actual rename/move
                             request.

  @retval EFI_ACCESS_DENIED  VirtioFsFile is the (possibly indirect) parent
                             directory of at least one other VIRTIO_FS_FILE
                             that is open for the same Virtio Filesystem
                             (identified by VirtioFsFile->OwnerFs). Renaming
                             VirtioFsFile would invalidate the canonical
                             pathnames of those VIRTIO_FS_FILE instances;
                             therefore the request has been rejected.

  @retval EFI_ACCESS_DENIED  VirtioFsFile is not open for writing, but
                             NewFileName expresses an actual rename/move
                             request.

  @retval EFI_NOT_FOUND      At least one dot-dot component in NewFileName
                             attempted to escape the root directory.

  @return                    Error codes propagated from underlying functions.
**/
STATIC
EFI_STATUS
Rename (
  IN OUT VIRTIO_FS_FILE  *VirtioFsFile,
  IN     CHAR16          *NewFileName
  )
{
  VIRTIO_FS   *VirtioFs;
  EFI_STATUS  Status;
  CHAR8       *Destination;
  BOOLEAN     RootEscape;
  UINT64      OldParentDirNodeId;
  CHAR8       *OldLastComponent;
  UINT64      NewParentDirNodeId;
  CHAR8       *NewLastComponent;

  VirtioFs = VirtioFsFile->OwnerFs;

  //
  // The root directory cannot be renamed.
  //
  if (AsciiStrCmp (VirtioFsFile->CanonicalPathname, "/") == 0) {
    if (StrCmp (NewFileName, L"") == 0) {
      //
      // Not a rename request anyway.
      //
      return EFI_SUCCESS;
    }

    return EFI_ACCESS_DENIED;
  }

  //
  // Compose the canonical pathname for the destination.
  //
  Status = VirtioFsComposeRenameDestination (
             VirtioFsFile->CanonicalPathname,
             NewFileName,
             &Destination,
             &RootEscape
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (RootEscape) {
    Status = EFI_NOT_FOUND;
    goto FreeDestination;
  }

  //
  // If the rename would leave VirtioFsFile->CanonicalPathname unchanged, then
  // EFI_FILE_PROTOCOL.SetInfo() isn't asking for a rename actually.
  //
  if (AsciiStrCmp (VirtioFsFile->CanonicalPathname, Destination) == 0) {
    Status = EFI_SUCCESS;
    goto FreeDestination;
  }

  //
  // Check if the rename would break the canonical pathnames of other
  // VIRTIO_FS_FILE instances of the same VIRTIO_FS.
  //
  if (VirtioFsFile->IsDirectory) {
    UINTN       PathLen;
    LIST_ENTRY  *OpenFilesEntry;

    PathLen = AsciiStrLen (VirtioFsFile->CanonicalPathname);
    BASE_LIST_FOR_EACH (OpenFilesEntry, &VirtioFs->OpenFiles) {
      VIRTIO_FS_FILE  *OtherFile;

      OtherFile = VIRTIO_FS_FILE_FROM_OPEN_FILES_ENTRY (OpenFilesEntry);
      if ((OtherFile != VirtioFsFile) &&
          (AsciiStrnCmp (
             VirtioFsFile->CanonicalPathname,
             OtherFile->CanonicalPathname,
             PathLen
             ) == 0) &&
          ((OtherFile->CanonicalPathname[PathLen] == '\0') ||
           (OtherFile->CanonicalPathname[PathLen] == '/')))
      {
        //
        // OtherFile refers to the same directory as VirtioFsFile, or is a
        // (possibly indirect) child of the directory referred to by
        // VirtioFsFile.
        //
        Status = EFI_ACCESS_DENIED;
        goto FreeDestination;
      }
    }
  }

  //
  // From this point on, the file needs to be open for writing.
  //
  if (!VirtioFsFile->IsOpenForWriting) {
    Status = EFI_ACCESS_DENIED;
    goto FreeDestination;
  }

  //
  // Split both source and destination canonical pathnames into (most specific
  // parent directory, last component) pairs.
  //
  Status = VirtioFsLookupMostSpecificParentDir (
             VirtioFs,
             VirtioFsFile->CanonicalPathname,
             &OldParentDirNodeId,
             &OldLastComponent
             );
  if (EFI_ERROR (Status)) {
    goto FreeDestination;
  }

  Status = VirtioFsLookupMostSpecificParentDir (
             VirtioFs,
             Destination,
             &NewParentDirNodeId,
             &NewLastComponent
             );
  if (EFI_ERROR (Status)) {
    goto ForgetOldParentDirNodeId;
  }

  //
  // Perform the rename. If the destination path exists, the rename will fail.
  //
  Status = VirtioFsFuseRename (
             VirtioFs,
             OldParentDirNodeId,
             OldLastComponent,
             NewParentDirNodeId,
             NewLastComponent
             );
  if (EFI_ERROR (Status)) {
    goto ForgetNewParentDirNodeId;
  }

  //
  // Swap in the new canonical pathname.
  //
  FreePool (VirtioFsFile->CanonicalPathname);
  VirtioFsFile->CanonicalPathname = Destination;
  Destination                     = NULL;
  Status                          = EFI_SUCCESS;

  //
  // Fall through.
  //
ForgetNewParentDirNodeId:
  if (NewParentDirNodeId != VIRTIO_FS_FUSE_ROOT_DIR_NODE_ID) {
    VirtioFsFuseForget (VirtioFs, NewParentDirNodeId);
  }

ForgetOldParentDirNodeId:
  if (OldParentDirNodeId != VIRTIO_FS_FUSE_ROOT_DIR_NODE_ID) {
    VirtioFsFuseForget (VirtioFs, OldParentDirNodeId);
  }

FreeDestination:
  if (Destination != NULL) {
    FreePool (Destination);
  }

  return Status;
}

/**
  Update the attributes of a VIRTIO_FS_FILE as requested in EFI_FILE_INFO.

  @param[in,out] VirtioFsFile  The VIRTIO_FS_FILE to update the attributes of.

  @param[in] NewFileInfo       The new attributes requested by
                               EFI_FILE_PROTOCOL.SetInfo(). NewFileInfo->Size
                               and NewFileInfo->FileName are ignored.

  @retval EFI_SUCCESS        No attributes had to be updated.

  @retval EFI_SUCCESS        The required set of attribute updates has been
                             determined and performed successfully.

  @retval EFI_ACCESS_DENIED  NewFileInfo requests an update to a property
                             different from the EFI_FILE_READ_ONLY bit in the
                             Attribute field, but VirtioFsFile is not open for
                             writing.

  @return                    Error codes propagated from underlying functions.
**/
STATIC
EFI_STATUS
UpdateAttributes (
  IN OUT VIRTIO_FS_FILE  *VirtioFsFile,
  IN     EFI_FILE_INFO   *NewFileInfo
  )
{
  VIRTIO_FS                           *VirtioFs;
  EFI_STATUS                          Status;
  VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE  FuseAttr;
  EFI_FILE_INFO                       FileInfo;
  BOOLEAN                             UpdateFileSize;
  UINT64                              FileSize;
  BOOLEAN                             UpdateAtime;
  BOOLEAN                             UpdateMtime;
  UINT64                              Atime;
  UINT64                              Mtime;
  BOOLEAN                             UpdateMode;
  UINT32                              Mode;

  VirtioFs = VirtioFsFile->OwnerFs;

  //
  // Fetch the current attributes first, so we can build the difference between
  // them and NewFileInfo.
  //
  Status = VirtioFsFuseGetAttr (VirtioFs, VirtioFsFile->NodeId, &FuseAttr);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = VirtioFsFuseAttrToEfiFileInfo (&FuseAttr, &FileInfo);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Collect the updates.
  //
  if (VirtioFsFile->IsDirectory) {
    UpdateFileSize = FALSE;
  } else {
    VirtioFsGetFuseSizeUpdate (
      &FileInfo,
      NewFileInfo,
      &UpdateFileSize,
      &FileSize
      );
  }

  Status = VirtioFsGetFuseTimeUpdates (
             &FileInfo,
             NewFileInfo,
             &UpdateAtime,
             &UpdateMtime,
             &Atime,
             &Mtime
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = VirtioFsGetFuseModeUpdate (
             &FileInfo,
             NewFileInfo,
             &UpdateMode,
             &Mode
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // If no attribute updates are necessary, we're done.
  //
  if (!UpdateFileSize && !UpdateAtime && !UpdateMtime && !UpdateMode) {
    return EFI_SUCCESS;
  }

  //
  // If the file is not open for writing, then only Mode may be updated (for
  // toggling EFI_FILE_READ_ONLY).
  //
  if (!VirtioFsFile->IsOpenForWriting &&
      (UpdateFileSize || UpdateAtime || UpdateMtime))
  {
    return EFI_ACCESS_DENIED;
  }

  //
  // Send the FUSE_SETATTR request now.
  //
  Status = VirtioFsFuseSetAttr (
             VirtioFs,
             VirtioFsFile->NodeId,
             UpdateFileSize ? &FileSize : NULL,
             UpdateAtime    ? &Atime    : NULL,
             UpdateMtime    ? &Mtime    : NULL,
             UpdateMode     ? &Mode     : NULL
             );
  return Status;
}

/**
  Process an EFI_FILE_INFO setting request.
**/
STATIC
EFI_STATUS
SetFileInfo (
  IN EFI_FILE_PROTOCOL  *This,
  IN UINTN              BufferSize,
  IN VOID               *Buffer
  )
{
  VIRTIO_FS_FILE  *VirtioFsFile;
  EFI_STATUS      Status;
  EFI_FILE_INFO   *FileInfo;

  VirtioFsFile = VIRTIO_FS_FILE_FROM_SIMPLE_FILE (This);

  //
  // Validate if Buffer passes as EFI_FILE_INFO.
  //
  Status = ValidateInfoStructure (
             BufferSize,                    // SizeByProtocolCaller
             OFFSET_OF (
               EFI_FILE_INFO,
               FileName
               ) + sizeof (CHAR16),         // MinimumStructSize
             TRUE,                          // IsSizeByInfoPresent
             Buffer
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  FileInfo = Buffer;

  //
  // Perform the rename/move request, if any.
  //
  Status = Rename (VirtioFsFile, FileInfo->FileName);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Update any attributes requested.
  //
  Status = UpdateAttributes (VirtioFsFile, FileInfo);
  //
  // The UEFI spec does not speak about partial failure in
  // EFI_FILE_PROTOCOL.SetInfo(); we won't try to roll back the rename (if
  // there was one) in case the attribute updates fail.
  //
  return Status;
}

/**
  Process an EFI_FILE_SYSTEM_INFO setting request.
**/
STATIC
EFI_STATUS
SetFileSystemInfo (
  IN EFI_FILE_PROTOCOL  *This,
  IN UINTN              BufferSize,
  IN VOID               *Buffer
  )
{
  VIRTIO_FS_FILE        *VirtioFsFile;
  VIRTIO_FS             *VirtioFs;
  EFI_STATUS            Status;
  EFI_FILE_SYSTEM_INFO  *FileSystemInfo;

  VirtioFsFile = VIRTIO_FS_FILE_FROM_SIMPLE_FILE (This);
  VirtioFs     = VirtioFsFile->OwnerFs;

  //
  // Validate if Buffer passes as EFI_FILE_SYSTEM_INFO.
  //
  Status = ValidateInfoStructure (
             BufferSize,                       // SizeByProtocolCaller
             OFFSET_OF (
               EFI_FILE_SYSTEM_INFO,
               VolumeLabel
               ) + sizeof (CHAR16),            // MinimumStructSize
             TRUE,                             // IsSizeByInfoPresent
             Buffer
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  FileSystemInfo = Buffer;

  //
  // EFI_FILE_SYSTEM_INFO fields other than VolumeLabel cannot be changed, per
  // spec.
  //
  // If the label is being changed to its current value, report success;
  // otherwise, reject the request, as the Virtio Filesystem device does not
  // support changing the label.
  //
  if (StrCmp (FileSystemInfo->VolumeLabel, VirtioFs->Label) == 0) {
    return EFI_SUCCESS;
  }

  return EFI_WRITE_PROTECTED;
}

/**
  Process an EFI_FILE_SYSTEM_VOLUME_LABEL setting request.
**/
STATIC
EFI_STATUS
SetFileSystemVolumeLabelInfo (
  IN EFI_FILE_PROTOCOL  *This,
  IN UINTN              BufferSize,
  IN VOID               *Buffer
  )
{
  VIRTIO_FS_FILE                *VirtioFsFile;
  VIRTIO_FS                     *VirtioFs;
  EFI_STATUS                    Status;
  EFI_FILE_SYSTEM_VOLUME_LABEL  *FileSystemVolumeLabel;

  VirtioFsFile = VIRTIO_FS_FILE_FROM_SIMPLE_FILE (This);
  VirtioFs     = VirtioFsFile->OwnerFs;

  //
  // Validate if Buffer passes as EFI_FILE_SYSTEM_VOLUME_LABEL.
  //
  Status = ValidateInfoStructure (
             BufferSize,                              // SizeByProtocolCaller
             OFFSET_OF (
               EFI_FILE_SYSTEM_VOLUME_LABEL,
               VolumeLabel
               ) + sizeof (CHAR16),                   // MinimumStructSize
             FALSE,                                   // IsSizeByInfoPresent
             Buffer
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  FileSystemVolumeLabel = Buffer;

  //
  // If the label is being changed to its current value, report success;
  // otherwise, reject the request, as the Virtio Filesystem device does not
  // support changing the label.
  //
  if (StrCmp (FileSystemVolumeLabel->VolumeLabel, VirtioFs->Label) == 0) {
    return EFI_SUCCESS;
  }

  return EFI_WRITE_PROTECTED;
}

EFI_STATUS
EFIAPI
VirtioFsSimpleFileSetInfo (
  IN EFI_FILE_PROTOCOL  *This,
  IN EFI_GUID           *InformationType,
  IN UINTN              BufferSize,
  IN VOID               *Buffer
  )
{
  if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {
    return SetFileInfo (This, BufferSize, Buffer);
  }

  if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
    return SetFileSystemInfo (This, BufferSize, Buffer);
  }

  if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
    return SetFileSystemVolumeLabelInfo (This, BufferSize, Buffer);
  }

  return EFI_UNSUPPORTED;
}
