/** @file
  EFI_FILE_PROTOCOL.GetInfo() 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>                // StrSize()
#include <Library/BaseMemoryLib.h>          // CompareGuid()

#include "VirtioFsDxe.h"

/**
  Provide EFI_FILE_INFO about this particular file.
**/
STATIC
EFI_STATUS
GetFileInfo (
  IN     EFI_FILE_PROTOCOL  *This,
  IN OUT UINTN              *BufferSize,
  OUT VOID                  *Buffer
  )
{
  VIRTIO_FS_FILE                      *VirtioFsFile;
  VIRTIO_FS                           *VirtioFs;
  UINTN                               AllocSize;
  UINTN                               BasenameSize;
  EFI_STATUS                          Status;
  EFI_FILE_INFO                       *FileInfo;
  VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE  FuseAttr;

  VirtioFsFile = VIRTIO_FS_FILE_FROM_SIMPLE_FILE (This);
  VirtioFs     = VirtioFsFile->OwnerFs;

  AllocSize = *BufferSize;

  //
  // Calculate the needed size.
  //
  BasenameSize = 0;
  Status       = VirtioFsGetBasename (
                   VirtioFsFile->CanonicalPathname,
                   NULL,
                   &BasenameSize
                   );
  ASSERT (Status == EFI_BUFFER_TOO_SMALL);
  *BufferSize = OFFSET_OF (EFI_FILE_INFO, FileName) + BasenameSize;

  if (*BufferSize > AllocSize) {
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // Set the structure size, and store the basename.
  //
  FileInfo       = Buffer;
  FileInfo->Size = *BufferSize;
  Status         = VirtioFsGetBasename (
                     VirtioFsFile->CanonicalPathname,
                     FileInfo->FileName,
                     &BasenameSize
                     );
  ASSERT_EFI_ERROR (Status);

  //
  // Fetch the file attributes, and convert them into the caller's buffer.
  //
  Status = VirtioFsFuseGetAttr (VirtioFs, VirtioFsFile->NodeId, &FuseAttr);
  if (!EFI_ERROR (Status)) {
    Status = VirtioFsFuseAttrToEfiFileInfo (&FuseAttr, FileInfo);
  }

  return (Status == EFI_BUFFER_TOO_SMALL) ? EFI_DEVICE_ERROR : Status;
}

/**
  Provide EFI_FILE_SYSTEM_INFO about the filesystem this file lives on.
**/
STATIC
EFI_STATUS
GetFileSystemInfo (
  IN     EFI_FILE_PROTOCOL  *This,
  IN OUT UINTN              *BufferSize,
  OUT VOID                  *Buffer
  )
{
  VIRTIO_FS_FILE                  *VirtioFsFile;
  VIRTIO_FS                       *VirtioFs;
  UINTN                           AllocSize;
  UINTN                           LabelSize;
  EFI_STATUS                      Status;
  VIRTIO_FS_FUSE_STATFS_RESPONSE  FilesysAttr;
  UINT64                          MaxBlocks;
  EFI_FILE_SYSTEM_INFO            *FilesysInfo;

  VirtioFsFile = VIRTIO_FS_FILE_FROM_SIMPLE_FILE (This);
  VirtioFs     = VirtioFsFile->OwnerFs;

  AllocSize = *BufferSize;

  //
  // Calculate the needed size.
  //
  LabelSize   = StrSize (VirtioFs->Label);
  *BufferSize = OFFSET_OF (EFI_FILE_SYSTEM_INFO, VolumeLabel) + LabelSize;

  if (*BufferSize > AllocSize) {
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // Fetch the filesystem attributes.
  //
  Status = VirtioFsFuseStatFs (VirtioFs, VirtioFsFile->NodeId, &FilesysAttr);
  if (EFI_ERROR (Status)) {
    return (Status == EFI_BUFFER_TOO_SMALL) ? EFI_DEVICE_ERROR : Status;
  }

  //
  // Sanity checks...
  //
  if (FilesysAttr.Frsize != FilesysAttr.Bsize) {
    return EFI_UNSUPPORTED;
  }

  if ((FilesysAttr.Frsize == 0) || (FilesysAttr.Blocks == 0) ||
      (FilesysAttr.Bavail > FilesysAttr.Blocks))
  {
    return EFI_DEVICE_ERROR;
  }

  MaxBlocks = DivU64x32 (MAX_UINT64, FilesysAttr.Frsize);
  if ((FilesysAttr.Blocks > MaxBlocks) || (FilesysAttr.Bavail > MaxBlocks)) {
    return EFI_DEVICE_ERROR;
  }

  //
  // Fill in EFI_FILE_SYSTEM_INFO.
  //
  FilesysInfo             = Buffer;
  FilesysInfo->Size       = *BufferSize;
  FilesysInfo->ReadOnly   = FALSE;
  FilesysInfo->VolumeSize = MultU64x32 (
                              FilesysAttr.Blocks,
                              FilesysAttr.Frsize
                              );
  FilesysInfo->FreeSpace = MultU64x32 (
                             FilesysAttr.Bavail,
                             FilesysAttr.Frsize
                             );
  FilesysInfo->BlockSize = FilesysAttr.Frsize;
  CopyMem (FilesysInfo->VolumeLabel, VirtioFs->Label, LabelSize);

  return EFI_SUCCESS;
}

/**
  Return the filesystem label as EFI_FILE_SYSTEM_VOLUME_LABEL.
**/
STATIC
EFI_STATUS
GetFileSystemVolumeLabelInfo (
  IN     EFI_FILE_PROTOCOL  *This,
  IN OUT UINTN              *BufferSize,
  OUT VOID                  *Buffer
  )
{
  VIRTIO_FS_FILE                *VirtioFsFile;
  VIRTIO_FS                     *VirtioFs;
  UINTN                         AllocSize;
  UINTN                         LabelSize;
  EFI_FILE_SYSTEM_VOLUME_LABEL  *FilesysVolumeLabel;

  VirtioFsFile = VIRTIO_FS_FILE_FROM_SIMPLE_FILE (This);
  VirtioFs     = VirtioFsFile->OwnerFs;

  AllocSize = *BufferSize;

  //
  // Calculate the needed size.
  //
  LabelSize   = StrSize (VirtioFs->Label);
  *BufferSize = (OFFSET_OF (EFI_FILE_SYSTEM_VOLUME_LABEL, VolumeLabel) +
                 LabelSize);

  if (*BufferSize > AllocSize) {
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // Store the label.
  //
  FilesysVolumeLabel = Buffer;
  CopyMem (FilesysVolumeLabel->VolumeLabel, VirtioFs->Label, LabelSize);

  return EFI_SUCCESS;
}

EFI_STATUS
EFIAPI
VirtioFsSimpleFileGetInfo (
  IN     EFI_FILE_PROTOCOL  *This,
  IN     EFI_GUID           *InformationType,
  IN OUT UINTN              *BufferSize,
  OUT VOID                  *Buffer
  )
{
  if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {
    return GetFileInfo (This, BufferSize, Buffer);
  }

  if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
    return GetFileSystemInfo (This, BufferSize, Buffer);
  }

  if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
    return GetFileSystemVolumeLabelInfo (This, BufferSize, Buffer);
  }

  return EFI_UNSUPPORTED;
}
