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

#include "ramdisk.h"

#include <inttypes.h>
#include <lib/fzl/owned-vmo-mapper.h>
#include <lib/zx/vmo.h>
#include <threads.h>
#include <zircon/assert.h>
#include <zircon/boot/image.h>
#include <zircon/device/block.h>
#include <zircon/types.h>

#include <atomic>
#include <limits>
#include <memory>
#include <random>

#include <ddk/driver.h>
#include <fbl/auto_lock.h>

#include "zircon/errors.h"

namespace ramdisk {
namespace {

using Transaction = block::BorrowedOperation<>;

constexpr uint64_t kMaxTransferSize = 1LLU << 19;

static std::atomic<uint64_t> g_ramdisk_count = 0;

}  // namespace

Ramdisk::Ramdisk(zx_device_t* parent, uint64_t block_size, uint64_t block_count,
                 const uint8_t* type_guid, fzl::ResizeableVmoMapper mapping)
    : RamdiskDeviceType(parent),
      block_size_(block_size),
      block_count_(block_count),
      mapping_(std::move(mapping)) {
  if (type_guid) {
    memcpy(type_guid_, type_guid, ZBI_PARTITION_GUID_LEN);
  } else {
    memset(type_guid_, 0, ZBI_PARTITION_GUID_LEN);
  }
  snprintf(name_, sizeof(name_), "ramdisk-%" PRIu64, g_ramdisk_count.fetch_add(1));
}

zx_status_t Ramdisk::Create(zx_device_t* parent, zx::vmo vmo, uint64_t block_size,
                            uint64_t block_count, const uint8_t* type_guid,
                            std::unique_ptr<Ramdisk>* out) {
  fzl::ResizeableVmoMapper mapping;
  zx_status_t status = mapping.Map(std::move(vmo), block_size * block_count);
  if (status != ZX_OK) {
    return status;
  }

  auto ramdev = std::unique_ptr<Ramdisk>(
      new Ramdisk(parent, block_size, block_count, type_guid, std::move(mapping)));
  if (thrd_create(&ramdev->worker_, WorkerThunk, ramdev.get()) != thrd_success) {
    return ZX_ERR_NO_MEMORY;
  }

  *out = std::move(ramdev);
  return ZX_OK;
}

zx_status_t Ramdisk::DdkGetProtocol(uint32_t proto_id, void* out_protocol) {
  auto* proto = static_cast<ddk::AnyProtocol*>(out_protocol);
  proto->ctx = this;
  switch (proto_id) {
    case ZX_PROTOCOL_BLOCK_IMPL: {
      proto->ops = &block_impl_protocol_ops_;
      return ZX_OK;
    }
    case ZX_PROTOCOL_BLOCK_PARTITION: {
      proto->ops = &block_partition_protocol_ops_;
      return ZX_OK;
    }
    default:
      return ZX_ERR_NOT_SUPPORTED;
  }
}

zx_off_t Ramdisk::DdkGetSize() { return block_size_ * block_count_; }

void Ramdisk::DdkUnbind(ddk::UnbindTxn txn) {
  {
    fbl::AutoLock lock(&lock_);
    dead_ = true;
  }
  sync_completion_signal(&signal_);
  txn.Reply();
}

zx_status_t Ramdisk::DdkMessage(fidl_incoming_msg_t* msg, fidl_txn_t* txn) {
  return fuchsia_hardware_ramdisk_Ramdisk_dispatch(this, txn, msg, Ops());
}

void Ramdisk::DdkRelease() {
  // Wake up the worker thread, in case it is sleeping
  sync_completion_signal(&signal_);

  thrd_join(worker_, nullptr);
  delete this;
}

void Ramdisk::BlockImplQuery(block_info_t* info, size_t* bopsz) {
  memset(info, 0, sizeof(*info));
  info->block_size = static_cast<uint32_t>(block_size_);
  info->block_count = block_count_;
  // Arbitrarily set, but matches the SATA driver for testing
  info->max_transfer_size = kMaxTransferSize;
  fbl::AutoLock lock(&lock_);
  info->flags = flags_;
  *bopsz = Transaction::OperationSize(sizeof(block_op_t));
}

void Ramdisk::BlockImplQueue(block_op_t* bop, block_impl_queue_callback completion_cb,
                             void* cookie) {
  Transaction txn(bop, completion_cb, cookie, sizeof(block_op_t));
  bool dead;
  bool read = false;

  switch ((txn.operation()->command &= BLOCK_OP_MASK)) {
    case BLOCK_OP_READ: {
      read = true;
      __FALLTHROUGH;
    }
    case BLOCK_OP_WRITE: {
      if ((txn.operation()->rw.offset_dev >= block_count_) ||
          ((block_count_ - txn.operation()->rw.offset_dev) < txn.operation()->rw.length)) {
        txn.Complete(ZX_ERR_OUT_OF_RANGE);
        return;
      }

      {
        fbl::AutoLock lock(&lock_);
        if (!(dead = dead_)) {
          if (!read) {
            block_counts_.received += txn.operation()->rw.length;
          }
          txn_list_.push(std::move(txn));
        }
      }

      if (dead) {
        txn.Complete(ZX_ERR_BAD_STATE);
      } else {
        sync_completion_signal(&signal_);
      }
      break;
    }
    case BLOCK_OP_FLUSH: {
      {
        fbl::AutoLock lock(&lock_);
        if (!(dead = dead_)) {
          txn_list_.push(std::move(txn));
        }
      }
      if (dead) {
        txn.Complete(ZX_ERR_BAD_STATE);
      } else {
        sync_completion_signal(&signal_);
      }
      break;
    }
    default: {
      txn.Complete(ZX_ERR_NOT_SUPPORTED);
      break;
    }
  }
}

zx_status_t Ramdisk::FidlSetFlags(uint32_t flags, fidl_txn_t* txn) {
  {
    fbl::AutoLock lock(&lock_);
    flags_ = flags;
  }
  return fuchsia_hardware_ramdisk_RamdiskSetFlags_reply(txn, ZX_OK);
}

zx_status_t Ramdisk::FidlWake(fidl_txn_t* txn) {
  {
    fbl::AutoLock lock(&lock_);

    if (flags_ & fuchsia_hardware_ramdisk_RAMDISK_FLAG_DISCARD_NOT_FLUSHED_ON_WAKE) {
      // Fill all blocks with a fill pattern.
      for (uint64_t block : blocks_written_since_last_flush_) {
        void* addr = reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(mapping_.start()) +
                                             block * block_size_);
        memset(addr, 0xaf, block_size_);
      }
      blocks_written_since_last_flush_.clear();
    }

    asleep_ = false;
    memset(&block_counts_, 0, sizeof(block_counts_));
    pre_sleep_write_block_count_ = 0;
    sync_completion_signal(&signal_);
  }
  return fuchsia_hardware_ramdisk_RamdiskWake_reply(txn, ZX_OK);
}

