// 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 <fs/vfs.h>
#include <fdio/debug.h>
#include <fdio/io.fidl2.h>
#include <fdio/remoteio.h>
#include <fdio/vfs.h>

#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

// Sends an 'unmount' signal on the srv handle, and waits until it is closed.
// Consumes 'srv'.
zx_status_t vfs_unmount_handle(zx_handle_t srv, zx_time_t deadline) {
    // TODO(smklein): use shared ioctl impl?
#ifdef ZXRIO_FIDL
    uint8_t msg[FIDL_ALIGN(sizeof(NodeIoctlRequest)) + FDIO_CHUNK_SIZE];
    NodeIoctlRequest* request = (NodeIoctlRequest*) msg;
    NodeIoctlResponse* response = (NodeIoctlResponse*) msg;

    // the only other messages we ever send are no-reply OPEN or CLONE with
    // txid of 0.
    request->hdr.txid = 1;
    request->hdr.ordinal = ZXFIDL_IOCTL;
    request->opcode = IOCTL_VFS_UNMOUNT_FS;
    request->max_out = 0;
    request->handles.count = 0;
    request->handles.data = (void*) FIDL_ALLOC_PRESENT;
    request->in.count = 0;
    request->in.data = (void*) FIDL_ALLOC_PRESENT;

    zx_channel_call_args_t args;
    args.wr_bytes = request;
    args.wr_handles = NULL;
    args.rd_bytes = response;
    args.rd_handles = NULL;
    args.wr_num_bytes = FIDL_ALIGN(sizeof(NodeIoctlRequest));
    args.wr_num_handles = 0;
    args.rd_num_bytes = FIDL_ALIGN(sizeof(NodeIoctlResponse));
    args.rd_num_handles = 0;

    uint32_t dsize;
    uint32_t hcount;
    zx_status_t rs;

    // At the moment, we don't actually care what the response is from the
    // filesystem server (or even if it supports the unmount operation). As
    // soon as ANY response comes back, either in the form of a closed handle
    // or a visible response, shut down.
    zx_status_t status = zx_channel_call(srv, 0, deadline, &args, &dsize, &hcount, &rs);
    if (status == ZX_ERR_CALL_FAILED) {
        // Write phase succeeded. The target filesystem had a chance to unmount properly.
        status = ZX_OK;
    } else if (status == ZX_OK) {
        // Read phase succeeded. If the target filesystem returned an error, we
        // should parse it.
        if (dsize < FIDL_ALIGN(sizeof(NodeIoctlResponse))) {
            status = ZX_ERR_IO;
        } else {
            status = response->s;
        }
    }
#else
    zxrio_msg_t msg;
    memset(&msg, 0, ZXRIO_HDR_SZ);

    // the only other messages we ever send are no-reply OPEN or CLONE with
    // txid of 0.
    msg.txid = 1;
    msg.op = ZXRIO_IOCTL;
    msg.arg2.op = IOCTL_VFS_UNMOUNT_FS;

    zx_channel_call_args_t args;
    args.wr_bytes = &msg;
    args.wr_handles = NULL;
    args.rd_bytes = &msg;
    args.rd_handles = NULL;
    args.wr_num_bytes = ZXRIO_HDR_SZ;
    args.wr_num_handles = 0;
    args.rd_num_bytes = ZXRIO_HDR_SZ + FDIO_CHUNK_SIZE;
    args.rd_num_handles = 0;

    uint32_t dsize;
    uint32_t hcount;
    zx_status_t rs;

    // At the moment, we don't actually care what the response is from the
    // filesystem server (or even if it supports the unmount operation). As
    // soon as ANY response comes back, either in the form of a closed handle
    // or a visible response, shut down.
    zx_status_t status = zx_channel_call(srv, 0, deadline, &args, &dsize, &hcount, &rs);
    if (status == ZX_ERR_CALL_FAILED) {
        // Write phase succeeded. The target filesystem had a chance to unmount properly.
        status = ZX_OK;
    } else if (status == ZX_OK) {
        // Read phase succeeded. If the target filesystem returned an error, we
        // should parse it.
        if (dsize < ZXRIO_HDR_SZ) {
            status = ZX_ERR_IO;
        } else {
            status = msg.arg;
        }
    }
#endif
    zx_handle_close(srv);
    return status;
}
