// 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <minfs/format.h>
#include <minfs/fsck.h>

#include "minfs-private.h"
#include <utility>

namespace minfs {

class MinfsChecker {
public:
    MinfsChecker();
    zx_status_t Init(fbl::unique_ptr<Bcache> bc, const Superblock* info);
    void CheckReserved();
    zx_status_t CheckInode(ino_t ino, ino_t parent, bool dot_or_dotdot);
    zx_status_t CheckUnlinkedInodes();
    zx_status_t CheckForUnusedBlocks() const;
    zx_status_t CheckForUnusedInodes() const;
    zx_status_t CheckLinkCounts() const;
    zx_status_t CheckAllocatedCounts() const;
    zx_status_t CheckJournal() const;

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

private:
    DISALLOW_COPY_ASSIGN_AND_MOVE(MinfsChecker);

    zx_status_t GetInode(Inode* inode, ino_t ino);

    // Returns the nth block within an inode, relative to the start of the
    // file. Returns the "next_n" which 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_status_t GetInodeNthBno(Inode* inode, blk_t n, blk_t* next_n,
                               blk_t* bno_out);
    zx_status_t CheckDirectory(Inode* inode, ino_t ino,
                               ino_t parent, uint32_t flags);
    const char* CheckDataBlock(blk_t bno);
    zx_status_t CheckFile(Inode* inode, ino_t ino);

    fbl::unique_ptr<Minfs> fs_;
    RawBitmap checked_inodes_;
    RawBitmap checked_blocks_;

    uint32_t alloc_inodes_;
    uint32_t alloc_blocks_;
    fbl::Array<int32_t> links_;

    blk_t cached_doubly_indirect_;
    blk_t cached_indirect_;
    uint8_t doubly_indirect_cache_[kMinfsBlockSize];
    uint8_t indirect_cache_[kMinfsBlockSize];
};

zx_status_t MinfsChecker::GetInode(Inode* inode, ino_t ino) {
    if (ino >= fs_->Info().inode_count) {
        FS_TRACE_ERROR("check: ino %u out of range (>=%u)\n",
              ino, fs_->Info().inode_count);
        return ZX_ERR_OUT_OF_RANGE;
    }

    fs_->GetInodeManager()->Load(ino, inode);
    if ((inode->magic != kMinfsMagicFile) && (inode->magic != kMinfsMagicDir)) {
        FS_TRACE_ERROR("check: ino %u has bad magic %#x\n", ino, inode->magic);
        return ZX_ERR_IO_DATA_INTEGRITY;
    }
    return ZX_OK;
}

#define CD_DUMP 1
#define CD_RECURSE 2

zx_status_t MinfsChecker::GetInodeNthBno(Inode* inode, blk_t n,
                                         blk_t* next_n, blk_t* bno_out) {
    // 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) {
        *bno_out = inode->dnum[n];
        return ZX_OK;
    }

    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) {
            *bno_out = 0;
            *next_n = kMinfsDirect + (i + 1) * kMinfsDirectPerIndirect;
            return ZX_OK;
        }

        if (cached_indirect_ != ibno) {
            zx_status_t status;
            if ((status = fs_->ReadDat(ibno, indirect_cache_)) != ZX_OK) {
                return status;
            }
            cached_indirect_ = ibno;
        }

        uint32_t* ientry = reinterpret_cast<uint32_t*>(indirect_cache_);
        *bno_out = ientry[j];
        return ZX_OK;
    }

    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) {
            *bno_out = 0;
            *next_n = kMinfsDirect + kMinfsIndirect * kMinfsDirectPerIndirect +
                    (i + 1) * kMinfsDirectPerDindirect;
            return ZX_OK;
        }

        if (cached_doubly_indirect_ != dibno) {
            zx_status_t status;
            if ((status = fs_->ReadDat(dibno, doubly_indirect_cache_)) != ZX_OK) {
                return status;
            }
            cached_doubly_indirect_ = dibno;
        }

        uint32_t* dientry = reinterpret_cast<uint32_t*>(doubly_indirect_cache_);
        blk_t ibno;
        if ((ibno = dientry[j]) == 0) {
            *bno_out = 0;
            *next_n = kMinfsDirect + kMinfsIndirect * kMinfsDirectPerIndirect +
                    (i * kMinfsDirectPerDindirect) + (j + 1) * kMinfsDirectPerIndirect;
            return ZX_OK;
        }

        if (cached_indirect_ != ibno) {
            zx_status_t status;
            if ((status = fs_->ReadDat(ibno, indirect_cache_)) != ZX_OK) {
                return status;
            }
            cached_indirect_ = ibno;
        }

        uint32_t* ientry = reinterpret_cast<uint32_t*>(indirect_cache_);
        *bno_out = ientry[k];
        return ZX_OK;
    }

    return ZX_ERR_OUT_OF_RANGE;
}

