// Copyright 2021 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.

// This file describes the in-memory structures which construct
// a F2FS filesystem.

#ifndef THIRD_PARTY_F2FS_BCACHE_H_
#define THIRD_PARTY_F2FS_BCACHE_H_

#include <errno.h>
#include <fuchsia/hardware/block/c/fidl.h>
#include <inttypes.h>
#include <lib/zx/vmo.h>

#include <atomic>
#include <shared_mutex>

#include <block-client/cpp/block-device.h>
#include <block-client/cpp/client.h>
#include <fbl/algorithm.h>
#include <fbl/array.h>
#include <fbl/macros.h>
#include <fbl/unique_fd.h>
#include <storage/buffer/vmo_buffer.h>
#include <storage/buffer/vmoid_registry.h>

#include "src/lib/storage/vfs/cpp/transaction/device_transaction_handler.h"

namespace f2fs {

#ifdef __Fuchsia__

// A helper function for converting "fd" to "BlockDevice".
zx_status_t FdToBlockDevice(fbl::unique_fd& fd, std::unique_ptr<block_client::BlockDevice>* out);

class Bcache : public fs::DeviceTransactionHandler, public storage::VmoidRegistry {
 public:
  // Not copyable or movable
  Bcache(const Bcache&) = delete;
  Bcache& operator=(const Bcache&) = delete;
  Bcache(Bcache&&) = delete;
  Bcache& operator=(Bcache&&) = delete;

  ~Bcache() = default;

  // Destroys a "bcache" object, but take back ownership of the underlying block device.
  static std::unique_ptr<block_client::BlockDevice> Destroy(std::unique_ptr<Bcache> bcache);

  ////////////////
  // fs::TransactionHandler interface.

  zx_status_t RunRequests(const std::vector<storage::BufferedOperation>& operations) override {
    std::shared_lock lock(mutex_);
    return DeviceTransactionHandler::RunRequests(operations);
  }

  uint64_t BlockNumberToDevice(uint64_t block_num) const final {
    return block_num * BlockSize() / info_.block_size;
  }

  block_client::BlockDevice* GetDevice() final { return device_; }

  uint32_t DeviceBlockSize() const;

  // Raw block read functions.
  // These do not track blocks (or attempt to access the block cache)
  // NOTE: Not marked as final, since these are overridden methods on host,
  // but not on __Fuchsia__.
  zx_status_t Readblk(block_t bno, void* data);
  zx_status_t Writeblk(block_t bno, const void* data);

  // TODO(rvargas): Move this to BlockDevice.
  // VmoidRegistry interface:
  zx_status_t BlockAttachVmo(const zx::vmo& vmo, storage::Vmoid* out) final;
  zx_status_t BlockDetachVmo(storage::Vmoid vmoid) final;

  ////////////////
  // Other methods.

  // This factory allows building this object from a BlockDevice. Bcache can take ownership of the
  // device (the first Create method), or not (the second Create method).
  static zx_status_t Create(std::unique_ptr<block_client::BlockDevice> device, uint32_t max_blocks,
                            std::unique_ptr<Bcache>* out);

  static zx_status_t Create(block_client::BlockDevice* device, uint32_t max_blocks,
                            std::unique_ptr<Bcache>* out);

  static zx_status_t Create(std::unique_ptr<block_client::BlockDevice> device, uint32_t max_blocks,
                            std::unique_ptr<Bcache>* out, uint32_t block_size);

  static zx_status_t Create(block_client::BlockDevice* device, uint32_t max_blocks,
                            std::unique_ptr<Bcache>* out, uint32_t block_size);

  // Returns the maximum number of available blocks,
  // assuming the filesystem is non-resizable.
  uint32_t Maxblk() const { return max_blocks_; }
  uint32_t BlockSize() const { return block_size_; }

  block_client::BlockDevice* device() { return device_; }
  const block_client::BlockDevice* device() const { return device_; }

  zx_status_t Sync();

  // Blocks all I/O operations to the underlying device (that go via the RunRequests method). This
  // does *not* block operations that go directly to the device.
  void Pause();

  // Resumes all I/O operations paused by the Pause method.
  void Resume();

 private:
  friend class BlockNode;

  Bcache(block_client::BlockDevice* device, uint32_t max_blocks, uint32_t block_size);

  // Used during initialization of this object.
  zx_status_t VerifyDeviceInfo();

  uint32_t max_blocks_;
  const uint32_t block_size_;
  fuchsia_hardware_block_BlockInfo info_ = {};
  std::unique_ptr<block_client::BlockDevice> owned_device_;  // The device, if owned.
  block_client::BlockDevice* device_;  // Pointer to the device, irrespective of ownership.
  // This buffer is used as internal scratch space for the "Readblk/Writeblk" methods.
  storage::VmoBuffer buffer_;
  std::shared_mutex mutex_;
};

#else  // __Fuchsia__

class Bcache : public fs::TransactionHandler {
 public:
  // Not copyable or movable
  Bcache(const Bcache&) = delete;
  Bcache& operator=(const Bcache&) = delete;
  Bcache(Bcache&&) = delete;
  Bcache& operator=(Bcache&&) = delete;

  ~Bcache() {}

  ////////////////
  // fs::TransactionHandler interface.

  uint64_t BlockNumberToDevice(uint64_t block_num) const final { return block_num; }

  zx_status_t RunRequests(const std::vector<storage::BufferedOperation>& operations) final;

  // Raw block read functions.
  // These do not track blocks (or attempt to access the block cache)
  // NOTE: Not marked as final, since these are overridden methods on host,
  // but not on __Fuchsia__.
  zx_status_t Readblk(block_t bno, void* data);
  zx_status_t Writeblk(block_t bno, const void* data);

  ////////////////
  // Other methods.

  static zx_status_t Create(fbl::unique_fd fd, uint32_t max_blocks, std::unique_ptr<Bcache>* out);

  // Returns the maximum number of available blocks,
  // assuming the filesystem is non-resizable.
  uint32_t Maxblk() const { return max_blocks_; }

  // Lengths of each extent (in bytes)
  fbl::Array<size_t> extent_lengths_;
  // Tell Bcache to look for Minfs partition starting at |offset| bytes
  zx_status_t SetOffset(off_t offset);
  // Tell the Bcache it is pointing at a sparse file
  // |offset| indicates where the minfs partition begins within the file
  // |extent_lengths| contains the length of each extent (in bytes)
  zx_status_t SetSparse(off_t offset, const fbl::Vector<size_t>& extent_lengths);

  int Sync();

 private:
  friend class BlockNode;

  Bcache(fbl::unique_fd fd, uint32_t max_blocks);

  const fbl::unique_fd fd_;
  uint32_t max_blocks_;
  off_t offset_ = 0;
};

#endif

}  // namespace f2fs

#endif  // THIRD_PARTY_F2FS_BCACHE_H_
