// Copyright 2016 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/storage/minfs/fsck.h"

#include <lib/cksum.h>
#include <lib/syslog/cpp/macros.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <iomanip>
#include <limits>
#include <map>
#include <memory>
#include <optional>
#include <utility>

#include <safemath/checked_math.h>

#include "src/storage/lib/vfs/cpp/journal/format.h"
#include "src/storage/minfs/format.h"
#include "zircon/errors.h"

#ifdef __Fuchsia__

#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>

#include <storage/buffer/owned_vmoid.h>

#include "src/storage/lib/block_client/cpp/reader.h"

#else

#include <storage/buffer/array_buffer.h>

#endif

#include "src/storage/minfs/runner.h"

namespace minfs {

namespace {

#ifdef __Fuchsia__
using RawBitmap = bitmap::RawBitmapGeneric<bitmap::VmoStorage>;
#else
using RawBitmap = bitmap::RawBitmapGeneric<bitmap::DefaultStorage>;
#endif

// The structure is initialized to an invalid state such that the block offset is the last block
// that an inode can address and that block is a double indirect block - this potentially cannot
// happen.
struct BlockInfo {
  ino_t owner = std::numeric_limits<ino_t>::max();   // Inode number that maps this block.
  blk_t offset = std::numeric_limits<blk_t>::max();  // Offset, in blocks, where this block is.
  BlockType type = BlockType::kDoubleIndirect;       // What is this block used as.
};

const std::string kBlockInfoDirectStr("direct");
const std::string kBlockInfoIndirectStr("indirect");
const std::string kBlockInfokDoubleIndirectStr("double indirect");

// Given a type of block, returns human readable c-string for the block type.
std::string BlockTypeToString(BlockType type) {
  switch (type) {
    case BlockType::kDirect:
      return kBlockInfoDirectStr;
    case BlockType::kIndirect:
      return kBlockInfoIndirectStr;
    case BlockType::kDoubleIndirect:
      return kBlockInfokDoubleIndirectStr;
    default:
      ZX_ASSERT(false);
  }
}

// Returns the logical block accessed from the "indirect" structure within an inode.
// |direct| refers to the index within the indirect block.
blk_t LogicalBlockIndirect(blk_t indirect, blk_t direct = 0) {
  ZX_DEBUG_ASSERT(indirect < kMinfsIndirect);
  ZX_DEBUG_ASSERT(direct < kMinfsDirectPerIndirect);
  const blk_t start = kMinfsDirect;
  return start + (indirect * kMinfsDirectPerIndirect) + direct;
}
// Returns the logical block accessed from the "doubly indirect" structure within an inode.
// |indirect| refers to an index within the doubly_indirect block.
// |direct| refers to an index within |indirect|.
blk_t LogicalBlockDoublyIndirect(blk_t doubly_indirect, blk_t indirect = 0, blk_t direct = 0) {
  ZX_DEBUG_ASSERT(doubly_indirect < kMinfsDoublyIndirect);
  ZX_DEBUG_ASSERT(indirect < kMinfsDirectPerIndirect);
  ZX_DEBUG_ASSERT(direct < kMinfsDirectPerIndirect);
  const blk_t start = kMinfsDirect + (kMinfsIndirect * kMinfsDirectPerIndirect);
  return start + (kMinfsDirectPerDindirect * doubly_indirect) +
         (indirect * kMinfsDirectPerIndirect) + direct;
}

class MinfsChecker {
 public:
  static zx::result<std::unique_ptr<MinfsChecker>> Create(FuchsiaDispatcher dispatcher,
                                                          std::unique_ptr<Bcache> bc,
                                                          const FsckOptions& options);

  static std::unique_ptr<Bcache> Destroy(std::unique_ptr<MinfsChecker> checker) {
    return Runner::Destroy(std::move(checker->runner_));
  }

  void CheckReserved();
  zx::result<> CheckInode(ino_t ino, ino_t parent, bool dot_or_dotdot);
  zx::result<> CheckUnlinkedInodes();
  zx::result<> CheckForUnusedBlocks() const;
  zx::result<> CheckForUnusedInodes() const;
  zx::result<> CheckLinkCounts() const;
  zx::result<> CheckAllocatedCounts() const;
  zx::result<> CheckSuperblockIntegrity() const;

  void DumpStats();

  bool conforming() const { return conforming_; }

 private:
  struct InodeNthBnoResult {
    blk_t bno = 0;
    blk_t next_n = false;
  };

  explicit MinfsChecker(std::unique_ptr<Runner> runner, const FsckOptions& fsck_options)
      : fsck_options_(fsck_options), runner_(std::move(runner)), fs_(runner_->minfs()) {}

  // Not copyable or movable
  MinfsChecker(const MinfsChecker&) = delete;
  MinfsChecker& operator=(const MinfsChecker&) = delete;
  MinfsChecker(MinfsChecker&&) = delete;
  MinfsChecker& operator=(MinfsChecker&&) = delete;

  // Reads the inode and optionally checks the magic value to ensure it is either a file or
  // directory.
  zx::result<Inode> GetInode(ino_t ino, bool check_magic = true) const;

  // Returns the nth block within an inode, relative to the start of the
  // file. Returns the
  //
  // Returns a pair of `next_n` and `bno`. `next_n` might contain a bno. This `next_n` is for
  // performance reasons -- it allows fsck to avoid repeatedly checking the same
  // indirect / doubly indirect blocks with all internal bno unallocated.
  zx::result<InodeNthBnoResult> GetInodeNthBno(Inode* inode, blk_t n);
  zx::result<> CheckDirectory(Inode* inode, ino_t ino, ino_t parent, uint32_t flags);
  std::optional<std::string> CheckDataBlock(blk_t bno, BlockInfo block_info);
  zx::result<> CheckFile(Inode* inode, ino_t ino);
  // Checks just one inode without recursing.  inode_stack_ will contain any child inodes (if the
  // inode happens to be a directory).
  zx::result<> CheckOneInode(ino_t ino, ino_t parent, bool dot_or_dotdot);