zx_status_t 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_status_t status;
    fbl::RefPtr<VnodeMinfs> vn;
    if ((status = VnodeMinfs::Recreate(fs_.get(), ino, &vn)) != ZX_OK) {
        return status;
    }

    size_t off = 0;
    while (true) {
        uint32_t data[MINFS_DIRENT_SIZE];
        size_t actual;
        status = vn->ReadInternal(nullptr, data, MINFS_DIRENT_SIZE, off, &actual);
        if (status != ZX_OK || actual != MINFS_DIRENT_SIZE) {
            FS_TRACE_ERROR("check: ino#%u: Could not read de[%u] at %zd\n", eno, ino, 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.
                FS_TRACE_ERROR("check: de count (%u) > inode_dirent_count (%u)\n", eno,
                               inode->dirent_count);
            }
            return status != ZX_OK ? status : ZX_ERR_IO;
        }
        Dirent* de = reinterpret_cast<Dirent*>(data);
        uint32_t rlen = static_cast<uint32_t>(MinfsReclen(de, off));
        uint32_t dlen = DirentSize(de->namelen);
        bool is_last = de->reclen & kMinfsReclenLast;
        if (!is_last && ((rlen < MINFS_DIRENT_SIZE) || (dlen > rlen) ||
                         (dlen > kMinfsMaxDirentSize) || (rlen & 3))) {
            FS_TRACE_ERROR("check: ino#%u: de[%u]: bad dirent reclen (%u)\n", ino, eno, rlen);
            return ZX_ERR_IO_DATA_INTEGRITY;
        }
        if (de->ino == 0) {
            if (flags & CD_DUMP) {
                FS_TRACE_DEBUG("ino#%u: de[%u]: <empty> reclen=%u\n", ino, eno, rlen);
            }
        } else {
            // Re-read the dirent to acquire the full name
            uint32_t record_full[DirentSize(NAME_MAX)];
            status = vn->ReadInternal(nullptr, record_full, DirentSize(de->namelen), off, &actual);
            if (status != ZX_OK || actual != DirentSize(de->namelen)) {
                FS_TRACE_ERROR("check: Error reading dirent of size: %u\n", DirentSize(de->namelen));
                return ZX_ERR_IO;
            }
            de = reinterpret_cast<Dirent*>(record_full);
            bool dot_or_dotdot = false;

            if ((de->namelen == 0) || (de->namelen > (rlen - MINFS_DIRENT_SIZE))) {
                FS_TRACE_ERROR("check: ino#%u: de[%u]: invalid namelen %u\n", ino, eno,
                               de->namelen);
                return ZX_ERR_IO_DATA_INTEGRITY;
            }
            if ((de->namelen == 1) && (de->name[0] == '.')) {
                if (dot) {
                    FS_TRACE_ERROR("check: ino#%u: multiple '.' entries\n", ino);
                }
                dot_or_dotdot = true;
                dot = true;
                if (de->ino != ino) {
                    FS_TRACE_ERROR("check: ino#%u: de[%u]: '.' ino=%u (not self!)\n", ino, eno,
                                   de->ino);
                }
            }
            if ((de->namelen == 2) && (de->name[0] == '.') && (de->name[1] == '.')) {
                if (dotdot) {
                    FS_TRACE_ERROR("check: ino#%u: multiple '..' entries\n", ino);
                }
                dot_or_dotdot = true;
                dotdot = true;
                if (de->ino != parent) {
                    FS_TRACE_ERROR("check: ino#%u: de[%u]: '..' ino=%u (not parent!)\n", ino, eno,
                                   de->ino);
                }
            }
            //TODO: check for cycles (non-dot/dotdot dir ref already in checked bitmap)
            if (flags & CD_DUMP) {
                FS_TRACE_DEBUG("ino#%u: de[%u]: ino=%u type=%u '%.*s' %s\n", ino, eno, de->ino,
                               de->type, de->namelen, de->name, is_last ? "[last]" : "");
            }

            if (flags & CD_RECURSE) {
                if ((status = CheckInode(de->ino, ino, dot_or_dotdot)) < 0) {
                    return status;
                }
            }
            dirent_count++;
        }
        if (is_last) {
            break;
        } else {
            off += rlen;
        }
        eno++;
    }
    if (dirent_count != inode->dirent_count) {
        FS_TRACE_ERROR("check: ino#%u: dirent_count of %u != %u (actual)\n",
              ino, inode->dirent_count, dirent_count);
    }
    if (dot == false) {
        FS_TRACE_ERROR("check: ino#%u: directory missing '.'\n", ino);
    }
    if (dotdot == false) {
        FS_TRACE_ERROR("check: ino#%u: directory missing '..'\n", ino);
    }
    return ZX_OK;
}

