// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_STORAGE_BLOBFS_TRANSFER_BUFFER_H_
#define SRC_STORAGE_BLOBFS_TRANSFER_BUFFER_H_

#ifndef __Fuchsia__
#error Fuchsia-only Header
#endif

#include <lib/zx/status.h>
#include <lib/zx/vmo.h>

#include <memory>

#include <fbl/macros.h>
#include <storage/buffer/owned_vmoid.h>

#include "src/storage/blobfs/blobfs_metrics.h"
#include "src/storage/blobfs/iterator/block_iterator_provider.h"
#include "src/storage/blobfs/loader_info.h"
#include "src/storage/blobfs/node_finder.h"
#include "src/storage/blobfs/transaction_manager.h"

namespace blobfs {

// The size of the transfer buffer for reading from storage.
//
// The decision to use a single global transfer buffer is arbitrary; a pool of them could also be
// available in the future for more fine-grained access. Moreover, the blobfs pager uses a single
// thread at the moment, so a global buffer should be sufficient.
//
// 256 MB; but the size is arbitrary, since pages will become decommitted as they are moved to
// destination VMOS.
constexpr uint64_t kTransferBufferSize = 256 * (1ull << 20);

// The size of the scratch buffer used for decompression.
//
// The decision to use a single global transfer buffer is arbitrary; a pool of them could also be
// available in the future for more fine-grained access. Moreover, the blobfs pager uses a single
// thread at the moment, so a global buffer should be sufficient.
//
// 256 MB; but the size is arbitrary, since pages will become decommitted as they are moved to
// destination VMOS.
constexpr uint64_t kDecompressionBufferSize = 256 * (1ull << 20);

// Make sure blocks are page-aligned.
static_assert(kBlobfsBlockSize % PAGE_SIZE == 0);

// Make sure the pager transfer buffer is block-aligned.
static_assert(kTransferBufferSize % kBlobfsBlockSize == 0);

// Make sure the decompression scratch buffer is block-aligned.
static_assert(kDecompressionBufferSize % kBlobfsBlockSize == 0);

// Make sure the pager transfer buffer and decompression buffer are sized per the worst case
// compression ratio of 1.
static_assert(kTransferBufferSize >= kDecompressionBufferSize);

// TransferBuffer is an interface representing a transfer buffer which can be loaded with data from
// the underlying storage device.
//
// The VMO returned by |TransferBuffer::vmo()| is guaranteed to never be mapped by the instance,
// which makes the VMO suitable for use with |zx_pager_supply_pages|.
class TransferBuffer {
 public:
  virtual ~TransferBuffer() = default;

  // Loads the buffer with data from the inode corresponding to |info.identifier|, at the byte range
  // specified by [|offset|, |offset| + |length|).
  // |offset| must be block aligned. |length| may be rounded up to a block-aligned offset.
  [[nodiscard]] virtual zx::status<> Populate(uint64_t offset, uint64_t length,
                                              const LoaderInfo& info) = 0;

  // Accesses the underlying VMO.
  // Must be preceded with a call to |TransferBuffer::Populate()|. The contents of the returned
  // VMO are only defined up to |length| bytes (the value passed to the last call to
  // |TransferBuffer::Populate()|).
  virtual const zx::vmo& GetVmo() const = 0;

  // Returns the size of the underlying VMO.
  virtual size_t GetSize() const = 0;
};

// StorageBackedTransferBuffer is an instance of |TransferBuffer| which can be loaded with data from
// the underlying storage device.
class StorageBackedTransferBuffer : public TransferBuffer {
 public:
  DISALLOW_COPY_ASSIGN_AND_MOVE(StorageBackedTransferBuffer);

  // Creates an instance of |StorageBackedTransferBuffer| with a VMO of size |size| bytes.
  // |size| must be a multiple of the block size of the underlying storage device.
  [[nodiscard]] static zx::status<std::unique_ptr<StorageBackedTransferBuffer>> Create(
      size_t size, TransactionManager* txn_manager, BlockIteratorProvider* block_iter_provider,
      BlobfsMetrics* metrics);

  [[nodiscard]] zx::status<> Populate(uint64_t offset, uint64_t length,
                                      const LoaderInfo& info) final;

  const zx::vmo& GetVmo() const final { return vmo_; }
  size_t GetSize() const final { return size_; }

 private:
  StorageBackedTransferBuffer(zx::vmo vmo, size_t size, storage::OwnedVmoid vmoid,
                              TransactionManager* txn_manager,
                              BlockIteratorProvider* block_iter_provider, BlobfsMetrics* metrics);

  TransactionManager* txn_manager_ = nullptr;
  BlockIteratorProvider* block_iter_provider_ = nullptr;

  zx::vmo vmo_;
  const size_t size_;
  storage::OwnedVmoid vmoid_;
  BlobfsMetrics* metrics_ = nullptr;
};

}  // namespace blobfs

#endif  // SRC_STORAGE_BLOBFS_TRANSFER_BUFFER_H_
