// Copyright 2018 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 <fs-management/mount.h>

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>

#include <fbl/alloc_checker.h>
#include <fbl/auto_call.h>
#include <fbl/unique_fd.h>
#include <fbl/unique_ptr.h>
#include <fs-management/fvm.h>
#include <fs/client.h>
#include <fuchsia/hardware/block/c/fidl.h>
#include <fuchsia/hardware/block/partition/c/fidl.h>
#include <fuchsia/hardware/block/volume/c/fidl.h>
#include <fvm/format.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/limits.h>
#include <lib/fdio/vfs.h>
#include <lib/fdio/watcher.h>
#include <lib/fzl/fdio.h>
#include <zircon/compiler.h>
#include <zircon/device/block.h>
#include <zircon/device/vfs.h>
#include <zircon/processargs.h>
#include <zircon/syscalls.h>

#include <utility>

namespace {
// Checks that |fd| is a partition which matches |uniqueGUID| and |typeGUID|.
// If either is null, it doesn't compare |fd| with that guid.
// At least one of the GUIDs must be non-null.
bool IsPartition(const fbl::unique_fd& fd, const uint8_t* uniqueGUID, const uint8_t* typeGUID) {
    ZX_ASSERT(uniqueGUID || typeGUID);

    fuchsia_hardware_block_partition_GUID guid;
    fzl::UnownedFdioCaller partition_connection(fd.get());
    zx::unowned_channel channel(partition_connection.borrow_channel());
    zx_status_t io_status, status;
    if (typeGUID) {
        io_status =
            fuchsia_hardware_block_partition_PartitionGetTypeGuid(channel->get(), &status, &guid);
        if (io_status != ZX_OK || status != ZX_OK || memcmp(guid.value, typeGUID, GUID_LEN) != 0) {
            return false;
        }
    }
    if (uniqueGUID) {
        io_status = fuchsia_hardware_block_partition_PartitionGetInstanceGuid(channel->get(),
                                                                              &status, &guid);
        if (io_status != ZX_OK || status != ZX_OK ||
            memcmp(guid.value, uniqueGUID, GUID_LEN) != 0) {
            return false;
        }
    }
    return true;
}

constexpr char kBlockDevPath[] = "/dev/class/block/";
constexpr char kBlockDevRelativePath[] = "class/block/";

} // namespace

zx_status_t fvm_init_preallocated(int fd, uint64_t initial_volume_size, uint64_t max_volume_size,
                                  size_t slice_size) {
    if (slice_size % fvm::kBlockSize != 0) {
        // Alignment
        return ZX_ERR_INVALID_ARGS;
    } else if ((slice_size * fvm::kMaxVSlices) / fvm::kMaxVSlices != slice_size) {
        // Overflow
        return ZX_ERR_INVALID_ARGS;
    } else if (initial_volume_size > max_volume_size || initial_volume_size == 0 ||
               max_volume_size == 0) {
        return ZX_ERR_INVALID_ARGS;
    }

    fvm::FormatInfo format_info =
        fvm::FormatInfo::FromPreallocatedSize(initial_volume_size, max_volume_size, slice_size);

    fbl::unique_ptr<uint8_t[]> mvmo(new uint8_t[format_info.metadata_allocated_size() * 2]);
    // Clear entire primary copy of metadata
    memset(mvmo.get(), 0, format_info.metadata_allocated_size());

    // Superblock
    fvm::fvm_t* sb = reinterpret_cast<fvm::fvm_t*>(mvmo.get());
    sb->magic = fvm::kMagic;
    sb->version = fvm::kVersion;
    sb->pslice_count = format_info.slice_count();
    sb->slice_size = slice_size;
    sb->fvm_partition_size = initial_volume_size;
    sb->vpartition_table_size = fvm::kVPartTableLength;
    sb->allocation_table_size = fvm::AllocTableLength(max_volume_size, slice_size);
    sb->generation = 0;

    if (sb->pslice_count == 0) {
        return ZX_ERR_NO_SPACE;
    }

    fvm_update_hash(mvmo.get(), format_info.metadata_size());

    void* backup = mvmo.get() + format_info.GetSuperblockOffset(fvm::SuperblockType::kSecondary);
    memcpy(backup, mvmo.get(), format_info.metadata_size());

    zx_status_t status =
        fvm_validate_header(mvmo.get(), backup, format_info.metadata_size(), nullptr);
    if (status != ZX_OK) {
        return status;
    }

    if (lseek(fd, 0, SEEK_SET) < 0) {
        return ZX_ERR_BAD_STATE;
    }
    // Write to primary copy.
    if (write(fd, mvmo.get(), format_info.metadata_allocated_size()) !=
        static_cast<ssize_t>(format_info.metadata_allocated_size())) {
        return ZX_ERR_BAD_STATE;
    }
    // Write to secondary copy, to overwrite any previous FVM metadata copy that
    // could be here.
    if (write(fd, mvmo.get(), format_info.metadata_allocated_size()) !=
        static_cast<ssize_t>(format_info.metadata_allocated_size())) {
        return ZX_ERR_BAD_STATE;
    }

    return ZX_OK;
}