const char* MinfsChecker::CheckDataBlock(blk_t bno) {
    if (bno == 0) {
        return "reserved bno";
    }
    if (bno >= fs_->Info().block_count) {
        return "out of range";
    }
    if (!fs_->GetBlockAllocator()->CheckAllocated(bno)) {
        return "not allocated";
    }
    if (checked_blocks_.Get(bno, bno + 1)) {
        return "double-allocated";
    }
    checked_blocks_.Set(bno, bno + 1);
    alloc_blocks_++;
    return nullptr;
}

zx_status_t MinfsChecker::CheckFile(Inode* inode, ino_t ino) {
    FS_TRACE_DEBUG("Direct blocks: \n");
    for (unsigned n = 0; n < kMinfsDirect; n++) {
        FS_TRACE_DEBUG(" %d,", inode->dnum[n]);
    }
    FS_TRACE_DEBUG(" ...\n");

    uint32_t block_count = 0;

    // count and sanity-check indirect blocks
    for (unsigned n = 0; n < kMinfsIndirect; n++) {
        if (inode->inum[n]) {
            const char* msg;
            if ((msg = CheckDataBlock(inode->inum[n])) != nullptr) {
                FS_TRACE_WARN("check: ino#%u: indirect block %u(@%u): %s\n",
                     ino, n, inode->inum[n], msg);
                conforming_ = false;
            }
            block_count++;
        }
    }

    // count and sanity-check doubly indirect blocks
    for (unsigned n = 0; n < kMinfsDoublyIndirect; n++) {
        if (inode->dinum[n]) {
            const char* msg;
            if ((msg = CheckDataBlock(inode->dinum[n])) != nullptr) {
                FS_TRACE_WARN("check: ino#%u: doubly indirect block %u(@%u): %s\n",
                     ino, n, inode->dinum[n], msg);
                conforming_ = false;
            }
            block_count++;

            char data[kMinfsBlockSize];
            zx_status_t status;
            if ((status = fs_->ReadDat(inode->dinum[n], data)) != ZX_OK) {
                return status;
            }
            uint32_t* entry = reinterpret_cast<uint32_t*>(data);

            for (unsigned m = 0; m < kMinfsDirectPerIndirect; m++) {
                if (entry[m]) {
                    if ((msg = CheckDataBlock(entry[m])) != nullptr) {
                        FS_TRACE_WARN("check: ino#%u: indirect block (in dind) %u(@%u): %s\n",
                            ino, m, entry[m], msg);
                        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) {
        zx_status_t status;
        blk_t bno;
        blk_t next_n;
        if ((status = GetInodeNthBno(inode, n, &next_n, &bno)) < 0) {
            if (status == ZX_ERR_OUT_OF_RANGE) {
                break;
            } else {
                return status;
            }
        }
        assert(next_n > n);
        if (bno) {
            next_blk = n + 1;
            block_count++;
            const char* msg;
            if ((msg = CheckDataBlock(bno)) != nullptr) {
                FS_TRACE_WARN("check: ino#%u: block %u(@%u): %s\n", ino, n, bno, msg);
                conforming_ = false;
            }
        }
        n = next_n;
    }
    if (next_blk) {
        unsigned max_blocks = fbl::round_up(inode->size, kMinfsBlockSize) / kMinfsBlockSize;
        if (next_blk > max_blocks) {
            FS_TRACE_WARN("check: ino#%u: filesize too small\n", ino);
            conforming_ = false;
        }
    }
    if (block_count != inode->block_count) {
        FS_TRACE_WARN("check: ino#%u: block count %u, actual blocks %u\n",
             ino, inode->block_count, block_count);
        conforming_ = false;
    }
    return ZX_OK;
}

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

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

zx_status_t MinfsChecker::CheckInode(ino_t ino, ino_t parent, bool dot_or_dotdot) {
    Inode inode;
    zx_status_t status;

    if ((status = GetInode(&inode, ino)) < 0) {
        FS_TRACE_ERROR("check: ino#%u: not readable: %d\n", ino, status);
        return status;
    }

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

    if (inode.magic == kMinfsMagicDir && prev_checked && !dot_or_dotdot) {
        FS_TRACE_ERROR("check: ino#%u: Multiple hard links to directory (excluding '.' and '..') found\n", ino);
        return ZX_ERR_BAD_STATE;
    }

    links_[ino - 1] += 1;

    if (prev_checked) {
        // we've been here before
        return ZX_OK;
    }

    links_[ino - 1] -= inode.link_count;
    checked_inodes_.Set(ino, ino + 1);
    alloc_inodes_++;

    if (!fs_->GetInodeManager()->GetInodeAllocator()->CheckAllocated(ino)) {
       FS_TRACE_WARN("check: ino#%u: not marked in-use\n", ino);
        conforming_ = false;
    }

    if (inode.magic == kMinfsMagicDir) {
        FS_TRACE_DEBUG("ino#%u: DIR blks=%u links=%u\n", ino, inode.block_count, inode.link_count);
        if ((status = CheckFile(&inode, ino)) < 0) {
            return status;
        }
        if ((status = CheckDirectory(&inode, ino, parent, CD_DUMP)) < 0) {
            return status;
        }
        if ((status = CheckDirectory(&inode, ino, parent, CD_RECURSE)) < 0) {
            return status;
        }
    } else {
        FS_TRACE_DEBUG("ino#%u: FILE blks=%u links=%u size=%u\n", ino, inode.block_count,
                       inode.link_count, inode.size);
        if ((status = CheckFile(&inode, ino)) < 0) {
            return status;
        }
    }
    return ZX_OK;
}

zx_status_t 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++;

        Inode inode;
        zx_status_t status = GetInode(&inode, next_ino);
        if (status != ZX_OK) {
            FS_TRACE_ERROR("check: ino#%u: not readable: %d\n", next_ino, status);
            return status;
        }

        if (inode.link_count > 0) {
            FS_TRACE_ERROR("check: ino#%u: should have 0 links\n", next_ino);
            return ZX_ERR_BAD_STATE;
        }

        if (inode.last_inode != last_ino) {
            FS_TRACE_ERROR("check: ino#%u: incorrect last unlinked inode\n", next_ino);
            return ZX_ERR_BAD_STATE;
        }

        links_[next_ino - 1] = -1;

        if ((status = CheckInode(next_ino, 0, 0)) != ZX_OK) {
            FS_TRACE_ERROR("minfs_check: CheckInode failure: %d\n", status);
            return status;
        }

        last_ino = next_ino;
        next_ino = inode.next_inode;
    }

    if (fs_->Info().unlinked_tail != last_ino) {
        FS_TRACE_ERROR("minfs_check: Incorrect unlinked tail: %d\n", fs_->Info().unlinked_tail);
        return ZX_ERR_BAD_STATE;
    }

    if (unlinked_count > 0) {
        FS_TRACE_WARN("minfs_check: Warning: %u unlinked inodes found\n", unlinked_count);
    }

    return ZX_OK;
}

zx_status_t 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) {
        FS_TRACE_ERROR("check: %u allocated block%s not in use\n",
              missing, missing > 1 ? "s" : "");
        return ZX_ERR_BAD_STATE;
    }
    return ZX_OK;
}