zx_status_t Ramdisk::FidlSleepAfter(uint64_t block_count, fidl_txn_t* txn) {
  {
    fbl::AutoLock lock(&lock_);
    asleep_ = false;
    memset(&block_counts_, 0, sizeof(block_counts_));
    pre_sleep_write_block_count_ = block_count;

    if (block_count == 0) {
      asleep_ = true;
    }
  }
  return fuchsia_hardware_ramdisk_RamdiskSleepAfter_reply(txn, ZX_OK);
}

zx_status_t Ramdisk::FidlGetBlockCounts(fidl_txn_t* txn) {
  fuchsia_hardware_ramdisk_BlockWriteCounts block_counts;
  {
    fbl::AutoLock lock(&lock_);
    memcpy(&block_counts, &block_counts_, sizeof(block_counts_));
  }
  return fuchsia_hardware_ramdisk_RamdiskGetBlockCounts_reply(txn, ZX_OK, &block_counts);
}

zx_status_t Ramdisk::BlockPartitionGetGuid(guidtype_t guid_type, guid_t* out_guid) {
  if (guid_type != GUIDTYPE_TYPE) {
    return ZX_ERR_NOT_SUPPORTED;
  }
  static_assert(ZBI_PARTITION_GUID_LEN == GUID_LENGTH, "GUID length mismatch");
  memcpy(out_guid, type_guid_, ZBI_PARTITION_GUID_LEN);
  return ZX_OK;
}

zx_status_t Ramdisk::BlockPartitionGetName(char* out_name, size_t capacity) {
  if (capacity < ZBI_PARTITION_NAME_LEN) {
    return ZX_ERR_BUFFER_TOO_SMALL;
  }
  static_assert(ZBI_PARTITION_NAME_LEN <= MAX_PARTITION_NAME_LENGTH, "Name length mismatch");
  strlcpy(out_name, name_, ZBI_PARTITION_NAME_LEN);
  return ZX_OK;
}

zx_status_t Ramdisk::FidlGrow(uint64_t required_size, fidl_txn_t* txn) {
  fbl::AutoLock lock(&lock_);
  if (required_size < block_size_ * block_count_) {
    return fuchsia_hardware_ramdisk_RamdiskGrow_reply(txn, ZX_ERR_INVALID_ARGS);
  }

  if (required_size % block_size_ != 0) {
    return fuchsia_hardware_ramdisk_RamdiskGrow_reply(txn, ZX_ERR_INVALID_ARGS);
  }
  zx_status_t status = mapping_.Grow(required_size);
  if (status != ZX_OK) {
    return fuchsia_hardware_ramdisk_RamdiskGrow_reply(txn, status);
  }

  block_count_ = required_size / block_size_;
  return fuchsia_hardware_ramdisk_RamdiskGrow_reply(txn, ZX_OK);
}