zx_status_t fvm_init_with_size(int fd, uint64_t volume_size, size_t slice_size) {
    return fvm_init_preallocated(fd, volume_size, volume_size, slice_size);
}

zx_status_t fvm_init(int fd, size_t slice_size) {
    // The metadata layout of the FVM is dependent on the
    // size of the FVM's underlying partition.
    fuchsia_hardware_block_BlockInfo block_info;
    fzl::UnownedFdioCaller disk_connection(fd);
    zx_status_t status;
    zx_status_t io_status =
        fuchsia_hardware_block_BlockGetInfo(disk_connection.borrow_channel(), &status, &block_info);
    if (io_status != ZX_OK) {
        return io_status;
    } else if (status != ZX_OK) {
        return status;
    } else if (slice_size == 0 || slice_size % block_info.block_size) {
        return ZX_ERR_BAD_STATE;
    }

    return fvm_init_with_size(fd, block_info.block_count * block_info.block_size, slice_size);
}

// Helper function to overwrite FVM given the slice_size
zx_status_t fvm_overwrite_impl(const fbl::unique_fd& fd, size_t slice_size) {
    fuchsia_hardware_block_BlockInfo block_info;
    fzl::UnownedFdioCaller disk_connection(fd.get());
    zx::unowned_channel channel(disk_connection.borrow_channel());
    zx_status_t status;
    zx_status_t io_status =
        fuchsia_hardware_block_BlockGetInfo(channel->get(), &status, &block_info);
    if (io_status != ZX_OK) {
        return io_status;
    } else if (status != ZX_OK) {
        return status;
    }

    size_t disk_size = block_info.block_count * block_info.block_size;
    size_t metadata_size = fvm::MetadataSize(disk_size, slice_size);

    fbl::unique_ptr<uint8_t[]> buf(new uint8_t[metadata_size]);

    memset(buf.get(), 0, metadata_size);

    if (lseek(fd.get(), 0, SEEK_SET) < 0) {
        return ZX_ERR_IO;
    }

    // Write to primary copy.
    if (write(fd.get(), buf.get(), metadata_size) != static_cast<ssize_t>(metadata_size)) {
        fprintf(stderr, "fvm_overwrite_impl: Failed to write metadata\n");
        return ZX_ERR_IO;
    }

    // Write to backup copy
    if (write(fd.get(), buf.get(), metadata_size) != static_cast<ssize_t>(metadata_size)) {
        fprintf(stderr, "fvm_overwrite_impl: Failed to write metadata (secondary)\n");
        return ZX_ERR_IO;
    }

    io_status = fuchsia_hardware_block_BlockRebindDevice(channel->get(), &status);
    if (io_status != ZX_OK) {
        return io_status;
    }
    return status;
}

zx_status_t fvm_overwrite(const char* path, size_t slice_size) {
    fbl::unique_fd fd(open(path, O_RDWR));
    if (!fd) {
        fprintf(stderr, "fvm_overwrite: Failed to open block device\n");
        return ZX_ERR_BAD_STATE;
    }
    return fvm_overwrite_impl(fd, slice_size);
}

zx_status_t fvm_overwrite_with_devfs(int devfs_root_fd, const char* relative_path,
                                     size_t slice_size) {
    fbl::unique_fd fd(openat(devfs_root_fd, relative_path, O_RDWR));
    if (!fd) {
        fprintf(stderr, "fvm_overwrite_with_devfs: Failed to open block device\n");
        return ZX_ERR_BAD_STATE;
    }
    return fvm_overwrite_impl(fd, slice_size);
}