zx_status_t 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++;
            }
        }
    }
    if (missing) {
        FS_TRACE_ERROR("check: %u allocated inode%s not in use\n",
              missing, missing > 1 ? "s" : "");
        return ZX_ERR_BAD_STATE;
    }
    return ZX_OK;
}

zx_status_t MinfsChecker::CheckLinkCounts() const {
    unsigned error = 0;
    for (uint32_t n = 0; n < fs_->Info().inode_count; n++) {
        if (links_[n] != 0) {
            error += 1;
            FS_TRACE_ERROR("check: inode#%u has incorrect link count %u\n", n + 1, links_[n]);
            return ZX_ERR_BAD_STATE;
        }
    }
    if (error) {
        FS_TRACE_ERROR("check: %u inode%s with incorrect link count\n",
              error, error > 1 ? "s" : "");
        return ZX_ERR_BAD_STATE;
    }
    return ZX_OK;
}

zx_status_t MinfsChecker::CheckAllocatedCounts() const {
    zx_status_t status = ZX_OK;
    if (alloc_blocks_ != fs_->Info().alloc_block_count) {
        FS_TRACE_ERROR("check: incorrect allocated block count %u (should be %u)\n",
                       fs_->Info().alloc_block_count, alloc_blocks_);
        status = ZX_ERR_BAD_STATE;
    }

    if (alloc_inodes_ != fs_->Info().alloc_inode_count) {
        FS_TRACE_ERROR("check: incorrect allocated inode count %u (should be %u)\n",
                       fs_->Info().alloc_inode_count, alloc_inodes_);
        status = ZX_ERR_BAD_STATE;
    }

    return status;
}

