/** @file
  EFI_FILE_PROTOCOL.Read() member function for the Virtio Filesystem driver.

  Copyright (C) 2020, Red Hat, Inc.

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Library/BaseMemoryLib.h>       // CopyMem()
#include <Library/MemoryAllocationLib.h> // AllocatePool()

#include "VirtioFsDxe.h"

/**
  Populate a caller-allocated EFI_FILE_INFO object from
  VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE.

  @param[in] Dirent              The entry read from the directory stream. The
                                 caller is responsible for ensuring that
                                 Dirent->Namelen describe valid storage.

  @param[in] SingleFileInfoSize  The allocated size of FileInfo.

  @param[out] FileInfo           The EFI_FILE_INFO object to populate. On
                                 success, all fields in FileInfo will be
                                 updated, setting FileInfo->Size to the
                                 actually used size (which will not exceed
                                 SingleFileInfoSize).

  @retval EFI_SUCCESS  FileInfo has been filled in.

  @return              Error codes propagated from
                       VirtioFsFuseDirentPlusToEfiFileInfo() and
                       VirtioFsFuseAttrToEfiFileInfo(). The contents of
                       FileInfo are indeterminate.
**/
STATIC
EFI_STATUS
PopulateFileInfo (
  IN     VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE *Dirent,
  IN     UINTN                              SingleFileInfoSize,
     OUT EFI_FILE_INFO                      *FileInfo
  )
{
  EFI_STATUS Status;

  //
  // Convert the name, set the actual size.
  //
  FileInfo->Size = SingleFileInfoSize;
  Status = VirtioFsFuseDirentPlusToEfiFileInfo (Dirent, FileInfo);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Populate the scalar fields.
  //
  Status = VirtioFsFuseAttrToEfiFileInfo (&Dirent->AttrResp, FileInfo);
  return Status;
}