// Helper function to destroy FVM
zx_status_t fvm_destroy(const char* path) {
    char driver_path[PATH_MAX];
    if (strlcpy(driver_path, path, sizeof(driver_path)) >= sizeof(driver_path)) {
        return ZX_ERR_BAD_PATH;
    }
    if (strlcat(driver_path, "/fvm", sizeof(driver_path)) >= sizeof(driver_path)) {
        return ZX_ERR_BAD_PATH;
    }
    fbl::unique_fd driver_fd(open(driver_path, O_RDWR));

    if (!driver_fd) {
        fprintf(stderr, "fvm_destroy: Failed to open fvm driver: %s\n", driver_path);
        return -1;
    }

    fuchsia_hardware_block_volume_VolumeInfo volume_info;
    zx_status_t status = fvm_query(driver_fd.get(), &volume_info);
    if (status != ZX_OK) {
        fprintf(stderr, "fvm_destroy: Failed to query fvm: %d\n", status);
        return -1;
    }
    return fvm_overwrite(path, volume_info.slice_size);
}

zx_status_t fvm_destroy_with_devfs(int devfs_root_fd, const char* relative_path) {
    char driver_path[PATH_MAX];
    if (strlcpy(driver_path, relative_path, sizeof(driver_path)) >= sizeof(driver_path)) {
        return ZX_ERR_BAD_PATH;
    }
    if (strlcat(driver_path, "/fvm", sizeof(driver_path)) >= sizeof(driver_path)) {
        return ZX_ERR_BAD_PATH;
    }
    fbl::unique_fd driver_fd(openat(devfs_root_fd, driver_path, O_RDWR));

    if (!driver_fd) {
        fprintf(stderr, "fvm_destroy_with_devfs: Failed to open fvm driver: %s\n", driver_path);
        return -1;
    }

    fuchsia_hardware_block_volume_VolumeInfo volume_info;
    zx_status_t status = fvm_query(driver_fd.get(), &volume_info);
    if (status != ZX_OK) {
        fprintf(stderr, "fvm_destroy_with_devfs: Failed to query fvm: %d\n", status);
        return -1;
    }
    return fvm_overwrite_with_devfs(devfs_root_fd, relative_path, volume_info.slice_size);
}

int fvm_allocate_partition_impl(int fvm_fd, const alloc_req_t* request) {
    fzl::UnownedFdioCaller caller(fvm_fd);

    fuchsia_hardware_block_partition_GUID type_guid;
    memcpy(type_guid.value, request->type, GUID_LEN);
    fuchsia_hardware_block_partition_GUID instance_guid;
    memcpy(instance_guid.value, request->guid, GUID_LEN);

    zx_status_t status;
    zx_status_t io_status = fuchsia_hardware_block_volume_VolumeManagerAllocatePartition(
        caller.borrow_channel(), request->slice_count, &type_guid, &instance_guid, request->name,
        NAME_LEN, request->flags, &status);
    if (io_status != ZX_OK || status != ZX_OK) {
        return -1;
    }
    return 0;
}

// Helper function to allocate, find, and open VPartition.
int fvm_allocate_partition(int fvm_fd, const alloc_req_t* request) {
    int alloc_status = fvm_allocate_partition_impl(fvm_fd, request);
    if (alloc_status != 0) {
        return alloc_status;
    }
    return open_partition(request->guid, request->type, ZX_SEC(10), nullptr);
}

int fvm_allocate_partition_with_devfs(int devfs_root_fd, int fvm_fd, const alloc_req_t* request) {
    int alloc_status = fvm_allocate_partition_impl(fvm_fd, request);
    if (alloc_status != 0) {
        return alloc_status;
    }
    return open_partition_with_devfs(devfs_root_fd, request->guid,
                                     request->type, ZX_SEC(10), nullptr);
}

zx_status_t fvm_query(int fvm_fd, fuchsia_hardware_block_volume_VolumeInfo* out) {
    fzl::UnownedFdioCaller caller(fvm_fd);

    zx_status_t status;
    zx_status_t io_status =
        fuchsia_hardware_block_volume_VolumeManagerQuery(caller.borrow_channel(), &status, out);
    if (io_status != ZX_OK) {
        return io_status;
    }
    return status;
}

