// Copyright 2019 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 <lib/cksum.h>
#include <lib/syslog/cpp/macros.h>

#include <iterator>
#include <utility>

#include <blobfs/common.h>
#include <blobfs/format.h>
#include <blobfs/mkfs.h>
#include <fbl/ref_ptr.h>
#include <fs/journal/initializer.h>
#include <fvm/client.h>
#include <safemath/checked_math.h>
#include <storage/buffer/owned_vmoid.h>

namespace blobfs {
namespace {

// Attempts to format the device as an FVM-based filesystem.
//
// If |device| does not speak FVM protocols, returns ZX_OK.
// If the volume cannot be modified (either removing old slices, or extending
// the volume to contain new slices), an error from the FVM is returned.
zx_status_t TryFormattingFVM(BlockDevice* device, Superblock* superblock) {
  fuchsia_hardware_block_volume_VolumeInfo fvm_info = {};
  zx_status_t status = device->VolumeQuery(&fvm_info);
  if (status != ZX_OK) {
    // If the device does not speak the FVM protocol, that's acceptable.
    return ZX_OK;
  }

  superblock->slice_size = fvm_info.slice_size;
  superblock->flags |= kBlobFlagFVM;

  if (superblock->slice_size % kBlobfsBlockSize) {
    FX_LOGS(ERROR) << "mkfs: Slice size not multiple of blobfs block";
    return ZX_ERR_IO_INVALID;
  }

  status = fvm::ResetAllSlices(device);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "mkfs: Failed to reset slices";
    return status;
  }

  const size_t blocks_per_slice = superblock->slice_size / kBlobfsBlockSize;
  // Converts blocks to slices, rounding up to the nearest slice size.
  auto BlocksToSlices = [blocks_per_slice](uint64_t blocks) {
    return fbl::round_up(blocks, blocks_per_slice) / blocks_per_slice;
  };
  uint64_t data_blocks = fbl::round_up(kMinimumDataBlocks, blocks_per_slice);

  uint64_t offset = kFVMBlockMapStart / blocks_per_slice;
  uint64_t length = BlocksToSlices(BlocksRequiredForBits(data_blocks));
  superblock->abm_slices = static_cast<uint32_t>(length);
  status = device->VolumeExtend(offset, superblock->abm_slices);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "mkfs: Failed to allocate block map";
    return status;
  }

  offset = kFVMNodeMapStart / blocks_per_slice;
  superblock->ino_slices = 1;
  status = device->VolumeExtend(offset, superblock->ino_slices);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "mkfs: Failed to allocate node map";
    return status;
  }

  // Allocate the minimum number of journal blocks in FVM.
  offset = kFVMJournalStart / blocks_per_slice;
  length = fbl::round_up(kDefaultJournalBlocks, blocks_per_slice) / blocks_per_slice;
  superblock->journal_slices = static_cast<uint32_t>(length);
  status = device->VolumeExtend(offset, superblock->journal_slices);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "mkfs: Failed to allocate journal blocks";
    return status;
  }

  // Allocate the minimum number of data blocks in the FVM.
  offset = kFVMDataStart / blocks_per_slice;
  length = fbl::round_up(kMinimumDataBlocks, blocks_per_slice) / blocks_per_slice;
  superblock->dat_slices = static_cast<uint32_t>(length);
  status = device->VolumeExtend(offset, superblock->dat_slices);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "mkfs: Failed to allocate data blocks";
    return status;
  }

  superblock->inode_count =
      static_cast<uint32_t>(superblock->ino_slices * superblock->slice_size / kBlobfsInodeSize);

  superblock->data_block_count =
      static_cast<uint32_t>(superblock->dat_slices * superblock->slice_size / kBlobfsBlockSize);
  superblock->journal_block_count =
      static_cast<uint32_t>(superblock->journal_slices * superblock->slice_size / kBlobfsBlockSize);
  return ZX_OK;
}

