// Copyright 2017 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_MINFS_WRITEBACK_H_
#define SRC_STORAGE_MINFS_WRITEBACK_H_

#include <lib/zx/status.h>

#include <memory>
#include <utility>
#include <vector>

#include <fbl/ref_ptr.h>

#ifdef __Fuchsia__
#include <lib/fzl/owned-vmo-mapper.h>
#include <lib/zx/vmo.h>

#include <fbl/auto_lock.h>
#include <fbl/mutex.h>

#include "storage/operation/unbuffered_operations_builder.h"
#endif

#include <fbl/algorithm.h>
#include <fbl/intrusive_hash_table.h>
#include <fbl/intrusive_single_list.h>
#include <fbl/macros.h>

#include "src/lib/storage/vfs/cpp/queue.h"
#include "src/lib/storage/vfs/cpp/transaction/buffered_operations_builder.h"
#include "src/lib/storage/vfs/cpp/vfs.h"
#include "src/storage/minfs/allocator/allocator_reservation.h"
#include "src/storage/minfs/bcache.h"
#include "src/storage/minfs/cached_block_transaction.h"
#include "src/storage/minfs/format.h"
#include "src/storage/minfs/pending_work.h"

namespace minfs {

class DataAssignableVnode;
class InodeManager;
class TransactionalFs;
class VnodeMinfs;

// Tracks the current transaction, including any enqueued writes, and reserved blocks
// and inodes. Also handles allocation of previously reserved blocks/inodes.
// Upon construction, acquires a lock to ensure that all work being done within the
// scope of the transaction is thread-safe. Specifically, the Minfs superblock, block bitmap, and
// inode table, as well as the Vnode block count and inode size may in the near future be modified
// asynchronously. Since these modifications require a Transaction to be in progress, this lock
// will protect against multiple simultaneous writes to these structures.
class Transaction final : public PendingWork {
 public:
  static zx::status<std::unique_ptr<Transaction>> Create(TransactionalFs* minfs,
                                                         size_t reserve_inodes,
                                                         size_t reserve_blocks,
                                                         InodeManager* inode_manager);

  // Creates a Transaction object from CachedBlockTransaction. Consumes cached_transaction.
  static std::unique_ptr<Transaction> FromCachedBlockTransaction(
      TransactionalFs* minfs, std::unique_ptr<CachedBlockTransaction> cached_transaction);

  Transaction() = delete;

  explicit Transaction(TransactionalFs* minfs,
                       std::unique_ptr<CachedBlockTransaction> cached_transaction = nullptr);

  ~Transaction() final;

  AllocatorReservation& inode_reservation() { return inode_reservation_; }
  AllocatorReservation& block_reservation() { return *block_reservation_; }

  ////////////////
  // PendingWork interface.

  void EnqueueMetadata(storage::Operation operation, storage::BlockBuffer* buffer) final;
  void EnqueueData(storage::Operation operation, storage::BlockBuffer* buffer) final;

  size_t AllocateBlock() final { return block_reservation_->Allocate(); }

  void DeallocateBlock(size_t block) final { return block_reservation_->Deallocate(block); }

  ////////////////
  // Other methods.
  size_t AllocateInode() { return inode_reservation_.Allocate(); }

  void PinVnode(fbl::RefPtr<VnodeMinfs> vnode);

  // Extends block reservation by |reserve_blocks| number of blocks. It may fail
  // if the underlying allocator runs out of space.
  zx::status<> ExtendBlockReservation(size_t reserve_blocks);

#ifdef __Fuchsia__
  // Returns a vector of all enqueued metadata write operations.
  std::vector<storage::UnbufferedOperation> RemoveMetadataOperations() {
    return metadata_operations_.TakeOperations();
  }

  // Returns a vector of all enqueued data write operations.
  std::vector<storage::UnbufferedOperation> RemoveDataOperations() {
    return data_operations_.TakeOperations();
  }

  size_t SwapBlock(size_t old_bno) { return block_reservation_->Swap(old_bno); }

  std::vector<fbl::RefPtr<VnodeMinfs>> RemovePinnedVnodes();

  // Returns the block reservations within |transaction| and consumes |transaction|.
  // Asserts that there are no inode reservations.
  static std::unique_ptr<AllocatorReservation> TakeBlockReservations(
      std::unique_ptr<Transaction> transaction) {
    // When consuming transaction, we ignore any pending data and matadata operations
    // as they will be enqueued again.
    ZX_ASSERT(transaction->inode_reservation_.GetReserved() == 0);
    return (std::move(transaction->block_reservation_));
  }

#else
  std::vector<storage::BufferedOperation> TakeOperations() { return builder_.TakeOperations(); }
#endif

 private:
#ifdef __Fuchsia__
  fbl::AutoLock<fbl::Mutex> lock_;
  storage::UnbufferedOperationsBuilder metadata_operations_;
  storage::UnbufferedOperationsBuilder data_operations_;
  std::vector<fbl::RefPtr<VnodeMinfs>> pinned_vnodes_;
#else
  fs::BufferedOperationsBuilder builder_;
#endif

  AllocatorReservation inode_reservation_;
  std::unique_ptr<AllocatorReservation> block_reservation_;
};

}  // namespace minfs

#endif  // SRC_STORAGE_MINFS_WRITEBACK_H_
