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

#include "src/lib/storage/vfs/cpp/paged_vnode.h"

#include <lib/async/task.h>

#include "src/lib/storage/vfs/cpp/paged_vfs.h"

namespace fs {

PagedVnode::PagedVnode(PagedVfs* vfs) : Vnode(vfs), clone_watcher_(this) {}

PagedVnode::~PagedVnode() {}

void PagedVnode::VmoDirty(uint64_t offset, uint64_t length) {
  ZX_ASSERT_MSG(false, "Filesystem does not support VmoDirty() (maybe read-only filesystem).");
}

zx::status<> PagedVnode::EnsureCreatePagedVmo(uint64_t size, uint32_t options) {
  if (paged_vmo())
    return zx::ok();

  if (!paged_vfs())
    return zx::error(ZX_ERR_BAD_STATE);  // Currently shutting down.

  auto info_or = paged_vfs()->CreatePagedNodeVmo(this, size, options);
  if (info_or.is_error())
    return info_or.take_error();
  paged_vmo_info_ = std::move(info_or).value();

  return zx::ok();
}

void PagedVnode::DidClonePagedVmo() {
  // Ensure that there is an owning reference to this vnode that goes along with the VMO clones.
  // This ensures that we can continue serving page requests even if all FIDL connections are
  // closed. This reference will be released when there are no more clones.
  if (!has_clones_reference_) {
    has_clones_reference_ = fbl::RefPtr<PagedVnode>(this);

    // Watch the VMO for the presence of no children. The VMO currently has no children because we
    // just created it, but the signal will be edge-triggered.
    WatchForZeroVmoClones();
  }
}

fbl::RefPtr<Vnode> PagedVnode::FreePagedVmo() {
  if (!paged_vmo_info_.vmo.is_valid())
    return nullptr;

  // Need to stop watching before deleting the VMO or there will be no handle to stop watching.
  StopWatchingForZeroVmoClones();

  if (paged_vfs() && paged_vmo())
    paged_vfs()->FreePagedVmo(std::move(paged_vmo_info_));

  // Reset to known-state after moving (or in case the paged_vfs was destroyed and we skipped
  // moving out of it).
  paged_vmo_info_.vmo = zx::vmo();
  paged_vmo_info_.id = 0;

  // This function must not free itself since the lock must be held to call it and the caller can't
  // release a deleted lock. The has_clones_reference_ may be the last thing keeping this class
  // alive so return it to allow the caller to release it properly.
  return std::move(has_clones_reference_);
}

void PagedVnode::OnNoPagedVmoClones() {
  ZX_DEBUG_ASSERT(!has_clones());

  // It is now save to release the VMO. Since we know there are no clones, we don't have to
  // call zx_pager_detach_vmo() to stop delivery of requests. And since there are no clones, the
  // has_clones_reference_ should also be null and there shouldn't be a reference to release
  // returned by FreePagedVmo(). If there is, deleting it here would cause "this" to be deleted
  // inside its own lock which will crash.
  fbl::RefPtr<fs::Vnode> pager_reference = FreePagedVmo();
  ZX_DEBUG_ASSERT(!pager_reference);
}

void PagedVnode::OnNoPagedVmoClonesMessage(async_dispatcher_t* dispatcher, async::WaitBase* wait,
                                           zx_status_t status, const zx_packet_signal_t* signal) {
  // The system will cancel our wait on teardown if we're still watching the vmo.
  if (status == ZX_ERR_CANCELED)
    return;

  // Our clone reference must be freed, but we need to do that outside of the lock.
  fbl::RefPtr<PagedVnode> clone_reference;

  {
    std::lock_guard lock(mutex_);

    ZX_DEBUG_ASSERT(has_clones());

    if (!paged_vfs())
      return;  // Called during tear-down.

    // The kernel signal delivery could have raced with us creating a new clone. Validate that there
    // are still no clones before tearing down.
    zx_info_vmo_t info;
    if (paged_vmo().get_info(ZX_INFO_VMO, &info, sizeof(info), nullptr, nullptr) != ZX_OK)
      return;  // Something wrong with the VMO, don't try to tear down.
    if (info.num_children > 0) {
      // Race with new VMO. Re-arm the clone watcher and continue as if the signal was not sent.
      WatchForZeroVmoClones();
      return;
    }

    // Move our reference for releasing outside of the lock. Clearing the member will also allow the
    // OnNoPagedVmoClones() observer to see "has_clones() == false" which is the new state.
    clone_reference = std::move(has_clones_reference_);

    StopWatchingForZeroVmoClones();
    OnNoPagedVmoClones();
  }

  // Release the reference to this class. This could be the last reference keeping it alive which
  // can cause it to be freed.
  clone_reference = nullptr;

  // THIS OBJECT IS NOW POSSIBLY DELETED.
}

void PagedVnode::WatchForZeroVmoClones() {
  clone_watcher_.set_object(paged_vmo().get());
  clone_watcher_.set_trigger(ZX_VMO_ZERO_CHILDREN);
  clone_watcher_.Begin(paged_vfs()->dispatcher());
}

void PagedVnode::StopWatchingForZeroVmoClones() {
  // This needs to tolerate calls where the cancel is unnecessary.
  if (clone_watcher_.is_pending())
    clone_watcher_.Cancel();
  clone_watcher_.set_object(ZX_HANDLE_INVALID);
}

}  // namespace fs