// Take the contents of the filesystem, generated in-memory, and transfer
// them to the underlying device.
zx_status_t WriteFilesystemToDisk(BlockDevice* device, const Superblock& superblock,
                                  const RawBitmap& block_bitmap,
                                  const fuchsia_hardware_block_BlockInfo& block_info) {
  uint64_t blockmap_blocks = BlockMapBlocks(superblock);
  uint64_t nodemap_blocks = NodeMapBlocks(superblock);

  // All in-memory structures have been created successfully. Dump everything to disk.
  uint64_t superblock_blocks = SuperblockBlocks(superblock);
  uint64_t journal_blocks = JournalBlocks(superblock);
  uint64_t total_blocks = superblock_blocks + blockmap_blocks + nodemap_blocks + journal_blocks;

  zx::vmo vmo;
  zx_status_t status = zx::vmo::create(kBlobfsBlockSize * total_blocks, 0, &vmo);
  if (status != ZX_OK) {
    return status;
  }

  storage::OwnedVmoid vmoid;
  status = device->BlockAttachVmo(vmo, &vmoid.GetReference(device));
  if (status != ZX_OK) {
    return status;
  }

  // Write the root block.
  status = vmo.write(&superblock, 0, kBlobfsBlockSize);
  if (status != ZX_OK) {
    return status;
  }

  // Write allocation bitmap.
  for (uint64_t n = 0; n < blockmap_blocks; n++) {
    uint64_t offset = kBlobfsBlockSize * (superblock_blocks + n);
    uint64_t length = kBlobfsBlockSize;
    status = vmo.write(GetRawBitmapData(block_bitmap, n), offset, length);
    if (status != ZX_OK) {
      return status;
    }
  }

  // Write node map.
  uint8_t block[kBlobfsBlockSize];
  memset(block, 0, sizeof(block));
  for (uint64_t n = 0; n < nodemap_blocks; n++) {
    uint64_t offset = kBlobfsBlockSize * (superblock_blocks + blockmap_blocks + n);
    uint64_t length = kBlobfsBlockSize;
    status = vmo.write(block, offset, length);
    if (status != ZX_OK) {
      return status;
    }
  }

  // Write the journal.

  auto base_offset = superblock_blocks + blockmap_blocks + nodemap_blocks;
  fs::WriteBlocksFn write_blocks_fn = [&vmo, &superblock, base_offset](
                                          fbl::Span<const uint8_t> buffer, uint64_t block_offset,
                                          uint64_t block_count) {
    uint64_t offset =
        safemath::CheckMul<uint64_t>(safemath::CheckAdd(base_offset, block_offset).ValueOrDie(),
                                     kBlobfsBlockSize)
            .ValueOrDie();
    uint64_t size = safemath::CheckMul<uint64_t>(block_count, kBlobfsBlockSize).ValueOrDie();
    ZX_ASSERT((block_offset + block_count) <= JournalBlocks(superblock));
    ZX_ASSERT(buffer.size() >= size);
    return vmo.write(buffer.data(), offset, size);
  };
  status = fs::MakeJournal(journal_blocks, write_blocks_fn);
  if (status != ZX_OK) {
    return status;
  }

  auto FsToDeviceBlocks = [disk_block = block_info.block_size](uint64_t block) {
    return block * (kBlobfsBlockSize / disk_block);
  };

  block_fifo_request_t requests[4] = {};
  requests[0].opcode = BLOCKIO_WRITE;
  requests[0].vmoid = vmoid.get();
  requests[0].length = static_cast<uint32_t>(FsToDeviceBlocks(superblock_blocks));
  requests[0].vmo_offset = FsToDeviceBlocks(0);
  requests[0].dev_offset = FsToDeviceBlocks(0);

  requests[1].opcode = BLOCKIO_WRITE;
  requests[1].vmoid = vmoid.get();
  requests[1].length = static_cast<uint32_t>(FsToDeviceBlocks(blockmap_blocks));
  requests[1].vmo_offset = FsToDeviceBlocks(superblock_blocks);
  requests[1].dev_offset = FsToDeviceBlocks(BlockMapStartBlock(superblock));

  requests[2].opcode = BLOCKIO_WRITE;
  requests[2].vmoid = vmoid.get();
  requests[2].length = static_cast<uint32_t>(FsToDeviceBlocks(nodemap_blocks));
  requests[2].vmo_offset = FsToDeviceBlocks(superblock_blocks + blockmap_blocks);
  requests[2].dev_offset = FsToDeviceBlocks(NodeMapStartBlock(superblock));

  requests[3].opcode = BLOCKIO_WRITE;
  requests[3].vmoid = vmoid.get();
  requests[3].length = static_cast<uint32_t>(FsToDeviceBlocks(journal_blocks));
  requests[3].vmo_offset = FsToDeviceBlocks(superblock_blocks + blockmap_blocks + nodemap_blocks);
  requests[3].dev_offset = FsToDeviceBlocks(JournalStartBlock(superblock));

  return device->FifoTransaction(requests, std::size(requests));
}

}  // namespace

zx_status_t FormatFilesystem(BlockDevice* device, const FilesystemOptions& options) {
  zx_status_t status;
  fuchsia_hardware_block_BlockInfo block_info = {};
  status = device->BlockGetInfo(&block_info);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "cannot acquire block info: " << status;
    return status;
  }

  if (block_info.flags & BLOCK_FLAG_READONLY) {
    FX_LOGS(ERROR) << "cannot format read-only device";
    return ZX_ERR_ACCESS_DENIED;
  }
  if (block_info.block_size == 0 || block_info.block_count == 0) {
    return ZX_ERR_NO_SPACE;
  }
  if (kBlobfsBlockSize % block_info.block_size != 0) {
    return ZX_ERR_IO_INVALID;
  }

  uint64_t blocks = (block_info.block_size * block_info.block_count) / kBlobfsBlockSize;
  Superblock superblock;
  InitializeSuperblock(blocks, options, &superblock);

  status = TryFormattingFVM(device, &superblock);
  if (status != ZX_OK) {
    return status;
  }

  status = CheckSuperblock(&superblock, blocks);
  if (status != ZX_OK) {
    return status;
  }

  uint64_t blockmap_blocks = BlockMapBlocks(superblock);

  RawBitmap block_bitmap;
  if (block_bitmap.Reset(blockmap_blocks * kBlobfsBlockBits)) {
    FX_LOGS(ERROR) << "Couldn't allocate block map";
    return -1;
  }
  if (block_bitmap.Shrink(superblock.data_block_count)) {
    FX_LOGS(ERROR) << "Couldn't shrink block map";
    return -1;
  }

  // Reserve first |kStartBlockMinimum| data blocks
  block_bitmap.Set(0, kStartBlockMinimum);

  status = WriteFilesystemToDisk(device, superblock, block_bitmap, block_info);
  if (status != ZX_OK) {
    FX_LOGS(ERROR) << "Failed to write to disk: " << status;
    return status;
  }

  FX_LOGS(DEBUG) << "mkfs success";
  return ZX_OK;
}

}  // namespace blobfs
