// 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 "src/storage/blobfs/format.h"

#include <lib/cksum.h>
#include <lib/syslog/cpp/macros.h>

#include <iterator>
#include <utility>

#include <fbl/ref_ptr.h>
#include <fs/journal/initializer.h>
#include <safemath/checked_math.h>
#include <storage/buffer/owned_vmoid.h>

#include "src/storage/blobfs/common.h"
#include "src/storage/blobfs/mkfs.h"
#include "src/storage/fvm/client.h"

namespace blobfs {
namespace {

using ::block_client::BlockDevice;

// 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[5] = {};
  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));

  int count = 4;
  if (superblock.flags & kBlobFlagFVM) {
    requests[4].opcode = BLOCKIO_WRITE;
    requests[4].vmoid = vmoid.get();
    requests[4].length = static_cast<uint32_t>(FsToDeviceBlocks(superblock_blocks));
    requests[4].vmo_offset = FsToDeviceBlocks(0);
    requests[4].dev_offset = FsToDeviceBlocks(kFVMBackupSuperblockOffset);
    ++count;
  }

  status = device->FifoTransaction(requests, count);
  if (status != ZX_OK)
    return status;

  block_fifo_request_t flush_request = {.opcode = BLOCKIO_FLUSH};
  return device->FifoTransaction(&flush_request, 1);
}

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