// Copyright 2020 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/vnode_mapper.h"

#include "src/storage/minfs/lazy_buffer.h"
#include "src/storage/minfs/minfs_private.h"
#include "src/storage/minfs/vnode.h"

namespace minfs {

// A Minfs file looks like:
//
// +-----------------------|-------------------------]------------------------+
// |     direct blocks     |    indirect blocks      | double indirect blocks |
// +-----------------------|-------------------------|------------------------+
// |<--kMinfsDirect (16)-->^<-------- [1] ---------->^<-------- [2] --------->^
//                         |                         |                        |
//                         |                         |                        |
//            kIndirectFileStartBlock                |                        |
//                                  kDoubleIndirectFileStartBlock             |
//                                                                        kMaxBlocks
//
// [1]: kMinfsIndirect (31) * kDirectPerIndirect (2048) = 63488
// [2]: kMinfsDoubleIndirect (1) * kDirectPerIndirect (2048) * kDirectPerIndirect (2048) = 4194304
//
// The pointers to those blocks are arranged like this:
//
//      inode.dnum             inode.inum              inode.dinum
//          |                      |                        |
//          v                      v                        v
//      Data blocks         Indirect blocks      Double indirect blocks
//                                 | (a)                    | (b)
//                                 v                        v
//                           Data blocks             Indirect blocks
//                                                          | (c)
//                                                          v
//                                                     Data blocks
//
// We support up to three *levels* of indirection.
//
// The pointers that aren't stored in an inode are stored in blocks that we need to allocate, and
// are referred to as indirect blocks. These blocks store 2048 block pointers. These blocks of block
// pointers are cached and stored in a VMO backed buffer, also known as the virtual indirect file,
// and it has the following layout:
//
//   +------------------------+----------------------------+--------------------------+
//   |    indirect-leaf (a)   |    double-indirect (b)     | double-indirect-leaf (c) |
//   +------------------------+----------------------------+--------------------------+
//   |<-kMinfsIndirect (31)-->|<-kMinfsDoublyIndirect (1)->|<--------- [1] ---------->|
//
// [1]: kMinfsDoublyIndirect (1) * kMinfsDirectPerIndirect (2048)

namespace {

// These constants are the offsets in terms of block pointers to (b) and (c) above, respectively.
constexpr uint64_t kDoubleIndirectViewStart = kMinfsIndirect * kMinfsDirectPerIndirect;
constexpr uint64_t kDoubleIndirectLeafViewStart =
    kDoubleIndirectViewStart + kMinfsDoublyIndirect * kMinfsDirectPerIndirect;

// Scans |array| for a contiguous range of blocks of at most |max_blocks|.
uint64_t Coalesce(const blk_t* array, uint64_t max_blocks) {
  uint64_t count = 1;
  if (*array == 0) {
    // A sparse range.
    while (count < max_blocks && array[count] == 0) {
      ++count;
    }
  } else {
    while (count < max_blocks && array[count] == array[count - 1] + 1) {
      ++count;
    }
  }
  return count;
}

// Converts blk_t to DeviceBlock. blk_t represents zeroed/sparse/unmapped blocks differently and are
// relative to |dat_block| in the super-block.
DeviceBlock ToDeviceBlock(VnodeMinfs* vnode, blk_t block) {
  return block == 0 ? DeviceBlock::Unmapped() : DeviceBlock(block + vnode->Vfs()->Info().dat_block);
}

// Returns a flusher responsible for flushing updated block pointers in the inode.
BaseBufferView::Flusher GetDirectFlusher(VnodeMinfs* vnode, PendingWork* transaction) {
  return [vnode, transaction](BaseBufferView* view) {
    vnode->InodeSync(transaction, kMxFsSyncDefault);
    return zx::ok();
  };
}

// Returns a flusher responsible for flushing updated block pointers in indirect blocks;
BaseBufferView::Flusher GetIndirectFlusher(VnodeMinfs* vnode, LazyBuffer* file,
                                           PendingWork* transaction) {
#ifdef __Fuchsia__
  return [vnode, file, transaction](BaseBufferView* view) {
    VnodeIndirectMapper mapper(vnode);
    return file->Flush(
        transaction, &mapper, view,
        [transaction](ResizeableBufferType* buffer, BlockRange range, DeviceBlock device_block) {
          transaction->EnqueueMetadata(
              storage::Operation{
                  .type = storage::OperationType::kWrite,
                  .vmo_offset = range.Start(),
                  .dev_offset = device_block.block(),
                  .length = range.Length(),
              },
              buffer);
          return zx::ok();
        });
  };
#else
  // TODO(fxbug.dev/47947): For the time being, host side code must immediately write data to the
  // device, but we should be able to make this code the same as above if storage::BufferedOperation
  // changes a bit (so that a pointer to the buffer is kept rather than a pointer to the address in
  // memory).
  return [vnode, file, transaction](BaseBufferView* view) {
    VnodeIndirectMapper mapper(vnode);
    auto status = file->Flush(
        transaction, &mapper, view,
        [vnode](ResizeableBufferType* buffer, BlockRange range, DeviceBlock device_block) {
          return EnumerateBlocks(
              range, [vnode, buffer, range, device_block](BlockRange r) -> zx::status<uint64_t> {
                auto status = vnode->Vfs()->GetMutableBcache()->Writeblk(
                    static_cast<blk_t>(device_block.block() + (r.Start() - range.Start())),
                    buffer->Data(r.Start()));
                if (status.is_ok()) {
                  return zx::ok(1);
                } else {
                  return status.take_error();
                }
              });
        });
    return status;
  };
#endif
}

// -- View Getters --
//
// These functions are helpers that set up BufferView objects for ranges of block pointers.

// The dnum block pointers.
zx::status<BufferView<blk_t>> GetInodeDirectView(PendingWork* transaction, VnodeMinfs* vnode,
                                                 BlockPointerRange range) {
  ZX_ASSERT(range.End() <= kMinfsDirect);
  return zx::ok(BufferView<blk_t>(BufferPtr::FromMemory(&vnode->GetMutableInode()->dnum),
                                  range.Start(), range.End() - range.Start(),
                                  transaction ? GetDirectFlusher(vnode, transaction) : nullptr));
}

// The inum block pointers.
zx::status<BufferView<blk_t>> GetInodeIndirectView(PendingWork* transaction, VnodeMinfs* vnode,
                                                   BlockPointerRange range) {
  ZX_ASSERT(range.End() <= kMinfsIndirect);
  return zx::ok(BufferView<blk_t>(BufferPtr::FromMemory(&vnode->GetMutableInode()->inum),
                                  range.Start(), range.End() - range.Start(),
                                  transaction ? GetDirectFlusher(vnode, transaction) : nullptr));
}

// The dinum block pointers.
zx::status<BufferView<blk_t>> GetInodeDoubleIndirectView(PendingWork* transaction,
                                                         VnodeMinfs* vnode,
                                                         BlockPointerRange range) {
  ZX_ASSERT(range.End() <= kMinfsDoublyIndirect);
  return zx::ok(BufferView<blk_t>(BufferPtr::FromMemory(&vnode->GetMutableInode()->dinum),
                                  range.Start(), range.End() - range.Start(),
                                  transaction ? GetDirectFlusher(vnode, transaction) : nullptr));
}

// The pointers in the indirect file. See diagram above to understand how these are laid out.
zx::status<BufferView<blk_t>> GetViewForIndirectFile(PendingWork* transaction, VnodeMinfs* vnode,
                                                     BlockPointerRange range) {
  zx::status<LazyBuffer*> file = vnode->GetIndirectFile();
  if (file.is_error())
    return file.take_error();
  VnodeIndirectMapper mapper(vnode);
  LazyBuffer::Reader reader(vnode->Vfs()->GetMutableBcache(), &mapper, file.value());
  return file.value()->GetView<blk_t>(
      range.Start(), range.End() - range.Start(), &reader,
      transaction ? GetIndirectFlusher(vnode, file.value(), transaction) : nullptr);
}

}  // namespace

// -- VnodeIndirectMapper --

zx::status<DeviceBlockRange> VnodeIndirectMapper::Map(BlockRange range) {
  return MapForWrite(/*transaction=*/nullptr, range, /*allocated=*/nullptr);
}

zx::status<BufferView<blk_t>> VnodeIndirectMapper::GetView(PendingWork* transaction,
                                                           BlockRange range) {
  constexpr uint64_t kDoubleIndirectLeafStart = kMinfsIndirect + kMinfsDoublyIndirect;
  constexpr uint64_t kMax =
      kDoubleIndirectLeafStart + kMinfsDoublyIndirect * kMinfsDirectPerIndirect;
  if (range.Start() < kMinfsIndirect) {
    // Region (a) -- Pointers are to be found in the inum field in the inode.
    return GetInodeIndirectView(
        transaction, &vnode_,
        BlockPointerRange(range.Start(),
                          std::min(range.End(), static_cast<uint64_t>(kMinfsIndirect))));
  } else if (range.Start() < kDoubleIndirectLeafStart) {
    // Region (b) -- Pointers are to be found in the dinum field in the inode.
    return GetInodeDoubleIndirectView(
        transaction, &vnode_,
        BlockPointerRange(range.Start() - kMinfsIndirect,
                          std::min(range.End(), kDoubleIndirectLeafStart) - kMinfsIndirect));
  } else if (range.Start() < kMax) {
    // Region (c) -- Pointers are to be found in region (b) of the virtual indirect file.
    return GetViewForIndirectFile(
        transaction, &vnode_,
        BlockPointerRange(
            range.Start() - kDoubleIndirectLeafStart + kDoubleIndirectViewStart,
            std::min(range.End(), kMax) - kDoubleIndirectLeafStart + kDoubleIndirectViewStart));
  } else {
    return zx::error(ZX_ERR_OUT_OF_RANGE);
  }
}

zx::status<DeviceBlockRange> VnodeIndirectMapper::MapForWrite(PendingWork* transaction,
                                                              BlockRange range, bool* allocated) {
  BufferView<blk_t> view;
  if (auto view_or = GetView(transaction, range); view_or.is_error()) {
    return view_or.take_error();
  } else {
    view = std::move(view_or).value();
  }
  // If |allocated| is non-null, allocate an indirect block if necessary.
  uint64_t block_count;
  if (*view == 0 && allocated) {
    block_count = 1;
    blk_t new_block = 0;
    vnode_.AllocateIndirect(transaction, &new_block);
    ZX_ASSERT(new_block != 0);
    view.mut_ref() = new_block;
    *allocated = true;
    auto status = view.Flush();
    if (status.is_error())
      return status.take_error();
  } else {
    if (allocated)
      *allocated = false;
    block_count = Coalesce(view.data(), view.count());
  }
  return zx::ok(DeviceBlockRange(ToDeviceBlock(&vnode_, *view), block_count));
}

// -- VnodeMapper --

zx::status<std::pair<blk_t, uint64_t>> VnodeMapper::MapToBlk(BlockRange range) {
  VnodeIterator iterator;
  auto status = iterator.Init(this, nullptr, range.Start());
  if (status.is_error())
    return status.take_error();
  return zx::ok(std::make_pair(iterator.Blk(), iterator.GetContiguousBlockCount(range.Length())));
}

zx::status<DeviceBlockRange> VnodeMapper::Map(BlockRange range) {
  zx::status<std::pair<blk_t, uint64_t>> status = MapToBlk(range);
  if (status.is_error())
    return status.take_error();
  return zx::ok(
      DeviceBlockRange(ToDeviceBlock(&vnode_, status.value().first), status.value().second));
}

// -- VnodeIterator --

zx::status<> VnodeIterator::Init(VnodeMapper* mapper, PendingWork* transaction,
                                 uint64_t file_block) {
  mapper_ = mapper;
  transaction_ = transaction;
  file_block_ = file_block;
  contiguous_block_count_ = 0;
  // The file block determines the number of levels of views that we need, and the view-getters
  // that we need to use.
  if (file_block < VnodeMapper::kIndirectFileStartBlock) {
    // We only need the dnum pointers.
    level_count_ = 1;
    auto status =
        InitializeLevel(0, BlockPointerRange(0, kMinfsDirect), file_block, &GetInodeDirectView);
    if (status.is_error())
      return status;
  } else if (file_block < VnodeMapper::kDoubleIndirectFileStartBlock) {
    // We need the inum pointers and the blocks they point to.
    level_count_ = 2;
    uint64_t relative_block = file_block - VnodeMapper::kIndirectFileStartBlock;
    auto status = InitializeLevel(1, BlockPointerRange(0, kMinfsIndirect),
                                  relative_block / kMinfsDirectPerIndirect, &GetInodeIndirectView);
    if (status.is_error())
      return status;
    status = InitializeIndirectLevel(0, relative_block);
    if (status.is_error())
      return status;
  } else if (file_block < VnodeMapper::kMaxBlocks) {
    // We need the dinum pointers and two more levels.
    level_count_ = 3;
    uint64_t relative_block = file_block - VnodeMapper::kDoubleIndirectFileStartBlock;
    auto status =
        InitializeLevel(2, BlockPointerRange(0, kMinfsDoublyIndirect),
                        relative_block / kMinfsDirectPerIndirect / kMinfsDirectPerIndirect,
                        &GetInodeDoubleIndirectView);
    if (status.is_error())
      return status;
    status = InitializeIndirectLevel(
        1, relative_block / kMinfsDirectPerIndirect + kDoubleIndirectViewStart);
    if (status.is_error())
      return status;
    status = InitializeIndirectLevel(0, relative_block + kDoubleIndirectLeafViewStart);
    if (status.is_error())
      return status;
  } else if (file_block == VnodeMapper::kMaxBlocks) {
    // Allow the iterator to point at the end.
    level_count_ = 0;
  } else {
    return zx::error(ZX_ERR_OUT_OF_RANGE);
  }
  return zx::ok();
}

// Here |range| and |block| are blocks relative to the base of the pointers we are looking at, which
// could be the dnum, inum, dinum pointers or the pointers in the virtual indirect file. |block|
// must be contained within |range|.
zx::status<> VnodeIterator::InitializeLevel(int level, BlockPointerRange range, uint64_t block,
                                            ViewGetter view_getter) {
  ZX_ASSERT(block >= range.Start() && block < range.End());
  levels_[level].range = range;
  levels_[level].count = range.End() - range.Start();
  levels_[level].index = block - range.Start();
  // If the parent level is sparse, delay getting the view until we need to.
  if (level + 1 < level_count_ && levels_[level + 1].blk() == 0) {
    levels_[level].view = {};
    levels_[level].view_getter = std::move(view_getter);
  } else {
    zx::status<BufferView<blk_t>> view = view_getter(transaction_, &mapper_->vnode(), range);
    if (view.is_error())
      return view.take_error();
    levels_[level].view = std::move(view).value();
    levels_[level].view_getter = nullptr;
  }
  return zx::ok();
}

// Convenience function for levels that point to the virtual indirect file. Here |relative_block| is
// the pointer offset within the virtual indirect file.
zx::status<> VnodeIterator::InitializeIndirectLevel(int level, uint64_t relative_block) {
  uint64_t first_block = fbl::round_down(relative_block, kMinfsDirectPerIndirect);
  return InitializeLevel(level,
                         BlockPointerRange(first_block, first_block + kMinfsDirectPerIndirect),
                         relative_block, &GetViewForIndirectFile);
}

zx::status<> VnodeIterator::SetBlk(Level* level, blk_t block) {
  ZX_ASSERT(level_count_ > 0);
  // If this level is sparse, try and get a view for it now.
  if (level->IsSparse()) {
    if (block == 0)
      return zx::ok();
    zx::status<BufferView<blk_t>> view =
        level->view_getter(transaction_, &mapper_->vnode(), level->range);
    if (view.is_error())
      return view.take_error();
    level->view = std::move(view).value();
  }
  level->view.mut_ref(level->index) = block;
  return zx::ok();
}

uint64_t VnodeIterator::GetContiguousBlockCount(uint64_t max_blocks) const {
  if (level_count_ == 0)
    return 0;
  if (contiguous_block_count_ == 0)
    contiguous_block_count_ = ComputeContiguousBlockCount();
  return std::min(contiguous_block_count_, max_blocks);
}

uint64_t VnodeIterator::ComputeContiguousBlockCount() const {
  // For efficiency reasons, handle sparse ranges differently. This is so we can quickly scan the
  // (typically) unallocated/sparse blocks from the end of the file.
  if (Blk() == 0) {
    // The number of blocks we have found so far.
    uint64_t count = 0;
    // The number of blocks a block pointer represents at the current level.
    uint64_t multiplier = 1;
    // The index into the view for the current level.
    uint64_t index = levels_[0].index;
    int level = 0;
    // N.B. When we truncate blocks, we rely on the fact that we only go *up* the tree here, *not*
    // down. To further explain, consider the case where the inode points to an indirect block, but
    // the indirect block doesn't happen to have any blocks allocated. We could, in theory, coalesce
    // those blocks and just say it's all sparse, but if we did that, we wouldn't free the indirect
    // block. Instead, we'll coalesce as many blocks as we can at the lowest level, then move up a
    // level and coalesce all the blocks at that level, but we'll stop as soon as we find an
    // allocated block, even though that indirect block might not point to any allocated blocks.
    for (;;) {
      const uint64_t left = levels_[level].count - index;
      if (left == 0 || levels_[level].IsSparse()) {
        count += left * multiplier;
      } else if (levels_[level].view[index] == 0) {
        uint64_t contiguous = Coalesce(&levels_[level].view[index], left);
        count += contiguous * multiplier;
        if (contiguous < left)
          return count;
      } else {
        // We've come to a block that isn't sparse.
        return count;
      }
      if (++level >= level_count_)
        return count;
      multiplier *= kMinfsDirectPerIndirect;
      index = levels_[level].index + 1;
    }
  } else {
    return Coalesce(&levels_[0].view[levels_[0].index], levels_[0].remaining());
  }
}

zx::status<> VnodeIterator::FlushLevel(int level) {
  if (!transaction_)
    return zx::ok();
  if (level + 1 < level_count_) {
    const blk_t parent_block = levels_[level + 1].blk();
    // If this block is now empty and we have a parent, deallocate rather than writing block. As an
    // optimisation, we quickly check that item current pointed at is zero before doing a full check
    // of the whole block.
    if (parent_block != 0 && levels_[level].blk() == 0) {
      ZX_ASSERT(levels_[level].view.count() == kMinfsDirectPerIndirect);
      bool empty = true;
      for (unsigned i = 0; i < kMinfsDirectPerIndirect; ++i) {
        if (levels_[level].view[i] != 0) {
          empty = false;
          break;
        }
      }
      if (empty) {
        // Delete the block and update the parent.
        mapper_->vnode().DeleteBlock(transaction_, 0, parent_block, /*indirect=*/true);
        [[maybe_unused]] auto status = SetBlk(&levels_[level + 1], 0);
        levels_[level].view.set_dirty(false);
        return zx::ok();
      }
    }
    // If there are modifications and the parent doesn't have a block, allocate it now. This isn't
    // strictly necessary because VnodeIndirectMapper will allocate if it needs to. However, it will
    // immediately flush whereas if we do it here, we can delay the flush as there might be more
    // changes to make later.
    if (levels_[level].view.dirty() && parent_block == 0) {
      blk_t new_block;
      mapper_->vnode().AllocateIndirect(transaction_, &new_block);
      ZX_ASSERT(new_block != 0);
      [[maybe_unused]] auto status = SetBlk(&levels_[level + 1], new_block);
    }
  }
  return levels_[level].view.Flush();
}

zx::status<> VnodeIterator::Flush() {
  if (!transaction_)
    return zx::ok();  // Iterator is read-only.
  for (int level = 0; level < level_count_; ++level) {
    auto status = FlushLevel(level);
    if (status.is_error())
      return status;
  }
  return zx::ok();
}

zx::status<> VnodeIterator::Advance(const uint64_t advance) {
  if (level_count_ == 0) {
    return advance == 0 ? zx::ok() : zx::make_status(ZX_ERR_BAD_STATE);
  }
  // Short circuit for the common case.
  if (advance < levels_[0].remaining()) {
    levels_[0].index += advance;
    file_block_ += advance;
    if (advance >= contiguous_block_count_) {
      contiguous_block_count_ = 0;
    } else {
      contiguous_block_count_ -= advance;
    }
    return zx::ok();
  }
  // Get a new iterator for the new file block.
  VnodeIterator iterator;
  auto status = iterator.Init(mapper_, transaction_, file_block_ + advance);
  if (status.is_error())
    return status;
  // Now see which of the old views need flushing.
  if (iterator.level_count_ != level_count_) {
    // The level count is different so we flush all of the levels.
    status = Flush();
    if (status.is_error())
      return status;
  } else {
    // If the two iterators have the same view for a level, just move the view. This prevents us
    // from over-flushing.
    for (int level = 0; level < level_count_; ++level) {
      if (levels_[level].range == iterator.levels_[level].range) {
        // The ranges are the same and because the level count is the same, we know that the view
        // must point to the same thing, so we can just move the views over and defer flushing this
        // level.
        iterator.levels_[level].view = std::move(levels_[level].view);
      } else {
        status = FlushLevel(level);
        if (status.is_error())
          return status;
      }
    }
  }
  *this = std::move(iterator);
  return zx::ok();
}

}  // namespace minfs
