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

#ifndef SRC_STORAGE_LIB_VFS_CPP_PAGED_VFS_H_
#define SRC_STORAGE_LIB_VFS_CPP_PAGED_VFS_H_

#include <lib/async/dispatcher.h>
#include <lib/zx/pager.h>
#include <lib/zx/result.h>
#include <lib/zx/thread.h>
#include <lib/zx/vmo.h>
#include <zircon/types.h>

#include <cstddef>
#include <cstdint>
#include <map>
#include <memory>
#include <vector>

#include "src/storage/lib/vfs/cpp/managed_vfs.h"
#include "src/storage/lib/vfs/cpp/pager_thread_pool.h"

namespace fs {

class PagedVnode;

// A variant of Vfs that supports paging. A PagedVfs supports PagedVnode objects.
class PagedVfs : public ManagedVfs {
 public:
  // The caller must call Init() which must succeed before using this class.
  explicit PagedVfs(async_dispatcher_t* dispatcher, int num_pager_threads = 1);
  ~PagedVfs() override;

  // Creates the pager and worker threads. If any of these fail, this class should not be used.
  // After calling Init, TearDown *must* be called before destroying.
  zx::result<> Init() __TA_EXCLUDES(vfs_lock_);
  bool is_initialized() const { return pager_.is_valid(); }

  // TearDown should be called before PagedVfs is destroyed. It can be called from the derived
  // classes's destructor, but it should be on the class that is marked as final.
  void TearDown();

  // Gets the list of pager threads. This is designed to allow callers to set up scheduling profiles
  // on their pagers.
  std::vector<zx::unowned_thread> GetPagerThreads() const;

  // Called in response to a successful PagedVnode::VmoRead() request, this supplies paged data from
  // aux_vmo to the PagedVnode's VMO to the kernel. See zx_pager_supply_pages() documentation for
  // more.
  zx::result<> SupplyPages(const zx::vmo& node_vmo, uint64_t offset, uint64_t length,
                           const zx::vmo& aux_vmo, uint64_t aux_offset) __TA_EXCLUDES(vfs_lock_);

  // Called in response to a successful PagedVnode::VmoDirty() request, this transits page state
  // from clean to dirty. See zx_pager_op_range() documentation for more.
  zx::result<> DirtyPages(const zx::vmo& node_vmo, uint64_t offset, uint64_t length)
      __TA_EXCLUDES(vfs_lock_);

  // Called in response to a failed PagedVnode::VmoRead() request, this reports that there was an
  // error populating page data. See zx_pager_op_range() documentation for more, only certain
  // values are permitted for err.
  zx::result<> ReportPagerError(const zx::vmo& node_vmo, uint64_t offset, uint64_t length,
                                zx_status_t err) __TA_EXCLUDES(vfs_lock_);

  // Notifies the kernel that the filesystem has started cleaning the `range` of pages. See
  // `ZX_PAGER_OP_WRITEBACK_BEGIN` for more information.
  zx::result<> WritebackBegin(const zx::vmo& node_vmo, uint64_t offset, uint64_t length)
      __TA_EXCLUDES(vfs_lock_);

  // Notifies the kernel that the filesystem has finished cleaning the `range` of pages. See
  // `ZX_PAGER_OP_WRITEBACK_END` for more information.
  zx::result<> WritebackEnd(const zx::vmo& node_vmo, uint64_t offset, uint64_t length)
      __TA_EXCLUDES(vfs_lock_);

  // Allocates a VMO of the given size associated with the given PagedVnode. VMOs for use with
  // the pager must be allocated by this method so the page requests are routed to the correct
  // PagedVnode.
  //
  // This will register the PagedVnode for pager requests. A non-owning reference will be taken to
  // it. The PagedVnode is responsible for notifying this class when it is destroyed via
  // FreePagedVmo() to free this reference.
  //
  // This function is for internal use by PagedVnode. Most callers should use
  // PagedVnode::EnsureCreateVmo().
  //
  // |options| must be zero or a combination of ZX_VMO_RESIZABLE and ZX_VMO_TRAP_DIRTY.
  struct VmoCreateInfo {
    zx::vmo vmo;

    // Unique identifier for the VMO that can be used in FreePagedVmo().
    uint64_t id = 0;
  };
  zx::result<VmoCreateInfo> CreatePagedNodeVmo(PagedVnode* node, uint64_t size,
                                               uint32_t options = 0) __TA_EXCLUDES(vfs_lock_);

  // When there is a VMO clone is alive, the PagedVnode should be registered with the VFS to handle
  // the paging requests for it.
  //
  // PagedVnodes should unregister themselves and properly detach from the pager when being freed or
  // when their VMO handle is destroyed to prevent leaks or use-after-free errors. Detaching from
  // the pager is important because otherwise pager requests from any code that has mappings will
  // hang indefinitely.
  //
  // The unique IDs are the ones generated by CreatePagedNodeVmo(). The vmo information should be
  // moved into this function, which will destroy the VMO handle after it's unregistered.
  void FreePagedVmo(VmoCreateInfo info) __TA_EXCLUDES(vfs_lock_);

  // Callback that the PagerThreadPool uses to notify us of pager events. These calls will get
  // issued on arbitrary threads.
  void PagerVmoRead(uint64_t node_id, uint64_t offset, uint64_t length) __TA_EXCLUDES(vfs_lock_)
      __TA_EXCLUDES(live_nodes_lock_);
  void PagerVmoDirty(uint64_t node_id, uint64_t offset, uint64_t length) __TA_EXCLUDES(vfs_lock_)
      __TA_EXCLUDES(live_nodes_lock_);

  // Returns the number of VMOs registered for notifications. Used for testing.
  size_t GetRegisteredPagedVmoCount() const __TA_EXCLUDES(vfs_lock_)
      __TA_EXCLUDES(live_nodes_lock_);

 protected:
  // Provides direct access to the underlying zx::pager. This is only exposed so clients can make
  // pager syscalls that haven't been stabilized yet.
  const zx::pager& pager_for_next_vdso_syscalls() const { return pager_; }

 private:
  std::unique_ptr<PagerThreadPool> pager_pool_;  // Threadsafe, does not need locking.
  zx::pager pager_;                              // Does not need locking.

  // Vnodes with active VMOs from the kernel paging system. These are non-owning references and
  // the PagedVnode class is responsible for notifying us when the reference is no longer valid.
  //
  // It is important for Vnodes to be registered here for as long as the VMO could possibly be used
  // to avoid accumulating bad state in the kernel. For example, if there are currently no mappings
  // one might think it would be safe to be unregistered. But if new mappings could possibly be
  // created in the future, it needs to stay continuously registered in case of race conditions.
  // See PagedVno::OnNoPagedVmoClones() for more.
  //
  // Protected by the registred vnode lock so creating nodes in the main lock doesn't attempt to
  // reenter the lock by registering.
  uint64_t next_node_id_ __TA_GUARDED(live_nodes_lock_) = 1;
  std::map<uint64_t, PagedVnode*> paged_nodes_ __TA_GUARDED(live_nodes_lock_);
};

}  // namespace fs

#endif  // SRC_STORAGE_LIB_VFS_CPP_PAGED_VFS_H_