/**
  Refill the EFI_FILE_INFO cache from the directory stream.
**/
STATIC
EFI_STATUS
RefillFileInfoCache (
  IN OUT VIRTIO_FS_FILE *VirtioFsFile
  )
{
  VIRTIO_FS                      *VirtioFs;
  EFI_STATUS                     Status;
  VIRTIO_FS_FUSE_STATFS_RESPONSE FilesysAttr;
  UINT32                         DirentBufSize;
  UINT8                          *DirentBuf;
  UINTN                          SingleFileInfoSize;
  UINT8                          *FileInfoArray;
  UINT64                         DirStreamCookie;
  UINT64                         CacheEndsAtCookie;
  UINTN                          NumFileInfo;

  //
  // Allocate a DirentBuf that can receive at least
  // VIRTIO_FS_FILE_MAX_FILE_INFO directory entries, based on the maximum
  // filename length supported by the filesystem. Note that the multiplication
  // is safe from overflow due to the VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE_SIZE()
  // check.
  //
  VirtioFs = VirtioFsFile->OwnerFs;
  Status = VirtioFsFuseStatFs (VirtioFs, VirtioFsFile->NodeId, &FilesysAttr);
  if (EFI_ERROR (Status)) {
    return Status;
  }
  DirentBufSize = (UINT32)VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE_SIZE (
                            FilesysAttr.Namelen);
  if (DirentBufSize == 0) {
    return EFI_UNSUPPORTED;
  }
  DirentBufSize *= VIRTIO_FS_FILE_MAX_FILE_INFO;
  DirentBuf = AllocatePool (DirentBufSize);
  if (DirentBuf == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Allocate the EFI_FILE_INFO cache. A single EFI_FILE_INFO element is sized
  // accordingly to the maximum filename length supported by the filesystem.
  //
  // Note that the calculation below cannot overflow, due to the filename limit
  // imposed by the VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE_SIZE() check above. The
  // calculation takes the L'\0' character that we'll need to append into
  // account.
  //
  SingleFileInfoSize = (OFFSET_OF (EFI_FILE_INFO, FileName) +
                        ((UINTN)FilesysAttr.Namelen + 1) * sizeof (CHAR16));
  FileInfoArray = AllocatePool (
                    VIRTIO_FS_FILE_MAX_FILE_INFO * SingleFileInfoSize
                    );
  if (FileInfoArray == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto FreeDirentBuf;
  }

  //
  // Pick up reading the directory stream where the previous cache ended.
  //
  DirStreamCookie   = VirtioFsFile->FilePosition;
  CacheEndsAtCookie = VirtioFsFile->FilePosition;
  NumFileInfo       = 0;
  do {
    UINT32 Remaining;
    UINT32 Consumed;

    //
    // Fetch a chunk of the directory stream. The chunk may hold more entries
    // than what we can fit in the cache. The chunk may also not entirely fill
    // the cache, especially after filtering out entries that cannot be
    // supported under UEFI (sockets, FIFOs, filenames with backslashes, etc).
    //
    Remaining = DirentBufSize;
    Status = VirtioFsFuseReadFileOrDir (
               VirtioFs,
               VirtioFsFile->NodeId,
               VirtioFsFile->FuseHandle,
               TRUE,                     // IsDir
               DirStreamCookie,          // Offset
               &Remaining,               // Size
               DirentBuf                 // Data
               );
    if (EFI_ERROR (Status)) {
      goto FreeFileInfoArray;
    }

    if (Remaining == 0) {
      //
      // The directory stream ends.
      //
      break;
    }

    //
    // Iterate over all records in DirentBuf. Primarily, forget them all.
    // Secondarily, if a record proves transformable to EFI_FILE_INFO, add it
    // to the EFI_FILE_INFO cache (unless the cache is full).
    //
    Consumed = 0;
    while (Remaining >= sizeof (VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE)) {
      VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE *Dirent;
      UINT32                             DirentSize;

      Dirent = (VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE *)(DirentBuf + Consumed);
      DirentSize = (UINT32)VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE_SIZE (
                             Dirent->Namelen);
      if (DirentSize == 0) {
        //
        // This means one of two things: (a) Dirent->Namelen is zero, or (b)
        // (b) Dirent->Namelen is unsupportably large. (a) is just invalid for
        // the Virtio Filesystem device to send, while (b) shouldn't happen
        // because "FilesysAttr.Namelen" -- the maximum filename length
        // supported by the filesystem -- proved acceptable above.
        //
        Status = EFI_PROTOCOL_ERROR;
        goto FreeFileInfoArray;
      }
      if (DirentSize > Remaining) {
        //
        // Dirent->Namelen suggests that the filename byte array (plus any
        // padding) are truncated. This should never happen; the Virtio
        // Filesystem device is supposed to send complete entries only.
        //
        Status = EFI_PROTOCOL_ERROR;
        goto FreeFileInfoArray;
      }
      if (Dirent->Namelen > FilesysAttr.Namelen) {
        //
        // This is possible without tripping the truncation check above, due to
        // how entries are padded. The condition means that Dirent->Namelen is
        // reportedly larger than the filesystem limit, without spilling into
        // the next alignment bucket. Should never happen.
        //
        Status = EFI_PROTOCOL_ERROR;
        goto FreeFileInfoArray;
      }

      //
      // If we haven't filled the EFI_FILE_INFO cache yet, attempt transforming
      // Dirent to EFI_FILE_INFO.
      //
      if (NumFileInfo < VIRTIO_FS_FILE_MAX_FILE_INFO) {
        EFI_FILE_INFO *FileInfo;

        FileInfo = (EFI_FILE_INFO *)(FileInfoArray +
                                     (NumFileInfo * SingleFileInfoSize));
        Status = PopulateFileInfo (Dirent, SingleFileInfoSize, FileInfo);
        if (!EFI_ERROR (Status)) {
          //
          // Dirent has been transformed and cached successfully.
          //
          NumFileInfo++;
          //
          // The next time we refill the cache, restart reading the directory
          // stream right after the entry that we've just transformed and
          // cached.
          //
          CacheEndsAtCookie = Dirent->CookieForNextEntry;
        }
        //
        // If Dirent wasn't transformable to an EFI_FILE_INFO, we'll just skip
        // it.
        //
      }

      //
      // Make the Virtio Filesystem device forget the NodeId in this directory
      // entry, as we'll need it no more. (The "." and ".." entries need no
      // FUSE_FORGET requests, when returned by FUSE_READDIRPLUS -- and so the
      // Virtio Filesystem device reports their NodeId fields as zero.)
      //
      if (Dirent->NodeResp.NodeId != 0) {
        VirtioFsFuseForget (VirtioFs, Dirent->NodeResp.NodeId);
      }

      //
      // Advance to the next entry in DirentBuf.
      //
      DirStreamCookie = Dirent->CookieForNextEntry;
      Consumed += DirentSize;
      Remaining -= DirentSize;
    }

    if (Remaining > 0) {
      //
      // This suggests that a VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE header was
      // truncated. This should never happen; the Virtio Filesystem device is
      // supposed to send complete entries only.
      //
      Status = EFI_PROTOCOL_ERROR;
      goto FreeFileInfoArray;
    }
    //
    // Fetch another DirentBuf from the directory stream, unless we've filled
    // the EFI_FILE_INFO cache.
    //
  } while (NumFileInfo < VIRTIO_FS_FILE_MAX_FILE_INFO);

  //
  // Commit the results. (Note that the result may be an empty cache.)
  //
  if (VirtioFsFile->FileInfoArray != NULL) {
    FreePool (VirtioFsFile->FileInfoArray);
  }
  VirtioFsFile->FileInfoArray      = FileInfoArray;
  VirtioFsFile->SingleFileInfoSize = SingleFileInfoSize;
  VirtioFsFile->NumFileInfo        = NumFileInfo;
  VirtioFsFile->NextFileInfo       = 0;
  VirtioFsFile->FilePosition       = CacheEndsAtCookie;

  FreePool (DirentBuf);
  return EFI_SUCCESS;

FreeFileInfoArray:
  FreePool (FileInfoArray);

FreeDirentBuf:
  FreePool (DirentBuf);

  return Status;
}

/**
  Read an entry from the EFI_FILE_INFO cache.
**/
STATIC
EFI_STATUS
ReadFileInfoCache (
  IN OUT VIRTIO_FS_FILE *VirtioFsFile,
  IN OUT UINTN          *BufferSize,
     OUT VOID           *Buffer
  )
{
  EFI_FILE_INFO *FileInfo;
  UINTN         CallerAllocated;

  //
  // Refill the cache if needed. If the refill doesn't produce any new
  // EFI_FILE_INFO, report End of Directory, by setting (*BufferSize) to 0.
  //
  if (VirtioFsFile->NextFileInfo == VirtioFsFile->NumFileInfo) {
    EFI_STATUS Status;

    Status = RefillFileInfoCache (VirtioFsFile);
    if (EFI_ERROR (Status)) {
      return (Status == EFI_BUFFER_TOO_SMALL) ? EFI_DEVICE_ERROR : Status;
    }
    if (VirtioFsFile->NumFileInfo == 0) {
      *BufferSize = 0;
      return EFI_SUCCESS;
    }
  }
  FileInfo = (EFI_FILE_INFO *)(VirtioFsFile->FileInfoArray +
                               (VirtioFsFile->NextFileInfo *
                                VirtioFsFile->SingleFileInfoSize));

  //
  // Check if the caller is ready to accept FileInfo. If not, we'll just
  // present the required size for now.
  //
  // (The (UINTN) cast below is safe because FileInfo->Size has been reduced
  // from VirtioFsFile->SingleFileInfoSize, in
  //
  //   RefillFileInfoCache()
  //     PopulateFileInfo()
  //       VirtioFsFuseDirentPlusToEfiFileInfo()
  //
  // and VirtioFsFile->SingleFileInfoSize was computed from
  // FilesysAttr.Namelen, which had been accepted by
  // VIRTIO_FS_FUSE_DIRENTPLUS_RESPONSE_SIZE().)
  //
  CallerAllocated = *BufferSize;
  *BufferSize = (UINTN)FileInfo->Size;
  if (CallerAllocated < *BufferSize) {
    return EFI_BUFFER_TOO_SMALL;
  }
  //
  // Output FileInfo, and remove it from the cache.
  //
  CopyMem (Buffer, FileInfo, *BufferSize);
  VirtioFsFile->NextFileInfo++;
  return EFI_SUCCESS;
}

/**
  Read from a regular file.
**/
STATIC
EFI_STATUS
ReadRegularFile (
  IN OUT VIRTIO_FS_FILE *VirtioFsFile,
  IN OUT UINTN          *BufferSize,
     OUT VOID           *Buffer
  )
{
  VIRTIO_FS                          *VirtioFs;
  EFI_STATUS                         Status;
  VIRTIO_FS_FUSE_ATTRIBUTES_RESPONSE FuseAttr;
  UINTN                              Transferred;
  UINTN                              Left;

  VirtioFs = VirtioFsFile->OwnerFs;
  //
  // The UEFI spec forbids reads that start beyond the end of the file.
  //
  Status = VirtioFsFuseGetAttr (VirtioFs, VirtioFsFile->NodeId, &FuseAttr);
  if (EFI_ERROR (Status) || VirtioFsFile->FilePosition > FuseAttr.Size) {
    return EFI_DEVICE_ERROR;
  }

  Status      = EFI_SUCCESS;
  Transferred = 0;
  Left        = *BufferSize;
  while (Left > 0) {
    UINT32 ReadSize;

    //
    // FUSE_READ cannot express a >=4GB buffer size.
    //
    ReadSize = (UINT32)MIN ((UINTN)MAX_UINT32, Left);
    Status = VirtioFsFuseReadFileOrDir (
               VirtioFs,
               VirtioFsFile->NodeId,
               VirtioFsFile->FuseHandle,
               FALSE,                                    // IsDir
               VirtioFsFile->FilePosition + Transferred,
               &ReadSize,
               (UINT8 *)Buffer + Transferred
               );
    if (EFI_ERROR (Status) || ReadSize == 0) {
      break;
    }
    Transferred += ReadSize;
    Left        -= ReadSize;
  }

  *BufferSize = Transferred;
  VirtioFsFile->FilePosition += Transferred;
  //
  // If we managed to read some data, return success. If zero bytes were
  // transferred due to zero-sized buffer on input or due to EOF on first read,
  // return SUCCESS. Otherwise, return the error due to which zero bytes were
  // transferred.
  //
  return (Transferred > 0) ? EFI_SUCCESS : Status;
}

EFI_STATUS
EFIAPI
VirtioFsSimpleFileRead (
  IN     EFI_FILE_PROTOCOL *This,
  IN OUT UINTN             *BufferSize,
     OUT VOID              *Buffer
  )
{
  VIRTIO_FS_FILE *VirtioFsFile;
  EFI_STATUS     Status;

  VirtioFsFile = VIRTIO_FS_FILE_FROM_SIMPLE_FILE (This);

  if (VirtioFsFile->IsDirectory) {
    Status = ReadFileInfoCache (VirtioFsFile, BufferSize, Buffer);
  } else {
    Status = ReadRegularFile (VirtioFsFile, BufferSize, Buffer);
  }
  return Status;
}