// Takes ownership of |dir|.
int open_partition_impl(DIR* dir, const char* out_path_base, const uint8_t* uniqueGUID,
                        const uint8_t* typeGUID, zx_duration_t timeout, char* out_path) {
    typedef struct {
        const uint8_t* guid;
        const uint8_t* type;
        const char* out_path_base;
        char* out_path;
        fbl::unique_fd out_partition;
    } alloc_helper_info_t;

    alloc_helper_info_t info;
    info.guid = uniqueGUID;
    info.type = typeGUID;
    info.out_path_base = out_path_base;
    info.out_path = out_path;
    info.out_partition.reset();

    auto cb = [](int dirfd, int event, const char* fn, void* cookie) {
        if (event != WATCH_EVENT_ADD_FILE) {
            return ZX_OK;
        } else if ((strcmp(fn, ".") == 0) || strcmp(fn, "..") == 0) {
            return ZX_OK;
        }
        auto info = static_cast<alloc_helper_info_t*>(cookie);
        fbl::unique_fd devfd(openat(dirfd, fn, O_RDWR));
        if (!devfd) {
            return ZX_OK;
        }
        if (IsPartition(devfd, info->guid, info->type)) {
            info->out_partition = std::move(devfd);
            if (info->out_path) {
                strcpy(info->out_path, info->out_path_base);
                strcat(info->out_path, fn);
            }
            return ZX_ERR_STOP;
        }
        return ZX_OK;
    };

    zx_time_t deadline = zx_deadline_after(timeout);
    if (fdio_watch_directory(dirfd(dir), cb, deadline, &info) != ZX_ERR_STOP) {
        return -1;
    }
    closedir(dir);
    return info.out_partition.release();
}

int open_partition(const uint8_t* uniqueGUID, const uint8_t* typeGUID, zx_duration_t timeout,
                   char* out_path) {
    ZX_ASSERT(uniqueGUID || typeGUID);

    DIR* dir = opendir(kBlockDevPath);
    if (dir == nullptr) {
        return -1;
    }

    return open_partition_impl(dir, kBlockDevPath, uniqueGUID, typeGUID, timeout, out_path);
}

int open_partition_with_devfs(int devfs_root_fd, const uint8_t* uniqueGUID,
                              const uint8_t* typeGUID, zx_duration_t timeout,
                              char* out_path_relative) {
    ZX_ASSERT(uniqueGUID || typeGUID);
    fbl::unique_fd block_dev_fd(openat(devfs_root_fd, kBlockDevRelativePath, O_RDONLY));
    if (!block_dev_fd) {
        return -1;
    }
    DIR* dir = fdopendir(block_dev_fd.get());
    if (dir == nullptr) {
        return -1;
    }

    return open_partition_impl(dir, kBlockDevRelativePath, uniqueGUID, typeGUID,
                               timeout, out_path_relative);
}

zx_status_t destroy_partition_impl(fbl::unique_fd&& fd) {
    fzl::FdioCaller partition_caller(std::move(fd));

    zx_status_t status;
    zx_status_t io_status =
        fuchsia_hardware_block_volume_VolumeDestroy(partition_caller.borrow_channel(), &status);
    if (io_status) {
        return io_status;
    }
    return status;
}

zx_status_t destroy_partition(const uint8_t* uniqueGUID, const uint8_t* typeGUID) {
    char path[PATH_MAX];
    fbl::unique_fd fd(open_partition(uniqueGUID, typeGUID, 0, path));
    if (!fd) {
        return ZX_ERR_IO;
    }
    return destroy_partition_impl(std::move(fd));
}

zx_status_t destroy_partition_with_devfs(int devfs_root_fd, const uint8_t* uniqueGUID,
                                         const uint8_t* typeGUID) {
    char relative_path[PATH_MAX];
    fbl::unique_fd fd(open_partition_with_devfs(devfs_root_fd, uniqueGUID,
                                                typeGUID, 0, relative_path));
    if (!fd) {
        return ZX_ERR_IO;
    }
    return destroy_partition_impl(std::move(fd));
}