  const FsckOptions fsck_options_;

  // "Set once"-style flag to identify if anything nonconforming
  // was found in the underlying filesystem -- even if it was fixed.
  bool conforming_ = true;

  std::unique_ptr<Runner> runner_;
  Minfs& fs_;
  RawBitmap checked_inodes_;
  RawBitmap checked_blocks_;
  ino_t max_inode_ = 0;

  // blk_info_ provides reverse lookup capability - a block number is mapped to
  // a set of BlockInfo. The filesystem is inconsistent if a block has more than
  // one <inode, offset, type>.
  std::map<blk_t, std::vector<BlockInfo>> blk_info_;

  uint32_t alloc_inodes_ = 0;
  uint32_t alloc_blocks_ = 0;
  fbl::Array<int64_t> links_;

  blk_t cached_doubly_indirect_;
  blk_t cached_indirect_;
  uint8_t doubly_indirect_cache_[kMinfsBlockSize];
  uint8_t indirect_cache_[kMinfsBlockSize];
  uint32_t indirect_blocks_ = 0;
  uint32_t directory_blocks_ = 0;

  // A stack of inodes to check.
  std::vector<std::tuple</*ino=*/ino_t, /*parent=*/ino_t, /*dot_or_dotdot=*/bool>> inode_stack_;
};

zx::result<Inode> MinfsChecker::GetInode(ino_t ino, bool check_magic) const {
  if (ino >= fs_.Info().inode_count) {
    FX_LOGS(ERROR) << "check: ino " << ino << " out of range (>=" << fs_.Info().inode_count << ")";
    return zx::error(ZX_ERR_OUT_OF_RANGE);
  }

  Inode inode;
  fs_.GetInodeManager()->Load(ino, &inode);
  if (check_magic && (inode.magic != kMinfsMagicFile) && (inode.magic != kMinfsMagicDir)) {
    FX_LOGS(ERROR) << "check: ino " << ino << " has bad magic 0x" << std::hex << inode.magic;
    return zx::error(ZX_ERR_IO_DATA_INTEGRITY);
  }
  return zx::ok(inode);
}

#define CD_DUMP 1
#define CD_RECURSE 2

zx::result<MinfsChecker::InodeNthBnoResult> MinfsChecker::GetInodeNthBno(Inode* inode, blk_t n) {
  InodeNthBnoResult result{
      .bno{},
      // The default value for the "next n". It's easier to set it here anyway,
      // since we proceed to modify n in the code below.
      .next_n = n + 1,
  };

  if (n < kMinfsDirect) {
    result.bno = inode->dnum[n];
    return zx::ok(result);
  }

  n -= kMinfsDirect;
  uint32_t i = n / kMinfsDirectPerIndirect;  // indirect index
  uint32_t j = n % kMinfsDirectPerIndirect;  // direct index

  if (i < kMinfsIndirect) {
    blk_t ibno;
    if ((ibno = inode->inum[i]) == 0) {
      result.bno = 0;
      result.next_n = kMinfsDirect + (i + 1) * kMinfsDirectPerIndirect;
      return zx::ok(result);
    }

    if (cached_indirect_ != ibno) {
      if (auto status = fs_.ReadDat(ibno, indirect_cache_); status.is_error()) {
        return status.take_error();
      }
      cached_indirect_ = ibno;
    }

    uint32_t* ientry = reinterpret_cast<uint32_t*>(indirect_cache_);
    result.bno = ientry[j];
    return zx::ok(result);
  }

  n -= kMinfsIndirect * kMinfsDirectPerIndirect;
  i = n / (kMinfsDirectPerDindirect);  // doubly indirect index
  n -= (i * kMinfsDirectPerDindirect);
  j = n / kMinfsDirectPerIndirect;           // indirect index
  uint32_t k = n % kMinfsDirectPerIndirect;  // direct index

  if (i < kMinfsDoublyIndirect) {
    blk_t dibno;
    if ((dibno = inode->dinum[i]) == 0) {
      result.bno = 0;
      result.next_n = kMinfsDirect + kMinfsIndirect * kMinfsDirectPerIndirect +
                      (i + 1) * kMinfsDirectPerDindirect;
      return zx::ok(result);
    }

    if (cached_doubly_indirect_ != dibno) {
      if (auto status = fs_.ReadDat(dibno, doubly_indirect_cache_); status.is_error()) {
        return status.take_error();
      }
      cached_doubly_indirect_ = dibno;
    }

    uint32_t* dientry = reinterpret_cast<uint32_t*>(doubly_indirect_cache_);
    blk_t ibno;
    if ((ibno = dientry[j]) == 0) {
      result.bno = 0;
      result.next_n = kMinfsDirect + kMinfsIndirect * kMinfsDirectPerIndirect +
                      (i * kMinfsDirectPerDindirect) + (j + 1) * kMinfsDirectPerIndirect;
      return zx::ok(result);
    }

    if (cached_indirect_ != ibno) {
      if (auto status = fs_.ReadDat(ibno, indirect_cache_); status.is_error()) {
        return status.take_error();
      }
      cached_indirect_ = ibno;
    }

    uint32_t* ientry = reinterpret_cast<uint32_t*>(indirect_cache_);
    result.bno = ientry[k];
    return zx::ok(result);
  }

  return zx::error(ZX_ERR_OUT_OF_RANGE);
}

zx::result<> MinfsChecker::CheckDirectory(Inode* inode, ino_t ino, ino_t parent, uint32_t flags) {
  unsigned eno = 0;
  bool dot = false;
  bool dotdot = false;
  uint32_t dirent_count = 0;

  zx::result<> status;
  fbl::RefPtr<VnodeMinfs> vn;
  VnodeMinfs::Recreate(&fs_, ino, &vn);

  size_t off = 0;
  bool is_last = false;
  auto dirent_buffer = std::make_unique<DirentBuffer<kMinfsMaxDirentSize>>();
  Dirent* de = &dirent_buffer->dirent;
  do {
    size_t actual;
    status = vn->ReadInternal(nullptr, de, kMinfsDirentSize, off, &actual);
    if (status.is_ok() && actual == 0 && inode->link_count == 0 && parent == 0) {
      // This is OK as it's an unlinked directory.
      break;
    }
    if (status.is_error() || actual != kMinfsDirentSize) {
      FX_LOGS(ERROR) << "check: ino#" << eno << ": Could not read de[" << ino << "] at " << off;
      if (inode->dirent_count >= 2 && inode->dirent_count == eno - 1) {
        // So we couldn't read the last direntry, for whatever reason, but our
        // inode says that we shouldn't have been able to read it anyway.
        FX_LOGS(ERROR) << "check: de count (" << eno << ") > inode_dirent_count ("
                       << inode->dirent_count << ")";
      }
      return status.is_error() ? status.take_error() : zx::error(ZX_ERR_IO);
    }

    const uint32_t rlen = static_cast<uint32_t>(DirentReservedSize(de, off));
    const uint32_t dlen = DirentSize(de->namelen);
    is_last = de->reclen & kMinfsReclenLast;
    if (!is_last && ((rlen < kMinfsDirentSize) || (dlen > rlen) || (dlen > kMinfsMaxDirentSize) ||
                     (rlen & kMinfsDirentAlignmentMask))) {
      FX_LOGS(ERROR) << "check: ino#" << ino << ": de[" << eno << "]: bad dirent reclen (" << rlen
                     << ") dlen(" << dlen << "), maxsize(" << kMinfsMaxDirentSize << "), size("
                     << kMinfsDirentSize << ")";
      return zx::error(ZX_ERR_IO_DATA_INTEGRITY);
    }
    if (de->ino == 0) {
      if (flags & CD_DUMP) {
        FX_LOGS(DEBUG) << "ino#" << ino << ": de[" << eno << "]: <empty> reclen=" << rlen;
      }
    } else {
      // Re-read the dirent to acquire the full name
      status = vn->ReadInternal(nullptr, de, dlen, off, &actual);
      if (status.is_error() || actual != dlen) {
        FX_LOGS(ERROR) << "check: Error reading dirent of size: " << dlen;
        return zx::error(ZX_ERR_IO);
      }
      bool dot_or_dotdot = false;
      if ((de->namelen == 0) || (de->namelen > (rlen - kMinfsDirentSize))) {
        FX_LOGS(ERROR) << "check: ino#" << ino << ": de[" << eno << "]: invalid namelen "
                       << de->namelen;
        return zx::error(ZX_ERR_IO_DATA_INTEGRITY);
      }
      if ((de->namelen == 1) && (de->name[0] == '.')) {
        if (dot) {
          FX_LOGS(ERROR) << "check: ino#" << ino << ": multiple '.' entries";
          conforming_ = false;
        }
        dot_or_dotdot = true;
        dot = true;
        if (de->ino != ino) {
          FX_LOGS(ERROR) << "check: ino#" << ino << ": de[" << eno << "]: '.' ino=" << de->ino
                         << " (not self!)";
          conforming_ = false;
        }
      }
      if ((de->namelen == 2) && (de->name[0] == '.') && (de->name[1] == '.')) {
        if (dotdot) {
          FX_LOGS(ERROR) << "check: ino#" << ino << ": multiple '..' entries";
          conforming_ = false;
        }
        dot_or_dotdot = true;
        dotdot = true;
        if (de->ino != parent) {
          FX_LOGS(ERROR) << "check: ino#" << ino << ": de[" << eno << "]: '..' ino=" << de->ino
                         << " (not parent (ino#" << parent << ")!)";
          conforming_ = false;
        }
      }
      if (flags & CD_DUMP) {
        FX_LOGS(DEBUG) << "ino#" << ino << ": de[" << eno << "]: ino=" << de->ino
                       << " type=" << de->type << " '" << std::string_view(de->name, de->namelen)
                       << "' " << (is_last ? "[last]" : "");
      }
      if (flags & CD_RECURSE) {
        inode_stack_.push_back(std::make_tuple(de->ino, ino, dot_or_dotdot));
      }
      dirent_count++;
    }
    off += rlen;
    eno++;
  } while (!is_last);
  if (inode->link_count == 0 && inode->dirent_count != 0) {
    FX_LOGS(ERROR) << "check: dirent_count (" << inode->dirent_count
                   << ") for unlinked directory != 0";
    conforming_ = false;
  }
  if (dirent_count != inode->dirent_count) {
    FX_LOGS(ERROR) << "check: ino#" << ino << ": dirent_count of " << inode->dirent_count
                   << " != " << dirent_count << " (actual)";
    conforming_ = false;
  }
  if (dot == false && inode->link_count > 0) {
    FX_LOGS(ERROR) << "check: ino#" << ino << ": directory missing '.'";
    conforming_ = false;
  }
  if (dotdot == false && inode->link_count > 0) {
    FX_LOGS(ERROR) << "check: ino#" << ino << ": directory missing '..'";
    conforming_ = false;
  }
  return zx::ok();
}

std::optional<std::string> MinfsChecker::CheckDataBlock(blk_t bno, BlockInfo block_info) {
  if (bno == 0) {
    return std::string("reserved bno");
  }
  if (bno >= fs_.Info().block_count) {
    return std::string("out of range");
  }
  if (!fs_.GetBlockAllocator().CheckAllocated(bno)) {
    return std::string("not allocated");
  }
  if (checked_blocks_.Get(bno, bno + 1)) {
    auto entries = blk_info_[bno].size();
    // The entries are printed as
    // "double-allocated"
    // "  <ino: 4294967295, off: 4294967295 type: DI>\n"
    std::string str("double-allocated\n");
    for (size_t i = 0; i < entries; i++) {
      str.append("  <ino: " + std::to_string(blk_info_[bno][i].owner) +
                 ", off: " + std::to_string(blk_info_[bno][i].offset) +
                 " type: " + BlockTypeToString(blk_info_[bno][i].type) + ">\n");
    }
    blk_info_[bno].push_back(block_info);
    return str;
  }
  checked_blocks_.Set(bno, bno + 1);
  std::vector<BlockInfo> vec;
  vec.push_back(block_info);
  blk_info_.insert(std::pair<blk_t, std::vector<BlockInfo>>(bno, vec));
  alloc_blocks_++;
  if (block_info.type != BlockType::kDirect) {
    ++indirect_blocks_;
  }
  return std::nullopt;
}

zx::result<> MinfsChecker::CheckFile(Inode* inode, ino_t ino) {
  FX_LOGS(DEBUG) << "Direct blocks: ";
  for (const blk_t& dnum : inode->dnum) {
    FX_LOGS(DEBUG) << " " << dnum << ",";
  }
  FX_LOGS(DEBUG) << " ...";

  uint32_t block_count = 0;

  // count and sanity-check indirect blocks
  for (unsigned n = 0; n < kMinfsIndirect; n++) {
    if (inode->inum[n]) {
      BlockInfo block_info = {ino, LogicalBlockIndirect(n), BlockType::kIndirect};
      auto msg = CheckDataBlock(inode->inum[n], block_info);
      if (msg) {
        FX_LOGS(WARNING) << "check: ino#" << ino << ": indirect block " << n << "(@"
                         << inode->inum[n] << "): " << msg.value();
        conforming_ = false;
      }
      block_count++;
    }
  }

  // count and sanity-check doubly indirect blocks
  for (unsigned n = 0; n < kMinfsDoublyIndirect; n++) {
    if (inode->dinum[n]) {
      BlockInfo block_info = {ino, LogicalBlockDoublyIndirect(n), BlockType::kDoubleIndirect};
      auto msg = CheckDataBlock(inode->dinum[n], block_info);
      if (msg) {
        FX_LOGS(WARNING) << "check: ino#" << ino << ": doubly indirect block " << n << "(@"
                         << inode->dinum[n] << "): " << msg.value();
        conforming_ = false;
      }
      block_count++;

      char data[kMinfsBlockSize];
      if (auto status = fs_.ReadDat(inode->dinum[n], data); status.is_error()) {
        return status.take_error();
      }
      uint32_t* entry = reinterpret_cast<uint32_t*>(data);

      for (unsigned m = 0; m < kMinfsDirectPerIndirect; m++) {
        if (entry[m]) {
          BlockInfo block_info = {ino, LogicalBlockDoublyIndirect(n, m), BlockType::kIndirect};
          msg = CheckDataBlock(entry[m], block_info);
          if (msg) {
            FX_LOGS(WARNING) << "check: ino#" << ino << ": indirect block (in dind) " << m << "(@"
                             << entry[m] << "): " << msg.value();
            conforming_ = false;
          }
          block_count++;
        }
      }
    }
  }

  // count and sanity-check data blocks

  // The next block which would be allocated if we expand the file size
  // by a single block.
  unsigned next_blk = 0;
  cached_doubly_indirect_ = 0;
  cached_indirect_ = 0;

  blk_t n = 0;
  while (true) {
    auto nth_bno_or = GetInodeNthBno(inode, n);
    if (nth_bno_or.is_error()) {
      if (nth_bno_or.error_value() == ZX_ERR_OUT_OF_RANGE) {
        break;
      } else {
        return nth_bno_or.take_error();
      }
    }

    assert(nth_bno_or->next_n > n);
    if (nth_bno_or->bno) {
      next_blk = n + 1;
      block_count++;
      BlockInfo block_info = {ino, n, BlockType::kDirect};
      auto msg = CheckDataBlock(nth_bno_or->bno, block_info);
      if (msg) {
        FX_LOGS(WARNING) << "check: ino#" << ino << ": block " << n << "(@" << nth_bno_or->bno
                         << "): " << msg.value();
        conforming_ = false;
      }
    }
    n = nth_bno_or->next_n;
  }
  if (next_blk) {
    unsigned max_blocks = fbl::round_up(inode->size, kMinfsBlockSize) / kMinfsBlockSize;
    if (next_blk > max_blocks) {
      FX_LOGS(WARNING) << "check: ino#" << ino << ": filesize too small";
      conforming_ = false;
    }
  }
  if (block_count != inode->block_count) {
    FX_LOGS(WARNING) << "check: ino#" << ino << ": block count " << inode->block_count
                     << ", actual blocks " << block_count;
    conforming_ = false;
  }
  return zx::ok();
}

void MinfsChecker::CheckReserved() {
  // Check reserved inode '0'.
  if (fs_.GetInodeManager()->GetInodeAllocator()->CheckAllocated(0)) {
    ZX_ASSERT(!checked_inodes_.Get(0, 1));
    checked_inodes_.Set(0, 1);
    alloc_inodes_++;
  } else {
    FX_LOGS(WARNING) << "check: reserved inode#0: not marked in-use";
    conforming_ = false;
  }

  // Check reserved data block '0'.
  if (fs_.GetBlockAllocator().CheckAllocated(0)) {
    checked_blocks_.Set(0, 1);
    alloc_blocks_++;
  } else {
    FX_LOGS(WARNING) << "check: reserved block#0: not marked in-use";
    conforming_ = false;
  }
}

zx::result<> MinfsChecker::CheckInode(ino_t ino, ino_t parent, bool dot_or_dotdot) {
  for (;;) {
    if (zx::result result = CheckOneInode(ino, parent, dot_or_dotdot); result.is_error())
      return result.take_error();

    if (inode_stack_.empty())
      return zx::ok();

    auto [next_ino, next_parent, next_dot_or_dotdot] = inode_stack_.back();
    inode_stack_.pop_back();
    ino = next_ino;
    parent = next_parent;
    dot_or_dotdot = next_dot_or_dotdot;
  }
}

zx::result<> MinfsChecker::CheckOneInode(ino_t ino, ino_t parent, bool dot_or_dotdot) {
  auto inode_or = GetInode(ino);
  if (inode_or.is_error()) {
    FX_LOGS(ERROR) << "check: ino#" << ino << ": not readable: " << inode_or.error_value();
    return inode_or.take_error();
  }

  Inode inode = std::move(inode_or.value());

  bool prev_checked = checked_inodes_.Get(ino, ino + 1);

  if (inode.magic == kMinfsMagicDir && prev_checked && !dot_or_dotdot) {
    FX_LOGS(ERROR) << "check: ino#" << ino
                   << ": Multiple hard links to directory (excluding '.' and '..') found";
    return zx::error(ZX_ERR_BAD_STATE);
  }

  if (!safemath::CheckAdd(links_[ino - 1], 1).AssignIfValid(&links_[ino - 1])) {
    FX_LOGS(ERROR) << "Ino " << ino << " overflowed int64_t.";
    return zx::error(ZX_ERR_OUT_OF_RANGE);
  }

  if (prev_checked) {
    // we've been here before
    return zx::ok();
  }

  if (!safemath::CheckSub(links_[ino - 1], inode.link_count).AssignIfValid(&links_[ino - 1])) {
    FX_LOGS(ERROR) << "Ino " << ino << " underflowed int64_t.";
    return zx::error(ZX_ERR_OUT_OF_RANGE);
  }
  checked_inodes_.Set(ino, ino + 1);
  max_inode_ = std::max(ino, max_inode_);
  alloc_inodes_++;

  if (!fs_.GetInodeManager()->GetInodeAllocator()->CheckAllocated(ino)) {
    FX_LOGS(WARNING) << "check: ino#" << ino << ": not marked in-use";
    conforming_ = false;
  }

  if (inode.magic == kMinfsMagicDir) {
    FX_LOGS(DEBUG) << "ino#" << ino << ": DIR blks=" << inode.block_count
                   << " links=" << inode.link_count;
    if (auto status = CheckFile(&inode, ino); status.is_error()) {
      return status.take_error();
    }
    if (auto status = CheckDirectory(&inode, ino, parent, CD_DUMP); status.is_error()) {
      return status.take_error();
    }
    if (auto status = CheckDirectory(&inode, ino, parent, CD_RECURSE); status.is_error()) {
      return status.take_error();
    }
    directory_blocks_ += inode.block_count;
  } else {
    if (ino == kMinfsRootIno) {
      FX_LOGS(ERROR) << "Root inode must be a directory";
      return zx::error(ZX_ERR_BAD_STATE);
    }
    FX_LOGS(DEBUG) << "ino#" << ino << ": FILE blks=" << inode.block_count
                   << " links=" << inode.link_count << " size=" << inode.size;
    if (auto status = CheckFile(&inode, ino); status.is_error()) {
      return status.take_error();
    }
  }
  return zx::ok();
}

zx::result<> MinfsChecker::CheckUnlinkedInodes() {
  ino_t last_ino = 0;
  ino_t next_ino = fs_.Info().unlinked_head;
  ino_t unlinked_count = 0;

  while (next_ino != 0) {
    unlinked_count++;

    auto inode_or = GetInode(next_ino);
    if (inode_or.is_error()) {
      FX_LOGS(ERROR) << "check: ino#" << next_ino << ": not readable: " << inode_or.error_value();
      return inode_or.take_error();
    }

    Inode inode = std::move(inode_or.value());

    if (inode.link_count > 0) {
      FX_LOGS(ERROR) << "check: ino#" << next_ino << ": should have 0 links";
      return zx::error(ZX_ERR_BAD_STATE);
    }

    if (inode.last_inode != last_ino) {
      FX_LOGS(ERROR) << "check: ino#" << next_ino << ": incorrect last unlinked inode";
      return zx::error(ZX_ERR_BAD_STATE);
    }

    links_[next_ino - 1] = -1;

    if (auto status = CheckInode(next_ino, 0, 0); status.is_error()) {
      FX_LOGS(ERROR) << "minfs_check: CheckInode failure: " << status.error_value();
      return status.take_error();
    }

    last_ino = next_ino;
    next_ino = inode.next_inode;
  }

  if (fs_.Info().unlinked_tail != last_ino) {
    FX_LOGS(ERROR) << "minfs_check: Incorrect unlinked tail: " << fs_.Info().unlinked_tail;
    return zx::error(ZX_ERR_BAD_STATE);
  }

  if (unlinked_count > 0 && !fsck_options_.quiet) {
    FX_LOGS(WARNING) << "minfs_check: Warning: " << unlinked_count << " unlinked inodes found";
  }

  return zx::ok();
}

zx::result<> MinfsChecker::CheckForUnusedBlocks() const {
  unsigned missing = 0;

  for (unsigned n = 0; n < fs_.Info().block_count; n++) {
    if (fs_.GetBlockAllocator().CheckAllocated(n)) {
      if (!checked_blocks_.Get(n, n + 1)) {
        missing++;
      }
    }
  }
  if (missing > 0) {
    FX_LOGS(ERROR) << "check: " << missing << " allocated block" << (missing > 1 ? "s" : "")
                   << " not in use";
    return zx::error(ZX_ERR_BAD_STATE);
  }
  return zx::ok();
}

zx::result<> MinfsChecker::CheckForUnusedInodes() const {
  unsigned missing = 0;
  for (unsigned n = 0; n < fs_.Info().inode_count; n++) {
    if (fs_.GetInodeManager()->GetInodeAllocator()->CheckAllocated(n)) {
      if (!checked_inodes_.Get(n, n + 1)) {
        missing++;
      }
    }
  }
  // Minfs behaviour was changed in revision 1 so that purged inodes have their magic field changed
  // to kMinfsMagicPurged. Prior to this, the inodes were left intact.
  if (missing > 0) {
    FX_LOGS(ERROR) << "check: " << missing << " allocated inode" << (missing > 1 ? "s" : "")
                   << " not in use";
    return zx::error(ZX_ERR_BAD_STATE);
  }
  return zx::ok();
}

zx::result<> MinfsChecker::CheckLinkCounts() const {
  unsigned error = 0;
  for (uint32_t n = 0; n < fs_.Info().inode_count; n++) {
    if (links_[n] != 0) {
      error += 1;
      FX_LOGS(ERROR) << "check: inode#" << n + 1 << " has incorrect link count " << links_[n];
      return zx::error(ZX_ERR_BAD_STATE);
    }
  }
  if (error) {
    FX_LOGS(ERROR) << "check: " << error << " inode" << (error > 1 ? "s" : "")
                   << " with incorrect link count";
    return zx::error(ZX_ERR_BAD_STATE);
  }
  return zx::ok();
}

zx::result<> MinfsChecker::CheckAllocatedCounts() const {
  zx::result<> status = zx::ok();
  if (alloc_blocks_ != fs_.Info().alloc_block_count) {
    FX_LOGS(ERROR) << "check: incorrect allocated block count " << fs_.Info().alloc_block_count
                   << " (should be " << alloc_blocks_ << ")";
    status = zx::error(ZX_ERR_BAD_STATE);
  }

  if (alloc_inodes_ != fs_.Info().alloc_inode_count) {
    FX_LOGS(ERROR) << "check: incorrect allocated inode count " << fs_.Info().alloc_inode_count
                   << " (should be " << alloc_inodes_ << ")";
    status = zx::error(ZX_ERR_BAD_STATE);
  }

  return status;
}

zx::result<> MinfsChecker::CheckSuperblockIntegrity() const {
  char data[kMinfsBlockSize];
  blk_t journal_block;

#ifdef __Fuchsia__
  journal_block = static_cast<blk_t>(JournalStartBlock(fs_.Info()));
#else
  journal_block = fs_.GetBlockOffsets().JournalStartBlock();
#endif

  if (fs_.bc_->Readblk(journal_block, data).is_error()) {
    FX_LOGS(ERROR) << "could not read journal block";
    return zx::error(ZX_ERR_IO);
  }

  // Check that the journal superblock is valid.
  fs::JournalInfo* journal_info = reinterpret_cast<fs::JournalInfo*>(data);
  if (journal_info->magic != fs::kJournalMagic) {
    FX_LOGS(ERROR) << "invalid journal magic";
    return zx::error(ZX_ERR_BAD_STATE);
  }

  uint32_t old_checksum = journal_info->checksum;
  journal_info->checksum = 0;
  journal_info->checksum = crc32(0, reinterpret_cast<uint8_t*>(data), sizeof(fs::JournalInfo));
  if (journal_info->checksum != old_checksum) {
    FX_LOGS(ERROR) << "invalid journal checksum: actual = " << old_checksum
                   << ", expected = " << journal_info->checksum;
    return zx::error(ZX_ERR_BAD_STATE);
  }

  // Check that the backup superblock is valid.
  blk_t backup_location;
  if ((fs_.Info().flags & kMinfsFlagFVM) == 0) {
    backup_location = kNonFvmSuperblockBackup;
  } else {
#ifdef __Fuchsia__
    backup_location = kFvmSuperblockBackup;
#else
    backup_location = fs_.GetBlockOffsets().IntegrityStartBlock();
#endif
  }

  if (fs_.bc_->Readblk(backup_location, data).is_error()) {
    FX_LOGS(ERROR) << "could not read backup superblock";
    return zx::error(ZX_ERR_IO);
  }

  Superblock* backup_info = reinterpret_cast<Superblock*>(data);
#ifdef __Fuchsia__
  return CheckSuperblock(*backup_info, fs_.bc_->device(), fs_.bc_->Maxblk());
#else
  return CheckSuperblock(*backup_info, fs_.bc_->Maxblk());
#endif
}

zx::result<std::unique_ptr<MinfsChecker>> MinfsChecker::Create(FuchsiaDispatcher dispatcher,
                                                               std::unique_ptr<Bcache> bc,
                                                               const FsckOptions& fsck_options) {
  auto fs = Runner::Create(
      dispatcher, std::move(bc),
      MountOptions{
          .writability = fsck_options.read_only ? minfs::Writability::ReadOnlyDisk
                                                : minfs::Writability::Writable,
          .repair_filesystem = fsck_options.repair,
          .fsck_after_every_transaction = false,  // Explicit in case the default is overridden.
          .quiet = fsck_options.quiet,
      });
  if (fs.is_error()) {
    FX_LOGS(ERROR) << "MinfsChecker::Create Failed to Create Minfs: " << fs.error_value();
    return fs.take_error();
  }

  const Superblock& info = fs->minfs().Info();

  auto checker = std::unique_ptr<MinfsChecker>(new MinfsChecker(*std::move(fs), fsck_options));
  checker->links_.reset(new int64_t[info.inode_count]{0}, info.inode_count);
  checker->links_[0] = -1;
  checker->cached_doubly_indirect_ = 0;
  checker->cached_indirect_ = 0;

  if (zx_status_t status = checker->checked_inodes_.Reset(info.inode_count); status != ZX_OK) {
    FX_LOGS(ERROR) << "MinfsChecker::Init Failed to reset checked inodes: " << status;
    return zx::error(status);
  }
  if (zx_status_t status = checker->checked_blocks_.Reset(info.block_count); status != ZX_OK) {
    FX_LOGS(ERROR) << "MinfsChecker::Init Failed to reset checked blocks: " << status;
    return zx::error(status);
  }

  return zx::ok(std::move(checker));
}

void MinfsChecker::DumpStats() {
  if (!fsck_options_.quiet) {
    FX_LOGS(INFO) << "Minfs fsck:\n  inodes           : " << alloc_inodes_ - 1
                  << "\n  blocks           : " << alloc_blocks_ - 1
                  << "\n  indirect blocks  : " << indirect_blocks_
                  << "\n  directory blocks : " << directory_blocks_;
  }
}

#ifdef __Fuchsia__

// Write Superblock and Backup Superblock to disk.
zx::result<> WriteSuperblockAndBackupSuperblock(fs::DeviceTransactionHandler* transaction_handler,
                                                block_client::BlockDevice* device,
                                                Superblock* info) {
  storage::VmoBuffer buffer;
  zx_status_t status =
      buffer.Initialize(transaction_handler->GetDevice(), 1, kMinfsBlockSize, "fsck-super-block");
  if (status != ZX_OK) {
    return zx::error(status);
  }
  memcpy(buffer.Data(0), info, sizeof(*info));
  fs::BufferedOperationsBuilder builder;
  builder
      .Add(storage::Operation{.type = storage::OperationType::kWrite,
                              .vmo_offset = 0,
                              .dev_offset = kSuperblockStart,
                              .length = 1},
           &buffer)
      .Add(storage::Operation{.type = storage::OperationType::kWrite,
                              .vmo_offset = 0,
                              .dev_offset = (info->flags & kMinfsFlagFVM ? kFvmSuperblockBackup
                                                                         : kNonFvmSuperblockBackup),
                              .length = 1},
           &buffer);
  return zx::make_result(transaction_handler->RunRequests(builder.TakeOperations()));
}

// Reads backup superblock from correct location depending on whether filesystem has FVM support.
zx::result<Superblock> ReadBackupSuperblock(fs::TransactionHandler* transaction_handler,
                                            block_client::BlockDevice* device, uint32_t max_blocks,
                                            uint32_t backup_location) {
  Superblock backup;
  block_client::Reader reader(*device);
  if (zx_status_t status = reader.Read(static_cast<uint64_t>(backup_location) * kMinfsBlockSize,
                                       kMinfsBlockSize, &backup);
      status != ZX_OK) {
    return zx::error(status);
  }

  if (auto status = CheckSuperblock(backup, device, max_blocks); status.is_error()) {
    return status.take_error();
  }
  // Found a valid backup superblock. Confirm if the FVM flags are set in the backup superblock.
  if ((backup_location == kFvmSuperblockBackup) && ((backup.flags & kMinfsFlagFVM) == 0)) {
    return zx::error(ZX_ERR_BAD_STATE);
  } else if ((backup_location == kNonFvmSuperblockBackup) &&
             ((backup.flags & kMinfsFlagFVM) != 0)) {
    return zx::error(ZX_ERR_BAD_STATE);
  }

  return zx::ok(std::move(backup));
}
#endif

}  // namespace

// Repairs superblock from backup.
#ifdef __Fuchsia__
zx::result<Superblock> RepairSuperblock(fs::DeviceTransactionHandler* transaction_handler,
                                        block_client::BlockDevice* device, uint32_t max_blocks) {
  // Try the FVM backup location first.
  auto backup_info_or =
      ReadBackupSuperblock(transaction_handler, device, max_blocks, kFvmSuperblockBackup);

  if (backup_info_or.is_error()) {
    // Try the non-fvm backup superblock location.
    backup_info_or =
        ReadBackupSuperblock(transaction_handler, device, max_blocks, kNonFvmSuperblockBackup);
  }

  if (backup_info_or.is_error()) {
    FX_LOGS(ERROR) << "Fsck::RepairSuperblock failed. Unrepairable superblock: "
                   << backup_info_or.error_value();
    return backup_info_or.take_error();
  }
  FX_LOGS(INFO) << "Superblock corrupted. Repairing filesystem from backup superblock.";

  Superblock& backup_info = backup_info_or.value();

  // Try to reconstruct alloc_*_counts of the backup superblock, since the
  // alloc_*_counts might be out-of-sync with the actual values.
  zx::result<> status = ReconstructAllocCounts(transaction_handler, device, &backup_info);

  if (status.is_error()) {
    FX_LOGS(ERROR) << "Fsck::ReconstructAllocCounts failed. Unrepairable superblock: "
                   << status.status_value();
    return status.take_error();
  }
  // Recalculate checksum.
  UpdateChecksum(&backup_info);

  // Update superblock and backup superblock.
  status = WriteSuperblockAndBackupSuperblock(transaction_handler, device, &backup_info);

  if (status.is_error()) {
    FX_LOGS(ERROR) << "Fsck::RepairSuperblock failed to repair superblock from backup :"
                   << status.status_value();
  }

  return zx::ok(std::move(backup_info));
}
#endif

zx::result<Superblock> LoadSuperblock(Bcache* bc) {
  Superblock info;
  zx::result<> status = bc->Readblk(kSuperblockStart, &info);
  if (status.is_error()) {
    FX_LOGS(ERROR) << "could not read info block.";
    return status.take_error();
  }
  DumpInfo(info);
#ifdef __Fuchsia__
  status = CheckSuperblock(info, bc->device(), bc->Maxblk());
#else
  status = CheckSuperblock(info, bc->Maxblk());
#endif
  if (status.is_error()) {
    FX_LOGS(ERROR) << "Fsck: check_info failure: " << status.status_value();
    return status.take_error();
  }
  return zx::ok(info);
}

zx::result<uint64_t> UsedDataSize(std::unique_ptr<Bcache>& bc) {
  auto info_or = LoadSuperblock(bc.get());
  if (info_or.is_error()) {
    return info_or.take_error();
  }
  Superblock& info = info_or.value();

  uint64_t size =
      static_cast<uint64_t>(info.alloc_block_count) * static_cast<uint64_t>(info.block_size);
  return zx::ok(size);
}

zx::result<uint64_t> UsedInodes(std::unique_ptr<Bcache>& bc) {
  auto info_or = LoadSuperblock(bc.get());
  if (info_or.is_error()) {
    return info_or.take_error();
  }

  Superblock& info = info_or.value();
  return zx::ok(info.alloc_inode_count);
}

zx::result<uint64_t> UsedSize(std::unique_ptr<Bcache>& bc) {
  auto info_or = LoadSuperblock(bc.get());
  if (info_or.is_error()) {
    return info_or.take_error();
  }

  Superblock& info = info_or.value();
  uint64_t size = (NonDataBlocks(info) + info.alloc_block_count) * info.block_size;
  return zx::ok(size);
}

#ifdef __Fuchsia__
zx::result<uint32_t> CalculateBitsSetBitmap(fs::TransactionHandler* transaction_handler,
                                            block_client::BlockDevice* device, blk_t start_block,
                                            uint32_t num_blocks) {
#else
zx::result<uint32_t> CalculateBitsSetBitmap(fs::TransactionHandler* transaction_handler,
                                            blk_t start_block, uint32_t num_blocks) {
#endif
  minfs::RawBitmap bitmap;
  zx_status_t status = bitmap.Reset(static_cast<size_t>(num_blocks) * kMinfsBlockBits);
  if (status != ZX_OK) {
    return zx::error(status);
  }

#ifdef __Fuchsia__
  storage::OwnedVmoid map_vmoid;
  status =
      device->BlockAttachVmo(bitmap.StorageUnsafe()->GetVmo(), &map_vmoid.GetReference(device));
  if (status != ZX_OK) {
    return zx::error(status);
  }
  fs::internal::BorrowedBuffer buffer(map_vmoid.get());
#else
  fs::internal::BorrowedBuffer buffer(bitmap.StorageUnsafe()->GetData());
#endif
  status =
      transaction_handler->RunOperation(storage::Operation{.type = storage::OperationType::kRead,
                                                           .vmo_offset = 0,
                                                           .dev_offset = start_block,
                                                           .length = num_blocks},
                                        &buffer);
  if (status != ZX_OK) {
    return zx::error(status);
  }

  // Efficiently iterate through the bitmap to count the number of bits set in the bitmap.
  size_t off = 0;
  size_t bitmap_size = bitmap.size();
  size_t count = 0;

  while (off < bitmap_size) {
    size_t ind = 0;
    if (bitmap.Find(true, off, bitmap_size, 1, &ind) == ZX_OK) {
      size_t scan_ind = 0;
      if (bitmap.Scan(ind, bitmap_size, true, &scan_ind)) {
        count += (bitmap_size - ind);
        break;
      }
      count += (scan_ind - ind);
      off = scan_ind + 1;

    } else {
      break;
    }
  }

  return zx::ok(static_cast<uint32_t>(count));
}

#ifdef __Fuchsia__
zx::result<> ReconstructAllocCounts(fs::TransactionHandler* transaction_handler,
                                    block_client::BlockDevice* device, Superblock* out_info) {
#else
zx::result<> ReconstructAllocCounts(fs::TransactionHandler* transaction_handler,
                                    Superblock* out_info) {
#endif
  uint32_t allocation_bitmap_num_blocks =
      (out_info->block_count + kMinfsBlockBits - 1) / kMinfsBlockBits;

#ifdef __Fuchsia__
  // Correct allocated block count.
  auto alloc_block_count_or = CalculateBitsSetBitmap(
      transaction_handler, device, out_info->abm_block, allocation_bitmap_num_blocks);
#else
  auto alloc_block_count_or = CalculateBitsSetBitmap(transaction_handler, out_info->abm_block,
                                                     allocation_bitmap_num_blocks);
#endif
  if (alloc_block_count_or.is_error()) {
    return alloc_block_count_or.take_error();
  }
  out_info->alloc_block_count = alloc_block_count_or.value();

  uint32_t inode_bitmap_num_blocks =
      (out_info->inode_count + kMinfsBlockBits - 1) / kMinfsBlockBits;

#ifdef __Fuchsia__
  // Correct allocated inode count.
  auto alloc_inode_count_or = CalculateBitsSetBitmap(transaction_handler, device,
                                                     out_info->ibm_block, inode_bitmap_num_blocks);
#else
  auto alloc_inode_count_or =
      CalculateBitsSetBitmap(transaction_handler, out_info->ibm_block, inode_bitmap_num_blocks);
#endif

  if (alloc_inode_count_or.is_error()) {
    return alloc_inode_count_or.take_error();
  }
  out_info->alloc_inode_count = alloc_inode_count_or.value();

  return zx::ok();
}

zx::result<std::unique_ptr<Bcache>> Fsck(std::unique_ptr<Bcache> bc, const FsckOptions& options) {
  FuchsiaDispatcher dispatcher = nullptr;  // Use null for the dispatcher on host.
#ifdef __Fuchsia__
  async::Loop loop(&kAsyncLoopConfigNoAttachToCurrentThread);
  dispatcher = loop.dispatcher();
  if (zx_status_t status = loop.StartThread(); status != ZX_OK) {
    FX_LOGS(ERROR) << "Cannot initialize dispatch loop: " << zx_status_get_string(status);
    return zx::error(status);
  }
#endif

  auto chk_or = MinfsChecker::Create(dispatcher, std::move(bc), options);
  if (chk_or.is_error()) {
    FX_LOGS(ERROR) << "Fsck: Init failure: " << chk_or.error_value();
    return chk_or.take_error();
  }

  chk_or->CheckReserved();

  if (auto status = chk_or->CheckInode(kMinfsRootIno, kMinfsRootIno, 0); status.is_error()) {
    FX_LOGS(ERROR) << "Fsck: CheckInode failure: " << status.error_value();
    return status.take_error();
  }

  zx::result<> r;
  zx_status_t status = ZX_OK;

  // Save an error if it occurs, but check for subsequent errors anyway.
  r = chk_or->CheckUnlinkedInodes();
  status |= (status != ZX_OK) ? 0 : r.status_value();
  r = chk_or->CheckForUnusedBlocks();
  status |= (status != ZX_OK) ? 0 : r.status_value();
  r = chk_or->CheckForUnusedInodes();
  status |= (status != ZX_OK) ? 0 : r.status_value();
  r = chk_or->CheckLinkCounts();
  status |= (status != ZX_OK) ? 0 : r.status_value();
  r = chk_or->CheckAllocatedCounts();
  status |= (status != ZX_OK) ? 0 : r.status_value();

  r = chk_or->CheckSuperblockIntegrity();
  status |= (status != ZX_OK) ? 0 : r.status_value();

  status |= (status != ZX_OK) ? 0 : (chk_or->conforming() ? ZX_OK : ZX_ERR_BAD_STATE);
  if (status != ZX_OK) {
    return zx::error(status);
  }

  chk_or->DumpStats();

  bc = MinfsChecker::Destroy(std::move(chk_or.value()));
  return zx::ok(std::move(bc));
}

}  // namespace minfs