zx_status_t MinfsChecker::CheckJournal() const {
    char data[kMinfsBlockSize];
    blk_t journal_block;
#ifdef __Fuchsia__
    journal_block = fs_->Info().journal_start_block;
#else
    journal_block = fs_->GetBlockOffsets().JournalStartBlock();
#endif

    if (fs_->bc_->Readblk(journal_block, data) < 0) {
        FS_TRACE_ERROR("minfs: could not read journal block\n");
        return ZX_ERR_IO;
    }

    const JournalInfo* journal_info = reinterpret_cast<const JournalInfo*>(data);
    if (journal_info->magic != kJournalMagic) {
        FS_TRACE_ERROR("minfs: invalid journal magic\n");
        return ZX_ERR_BAD_STATE;
    }

    return ZX_OK;
}

MinfsChecker::MinfsChecker()
    : conforming_(true), fs_(nullptr), alloc_inodes_(0), alloc_blocks_(0), links_() {}

zx_status_t MinfsChecker::Init(fbl::unique_ptr<Bcache> bc, const Superblock* info) {
    links_.reset(new int32_t[info->inode_count]{0}, info->inode_count);
    links_[0] = -1;

    cached_doubly_indirect_ = 0;
    cached_indirect_ = 0;

    zx_status_t status;
    if ((status = checked_inodes_.Reset(info->inode_count)) != ZX_OK) {
        FS_TRACE_ERROR("MinfsChecker::Init Failed to reset checked inodes: %d\n", status);
        return status;
    }
    if ((status = checked_blocks_.Reset(info->block_count)) != ZX_OK) {
        FS_TRACE_ERROR("MinfsChecker::Init Failed to reset checked blocks: %d\n", status);
        return status;
    }
    fbl::unique_ptr<Minfs> fs;
    if ((status = Minfs::Create(std::move(bc), info, &fs, IntegrityCheck::kAll)) != ZX_OK) {
        FS_TRACE_ERROR("MinfsChecker::Create Failed to Create Minfs: %d\n", status);
        return status;
    }
    fs_ = std::move(fs);

    return ZX_OK;
}