void Ramdisk::ProcessRequests() {
  block::BorrowedOperationQueue<> deferred_list;
  std::random_device random;
  std::uniform_int_distribution<bool> distribution;

  for (;;) {
    std::optional<Transaction> txn;
    bool defer;
    uint64_t block_write_limit;

    do {
      {
        fbl::AutoLock lock(&lock_);
        defer = (flags_ & fuchsia_hardware_ramdisk_RAMDISK_FLAG_RESUME_ON_WAKE) != 0;
        block_write_limit = pre_sleep_write_block_count_ == 0 && !asleep_
                                ? std::numeric_limits<uint64_t>::max()
                                : pre_sleep_write_block_count_;

        if (dead_) {
          while ((txn = deferred_list.pop())) {
            txn->Complete(ZX_ERR_BAD_STATE);
          }
          while ((txn = txn_list_.pop())) {
            txn->Complete(ZX_ERR_BAD_STATE);
          }
          return;
        }

        if (!asleep_) {
          // If we are awake, try grabbing pending transactions from the deferred list.
          txn = deferred_list.pop();
        }

        if (!txn) {
          // If no transactions were available in the deferred list (or we are asleep),
          // grab one from the regular txn_list.
          txn = txn_list_.pop();
        }
      }

      if (!txn) {
        sync_completion_wait(&signal_, ZX_TIME_INFINITE);
        sync_completion_reset(&signal_);
      }
    } while (!txn);

    if (txn->operation()->command == BLOCK_OP_FLUSH) {
      zx_status_t status = ZX_OK;
      if (block_write_limit == 0) {
        status = ZX_ERR_UNAVAILABLE;
      } else {
        fbl::AutoLock lock(&lock_);
        blocks_written_since_last_flush_.clear();
      }
      txn->Complete(status);
      continue;
    }

    uint32_t blocks = txn->operation()->rw.length;
    if (txn->operation()->command == BLOCK_OP_WRITE && blocks > block_write_limit) {
      // Limit the number of blocks we write.
      blocks = static_cast<uint32_t>(block_write_limit);
    }
    const uint64_t length = blocks * block_size_;
    const uint64_t dev_offset = txn->operation()->rw.offset_dev * block_size_;
    const uint64_t vmo_offset = txn->operation()->rw.offset_vmo * block_size_;
    void* addr =
        reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(mapping_.start()) + dev_offset);
    auto command = txn->operation()->command;

    zx_status_t status = ZX_OK;
    if (length > kMaxTransferSize) {
      status = ZX_ERR_OUT_OF_RANGE;
    } else if (command == BLOCK_OP_READ) {
      // A read operation should always succeed, even if the ramdisk is "asleep".
      status = zx_vmo_write(txn->operation()->rw.vmo, addr, vmo_offset, length);
    } else {  // BLOCK_OP_WRITE
      if (length > 0) {
        status = zx_vmo_read(txn->operation()->rw.vmo, addr, vmo_offset, length);
      }

      // Update the ramdisk block counts. Since we aren't failing read transactions, only include
      // write transaction counts.
      fbl::AutoLock lock(&lock_);
      // Increment the count based on the result of the last transaction.
      if (status == ZX_OK) {
        block_counts_.successful += blocks;

        // Put the ramdisk to sleep if we have reached the required # of blocks. It's possible that
        // an update to the sleep count arrived whilst we didn't hold the lock, so we check for that
        // here. If it has happened, then just don't count this transaction i.e. we pretend that it
        // completed before the update to the sleep count.
        if (pre_sleep_write_block_count_ == block_write_limit) {
          pre_sleep_write_block_count_ -= blocks;
          asleep_ = (pre_sleep_write_block_count_ == 0);

          if (flags_ & fuchsia_hardware_ramdisk_RAMDISK_FLAG_DISCARD_NOT_FLUSHED_ON_WAKE) {
            for (uint64_t block = txn->operation()->rw.offset_dev, count = blocks; count > 0;
                 ++block, --count) {
              if (!(flags_ & fuchsia_hardware_ramdisk_RAMDISK_FLAG_DISCARD_RANDOM) ||
                  distribution(random)) {
                blocks_written_since_last_flush_.push_back(block);
              }
            }
          }
        }

        if (blocks < txn->operation()->rw.length) {
          if (defer) {
            // If the first part of the transaction succeeded but the entire transaction is not
            // complete, we need to address the remainder.

            // If we are deferring after this block count, update the transaction to reflect the
            // blocks that have already been written, and add it to the deferred queue.
            txn->operation()->rw.length -= blocks;
            txn->operation()->rw.offset_vmo += blocks;
            txn->operation()->rw.offset_dev += blocks;

            // Add the remaining blocks to the deferred list.
            deferred_list.push(std::move(*txn));

            // Hold off on returning the result until the remainder of the transaction is completed.
            continue;
          } else {
            block_counts_.failed += txn->operation()->rw.length - blocks;
            status = ZX_ERR_UNAVAILABLE;
          }
        }
      } else {
        block_counts_.failed += txn->operation()->rw.length;
      }
    }

    txn->Complete(status);
  }
}

}  // namespace ramdisk