zx_status_t LoadSuperblock(fbl::unique_ptr<Bcache>& bc, Superblock* out) {
    zx_status_t status;

    char data[kMinfsBlockSize];
    if (bc->Readblk(0, data) < 0) {
        FS_TRACE_ERROR("minfs: could not read info block\n");
        return ZX_ERR_IO;
    }
    const Superblock* info = reinterpret_cast<const Superblock*>(data);
    DumpInfo(info);
    if ((status = CheckSuperblock(info, bc.get())) != ZX_OK) {
        FS_TRACE_ERROR("Fsck: check_info failure: %d\n", status);
        return status;
    }

    memcpy(out, info, sizeof(*out));
    return ZX_OK;
}

zx_status_t UsedDataSize(fbl::unique_ptr<Bcache>& bc, uint64_t* out_size) {
    zx_status_t status;
    Superblock info = {};
    if ((status = LoadSuperblock(bc, &info)) != ZX_OK) {
        return status;
    }

    *out_size = (info.alloc_block_count * info.block_size);
    return ZX_OK;
}

zx_status_t UsedInodes(fbl::unique_ptr<Bcache>& bc, uint64_t* out_inodes) {
    zx_status_t status;
    Superblock info = {};
    if ((status = LoadSuperblock(bc, &info)) != ZX_OK) {
        return status;
    }

    *out_inodes = info.alloc_inode_count;
    return ZX_OK;
}

zx_status_t UsedSize(fbl::unique_ptr<Bcache>& bc, uint64_t* out_size) {
    zx_status_t status;
    Superblock info = {};
    if ((status = LoadSuperblock(bc, &info)) != ZX_OK) {
        return status;
    }

    *out_size = (NonDataBlocks(info) + info.alloc_block_count) * info.block_size;
    return ZX_OK;
}

zx_status_t Fsck(fbl::unique_ptr<Bcache> bc) {
    zx_status_t status;
    Superblock info = {};
    if ((status = LoadSuperblock(bc, &info)) != ZX_OK) {
        return status;
    }

    MinfsChecker chk;
    if ((status = chk.Init(std::move(bc), &info)) != ZX_OK) {
        FS_TRACE_ERROR("Fsck: Init failure: %d\n", status);
        return status;
    }

    chk.CheckReserved();

    //TODO: check root not a directory
    if ((status = chk.CheckInode(1, 1, 0)) != ZX_OK) {
        FS_TRACE_ERROR("Fsck: CheckInode failure: %d\n", status);
        return status;
    }

    zx_status_t r;

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

    //TODO: check allocated inodes that were abandoned
    //TODO: check allocated blocks that were not accounted for
    //TODO: check unallocated inodes where magic != 0
    status |= (status != ZX_OK) ? 0 : (chk.conforming_ ? ZX_OK : ZX_ERR_BAD_STATE);

    return status;
}

} // namespace minfs
