/*
 * Copyright (C) 2009-2010 Nippon Telegraph and Telephone Corporation.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 as published by the Free Software Foundation.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 * Contributions after 2012-01-13 are licensed under the terms of the
 * GNU GPL, version 2 or (at your option) any later version.
 */

#include "qemu-common.h"
#include "qemu-error.h"
#include "qemu_socket.h"
#include "block_int.h"
#include "bitops.h"

#define SD_PROTO_VER 0x01

#define SD_DEFAULT_ADDR "localhost"
#define SD_DEFAULT_PORT "7000"

#define SD_OP_CREATE_AND_WRITE_OBJ  0x01
#define SD_OP_READ_OBJ       0x02
#define SD_OP_WRITE_OBJ      0x03

#define SD_OP_NEW_VDI        0x11
#define SD_OP_LOCK_VDI       0x12
#define SD_OP_RELEASE_VDI    0x13
#define SD_OP_GET_VDI_INFO   0x14
#define SD_OP_READ_VDIS      0x15
#define SD_OP_FLUSH_VDI      0x16

#define SD_FLAG_CMD_WRITE    0x01
#define SD_FLAG_CMD_COW      0x02
#define SD_FLAG_CMD_CACHE    0x04

#define SD_RES_SUCCESS       0x00 /* Success */
#define SD_RES_UNKNOWN       0x01 /* Unknown error */
#define SD_RES_NO_OBJ        0x02 /* No object found */
#define SD_RES_EIO           0x03 /* I/O error */
#define SD_RES_VDI_EXIST     0x04 /* Vdi exists already */
#define SD_RES_INVALID_PARMS 0x05 /* Invalid parameters */
#define SD_RES_SYSTEM_ERROR  0x06 /* System error */
#define SD_RES_VDI_LOCKED    0x07 /* Vdi is locked */
#define SD_RES_NO_VDI        0x08 /* No vdi found */
#define SD_RES_NO_BASE_VDI   0x09 /* No base vdi found */
#define SD_RES_VDI_READ      0x0A /* Cannot read requested vdi */
#define SD_RES_VDI_WRITE     0x0B /* Cannot write requested vdi */
#define SD_RES_BASE_VDI_READ 0x0C /* Cannot read base vdi */
#define SD_RES_BASE_VDI_WRITE   0x0D /* Cannot write base vdi */
#define SD_RES_NO_TAG        0x0E /* Requested tag is not found */
#define SD_RES_STARTUP       0x0F /* Sheepdog is on starting up */
#define SD_RES_VDI_NOT_LOCKED   0x10 /* Vdi is not locked */
#define SD_RES_SHUTDOWN      0x11 /* Sheepdog is shutting down */
#define SD_RES_NO_MEM        0x12 /* Cannot allocate memory */
#define SD_RES_FULL_VDI      0x13 /* we already have the maximum vdis */
#define SD_RES_VER_MISMATCH  0x14 /* Protocol version mismatch */
#define SD_RES_NO_SPACE      0x15 /* Server has no room for new objects */
#define SD_RES_WAIT_FOR_FORMAT  0x16 /* Waiting for a format operation */
#define SD_RES_WAIT_FOR_JOIN    0x17 /* Waiting for other nodes joining */
#define SD_RES_JOIN_FAILED   0x18 /* Target node had failed to join sheepdog */

/*
 * Object ID rules
 *
 *  0 - 19 (20 bits): data object space
 * 20 - 31 (12 bits): reserved data object space
 * 32 - 55 (24 bits): vdi object space
 * 56 - 59 ( 4 bits): reserved vdi object space
 * 60 - 63 ( 4 bits): object type identifier space
 */

#define VDI_SPACE_SHIFT   32
#define VDI_BIT (UINT64_C(1) << 63)
#define VMSTATE_BIT (UINT64_C(1) << 62)
#define MAX_DATA_OBJS (UINT64_C(1) << 20)
#define MAX_CHILDREN 1024
#define SD_MAX_VDI_LEN 256
#define SD_MAX_VDI_TAG_LEN 256
#define SD_NR_VDIS   (1U << 24)
#define SD_DATA_OBJ_SIZE (UINT64_C(1) << 22)
#define SD_MAX_VDI_SIZE (SD_DATA_OBJ_SIZE * MAX_DATA_OBJS)
#define SECTOR_SIZE 512

#define SD_INODE_SIZE (sizeof(SheepdogInode))
#define CURRENT_VDI_ID 0

typedef struct SheepdogReq {
    uint8_t proto_ver;
    uint8_t opcode;
    uint16_t flags;
    uint32_t epoch;
    uint32_t id;
    uint32_t data_length;
    uint32_t opcode_specific[8];
} SheepdogReq;

typedef struct SheepdogRsp {
    uint8_t proto_ver;
    uint8_t opcode;
    uint16_t flags;
    uint32_t epoch;
    uint32_t id;
    uint32_t data_length;
    uint32_t result;
    uint32_t opcode_specific[7];
} SheepdogRsp;

typedef struct SheepdogObjReq {
    uint8_t proto_ver;
    uint8_t opcode;
    uint16_t flags;
    uint32_t epoch;
    uint32_t id;
    uint32_t data_length;
    uint64_t oid;
    uint64_t cow_oid;
    uint32_t copies;
    uint32_t rsvd;
    uint64_t offset;
} SheepdogObjReq;

typedef struct SheepdogObjRsp {
    uint8_t proto_ver;
    uint8_t opcode;
    uint16_t flags;
    uint32_t epoch;
    uint32_t id;
    uint32_t data_length;
    uint32_t result;
    uint32_t copies;
    uint32_t pad[6];
} SheepdogObjRsp;

typedef struct SheepdogVdiReq {
    uint8_t proto_ver;
    uint8_t opcode;
    uint16_t flags;
    uint32_t epoch;
    uint32_t id;
    uint32_t data_length;
    uint64_t vdi_size;
    uint32_t base_vdi_id;
    uint32_t copies;
    uint32_t snapid;
    uint32_t pad[3];
} SheepdogVdiReq;

typedef struct SheepdogVdiRsp {
    uint8_t proto_ver;
    uint8_t opcode;
    uint16_t flags;
    uint32_t epoch;
    uint32_t id;
    uint32_t data_length;
    uint32_t result;
    uint32_t rsvd;
    uint32_t vdi_id;
    uint32_t pad[5];
} SheepdogVdiRsp;

typedef struct SheepdogInode {
    char name[SD_MAX_VDI_LEN];
    char tag[SD_MAX_VDI_TAG_LEN];
    uint64_t ctime;
    uint64_t snap_ctime;
    uint64_t vm_clock_nsec;
    uint64_t vdi_size;
    uint64_t vm_state_size;
    uint16_t copy_policy;
    uint8_t nr_copies;
    uint8_t block_size_shift;
    uint32_t snap_id;
    uint32_t vdi_id;
    uint32_t parent_vdi_id;
    uint32_t child_vdi_id[MAX_CHILDREN];
    uint32_t data_vdi_id[MAX_DATA_OBJS];
} SheepdogInode;

/*
 * 64 bit FNV-1a non-zero initial basis
 */
#define FNV1A_64_INIT ((uint64_t)0xcbf29ce484222325ULL)

/*
 * 64 bit Fowler/Noll/Vo FNV-1a hash code
 */
static inline uint64_t fnv_64a_buf(void *buf, size_t len, uint64_t hval)
{
    unsigned char *bp = buf;
    unsigned char *be = bp + len;
    while (bp < be) {
        hval ^= (uint64_t) *bp++;
        hval += (hval << 1) + (hval << 4) + (hval << 5) +
            (hval << 7) + (hval << 8) + (hval << 40);
    }
    return hval;
}

static inline int is_data_obj_writable(SheepdogInode *inode, unsigned int idx)
{
    return inode->vdi_id == inode->data_vdi_id[idx];
}

static inline int is_data_obj(uint64_t oid)
{
    return !(VDI_BIT & oid);
}

static inline uint64_t data_oid_to_idx(uint64_t oid)
{
    return oid & (MAX_DATA_OBJS - 1);
}

static inline uint64_t vid_to_vdi_oid(uint32_t vid)
{
    return VDI_BIT | ((uint64_t)vid << VDI_SPACE_SHIFT);
}

static inline uint64_t vid_to_vmstate_oid(uint32_t vid, uint32_t idx)
{
    return VMSTATE_BIT | ((uint64_t)vid << VDI_SPACE_SHIFT) | idx;
}

static inline uint64_t vid_to_data_oid(uint32_t vid, uint32_t idx)
{
    return ((uint64_t)vid << VDI_SPACE_SHIFT) | idx;
}

static inline int is_snapshot(struct SheepdogInode *inode)
{
    return !!inode->snap_ctime;
}

#undef dprintf
#ifdef DEBUG_SDOG
#define dprintf(fmt, args...)                                       \
    do {                                                            \
        fprintf(stdout, "%s %d: " fmt, __func__, __LINE__, ##args); \
    } while (0)
#else
#define dprintf(fmt, args...)
#endif

typedef struct SheepdogAIOCB SheepdogAIOCB;

typedef struct AIOReq {
    SheepdogAIOCB *aiocb;
    unsigned int iov_offset;

    uint64_t oid;
    uint64_t base_oid;
    uint64_t offset;
    unsigned int data_len;
    uint8_t flags;
    uint32_t id;

    QLIST_ENTRY(AIOReq) aio_siblings;
} AIOReq;

enum AIOCBState {
    AIOCB_WRITE_UDATA,
    AIOCB_READ_UDATA,
};

struct SheepdogAIOCB {
    BlockDriverAIOCB common;

    QEMUIOVector *qiov;

    int64_t sector_num;
    int nb_sectors;

    int ret;
    enum AIOCBState aiocb_type;

    Coroutine *coroutine;
    void (*aio_done_func)(SheepdogAIOCB *);

    int canceled;
    int nr_pending;
};

typedef struct BDRVSheepdogState {
    SheepdogInode inode;

    uint32_t min_dirty_data_idx;
    uint32_t max_dirty_data_idx;

    char name[SD_MAX_VDI_LEN];
    int is_snapshot;
    uint8_t cache_enabled;

    char *addr;
    char *port;
    int fd;
    int flush_fd;

    CoMutex lock;
    Coroutine *co_send;
    Coroutine *co_recv;

    uint32_t aioreq_seq_num;
    QLIST_HEAD(inflight_aio_head, AIOReq) inflight_aio_head;
    QLIST_HEAD(pending_aio_head, AIOReq) pending_aio_head;
} BDRVSheepdogState;

static const char * sd_strerror(int err)
{
    int i;

    static const struct {
        int err;
        const char *desc;
    } errors[] = {
        {SD_RES_SUCCESS, "Success"},
        {SD_RES_UNKNOWN, "Unknown error"},
        {SD_RES_NO_OBJ, "No object found"},
        {SD_RES_EIO, "I/O error"},
        {SD_RES_VDI_EXIST, "VDI exists already"},
        {SD_RES_INVALID_PARMS, "Invalid parameters"},
        {SD_RES_SYSTEM_ERROR, "System error"},
        {SD_RES_VDI_LOCKED, "VDI is already locked"},
        {SD_RES_NO_VDI, "No vdi found"},
        {SD_RES_NO_BASE_VDI, "No base VDI found"},
        {SD_RES_VDI_READ, "Failed read the requested VDI"},
        {SD_RES_VDI_WRITE, "Failed to write the requested VDI"},
        {SD_RES_BASE_VDI_READ, "Failed to read the base VDI"},
        {SD_RES_BASE_VDI_WRITE, "Failed to write the base VDI"},
        {SD_RES_NO_TAG, "Failed to find the requested tag"},
        {SD_RES_STARTUP, "The system is still booting"},
        {SD_RES_VDI_NOT_LOCKED, "VDI isn't locked"},
        {SD_RES_SHUTDOWN, "The system is shutting down"},
        {SD_RES_NO_MEM, "Out of memory on the server"},
        {SD_RES_FULL_VDI, "We already have the maximum vdis"},
        {SD_RES_VER_MISMATCH, "Protocol version mismatch"},
        {SD_RES_NO_SPACE, "Server has no space for new objects"},
        {SD_RES_WAIT_FOR_FORMAT, "Sheepdog is waiting for a format operation"},
        {SD_RES_WAIT_FOR_JOIN, "Sheepdog is waiting for other nodes joining"},
        {SD_RES_JOIN_FAILED, "Target node had failed to join sheepdog"},
    };

    for (i = 0; i < ARRAY_SIZE(errors); ++i) {
        if (errors[i].err == err) {
            return errors[i].desc;
        }
    }

    return "Invalid error code";
}

/*
 * Sheepdog I/O handling:
 *
 * 1. In sd_co_rw_vector, we send the I/O requests to the server and
 *    link the requests to the inflight_list in the
 *    BDRVSheepdogState.  The function exits without waiting for
 *    receiving the response.
 *
 * 2. We receive the response in aio_read_response, the fd handler to
 *    the sheepdog connection.  If metadata update is needed, we send
 *    the write request to the vdi object in sd_write_done, the write
 *    completion function.  We switch back to sd_co_readv/writev after
 *    all the requests belonging to the AIOCB are finished.
 */

static inline AIOReq *alloc_aio_req(BDRVSheepdogState *s, SheepdogAIOCB *acb,
                                    uint64_t oid, unsigned int data_len,
                                    uint64_t offset, uint8_t flags,
                                    uint64_t base_oid, unsigned int iov_offset)
{
    AIOReq *aio_req;

    aio_req = g_malloc(sizeof(*aio_req));
    aio_req->aiocb = acb;
    aio_req->iov_offset = iov_offset;
    aio_req->oid = oid;
    aio_req->base_oid = base_oid;
    aio_req->offset = offset;
    aio_req->data_len = data_len;
    aio_req->flags = flags;
    aio_req->id = s->aioreq_seq_num++;

    acb->nr_pending++;
    return aio_req;
}

static inline void free_aio_req(BDRVSheepdogState *s, AIOReq *aio_req)
{
    SheepdogAIOCB *acb = aio_req->aiocb;

    QLIST_REMOVE(aio_req, aio_siblings);
    g_free(aio_req);

    acb->nr_pending--;
}

static void coroutine_fn sd_finish_aiocb(SheepdogAIOCB *acb)
{
    if (!acb->canceled) {
        qemu_coroutine_enter(acb->coroutine, NULL);
    }
    qemu_aio_release(acb);
}

static void sd_aio_cancel(BlockDriverAIOCB *blockacb)
{
    SheepdogAIOCB *acb = (SheepdogAIOCB *)blockacb;

    /*
     * Sheepdog cannot cancel the requests which are already sent to
     * the servers, so we just complete the request with -EIO here.
     */
    acb->ret = -EIO;
    qemu_coroutine_enter(acb->coroutine, NULL);
    acb->canceled = 1;
}

static AIOPool sd_aio_pool = {
    .aiocb_size = sizeof(SheepdogAIOCB),
    .cancel = sd_aio_cancel,
};

static SheepdogAIOCB *sd_aio_setup(BlockDriverState *bs, QEMUIOVector *qiov,
                                   int64_t sector_num, int nb_sectors,
                                   BlockDriverCompletionFunc *cb, void *opaque)
{
    SheepdogAIOCB *acb;

    acb = qemu_aio_get(&sd_aio_pool, bs, cb, opaque);

    acb->qiov = qiov;

    acb->sector_num = sector_num;
    acb->nb_sectors = nb_sectors;

    acb->aio_done_func = NULL;
    acb->canceled = 0;
    acb->coroutine = qemu_coroutine_self();
    acb->ret = 0;
    acb->nr_pending = 0;
    return acb;
}

static int connect_to_sdog(const char *addr, const char *port)
{
    char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
    int fd, ret;
    struct addrinfo hints, *res, *res0;

    if (!addr) {
        addr = SD_DEFAULT_ADDR;
        port = SD_DEFAULT_PORT;
    }

    memset(&hints, 0, sizeof(hints));
    hints.ai_socktype = SOCK_STREAM;

    ret = getaddrinfo(addr, port, &hints, &res0);
    if (ret) {
        error_report("unable to get address info %s, %s",
                     addr, strerror(errno));
        return -errno;
    }

    for (res = res0; res; res = res->ai_next) {
        ret = getnameinfo(res->ai_addr, res->ai_addrlen, hbuf, sizeof(hbuf),
                          sbuf, sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV);
        if (ret) {
            continue;
        }

        fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
        if (fd < 0) {
            continue;
        }

    reconnect:
        ret = connect(fd, res->ai_addr, res->ai_addrlen);
        if (ret < 0) {
            if (errno == EINTR) {
                goto reconnect;
            }
            break;
        }

        dprintf("connected to %s:%s\n", addr, port);
        goto success;
    }
    fd = -errno;
    error_report("failed connect to %s:%s", addr, port);
success:
    freeaddrinfo(res0);
    return fd;
}

static coroutine_fn int send_co_req(int sockfd, SheepdogReq *hdr, void *data,
                                    unsigned int *wlen)
{
    int ret;

    ret = qemu_co_send(sockfd, hdr, sizeof(*hdr));
    if (ret < sizeof(*hdr)) {
        error_report("failed to send a req, %s", strerror(errno));
        return ret;
    }

    ret = qemu_co_send(sockfd, data, *wlen);
    if (ret < *wlen) {
        error_report("failed to send a req, %s", strerror(errno));
    }

    return ret;
}

static void restart_co_req(void *opaque)
{
    Coroutine *co = opaque;

    qemu_coroutine_enter(co, NULL);
}

typedef struct SheepdogReqCo {
    int sockfd;
    SheepdogReq *hdr;
    void *data;
    unsigned int *wlen;
    unsigned int *rlen;
    int ret;
    bool finished;
} SheepdogReqCo;

static coroutine_fn void do_co_req(void *opaque)
{
    int ret;
    Coroutine *co;
    SheepdogReqCo *srco = opaque;
    int sockfd = srco->sockfd;
    SheepdogReq *hdr = srco->hdr;
    void *data = srco->data;
    unsigned int *wlen = srco->wlen;
    unsigned int *rlen = srco->rlen;

    co = qemu_coroutine_self();
    qemu_aio_set_fd_handler(sockfd, NULL, restart_co_req, NULL, co);

    socket_set_block(sockfd);
    ret = send_co_req(sockfd, hdr, data, wlen);
    if (ret < 0) {
        goto out;
    }

    qemu_aio_set_fd_handler(sockfd, restart_co_req, NULL, NULL, co);

    ret = qemu_co_recv(sockfd, hdr, sizeof(*hdr));
    if (ret < sizeof(*hdr)) {
        error_report("failed to get a rsp, %s", strerror(errno));
        ret = -errno;
        goto out;
    }

    if (*rlen > hdr->data_length) {
        *rlen = hdr->data_length;
    }

    if (*rlen) {
        ret = qemu_co_recv(sockfd, data, *rlen);
        if (ret < *rlen) {
            error_report("failed to get the data, %s", strerror(errno));
            ret = -errno;
            goto out;
        }
    }
    ret = 0;
out:
    qemu_aio_set_fd_handler(sockfd, NULL, NULL, NULL, NULL);
    socket_set_nonblock(sockfd);

    srco->ret = ret;
    srco->finished = true;
}

static int do_req(int sockfd, SheepdogReq *hdr, void *data,
                  unsigned int *wlen, unsigned int *rlen)
{
    Coroutine *co;
    SheepdogReqCo srco = {
        .sockfd = sockfd,
        .hdr = hdr,
        .data = data,
        .wlen = wlen,
        .rlen = rlen,
        .ret = 0,
        .finished = false,
    };

    if (qemu_in_coroutine()) {
        do_co_req(&srco);
    } else {
        co = qemu_coroutine_create(do_co_req);
        qemu_coroutine_enter(co, &srco);
        while (!srco.finished) {
            qemu_aio_wait();
        }
    }

    return srco.ret;
}

static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
                           struct iovec *iov, int niov, int create,
                           enum AIOCBState aiocb_type);


static AIOReq *find_pending_req(BDRVSheepdogState *s, uint64_t oid)
{
    AIOReq *aio_req;

    QLIST_FOREACH(aio_req, &s->pending_aio_head, aio_siblings) {
        if (aio_req->oid == oid) {
            return aio_req;
        }
    }

    return NULL;
}

/*
 * This function searchs pending requests to the object `oid', and
 * sends them.
 */
static void coroutine_fn send_pending_req(BDRVSheepdogState *s, uint64_t oid)
{
    AIOReq *aio_req;
    SheepdogAIOCB *acb;
    int ret;

    while ((aio_req = find_pending_req(s, oid)) != NULL) {
        acb = aio_req->aiocb;
        /* move aio_req from pending list to inflight one */
        QLIST_REMOVE(aio_req, aio_siblings);
        QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
        ret = add_aio_request(s, aio_req, acb->qiov->iov,
                              acb->qiov->niov, 0, acb->aiocb_type);
        if (ret < 0) {
            error_report("add_aio_request is failed");
            free_aio_req(s, aio_req);
            if (!acb->nr_pending) {
                sd_finish_aiocb(acb);
            }
        }
    }
}

/*
 * Receive responses of the I/O requests.
 *
 * This function is registered as a fd handler, and called from the
 * main loop when s->fd is ready for reading responses.
 */
static void coroutine_fn aio_read_response(void *opaque)
{
    SheepdogObjRsp rsp;
    BDRVSheepdogState *s = opaque;
    int fd = s->fd;
    int ret;
    AIOReq *aio_req = NULL;
    SheepdogAIOCB *acb;
    unsigned long idx;

    if (QLIST_EMPTY(&s->inflight_aio_head)) {
        goto out;
    }

    /* read a header */
    ret = qemu_co_recv(fd, &rsp, sizeof(rsp));
    if (ret < 0) {
        error_report("failed to get the header, %s", strerror(errno));
        goto out;
    }

    /* find the right aio_req from the inflight aio list */
    QLIST_FOREACH(aio_req, &s->inflight_aio_head, aio_siblings) {
        if (aio_req->id == rsp.id) {
            break;
        }
    }
    if (!aio_req) {
        error_report("cannot find aio_req %x", rsp.id);
        goto out;
    }

    acb = aio_req->aiocb;

    switch (acb->aiocb_type) {
    case AIOCB_WRITE_UDATA:
        /* this coroutine context is no longer suitable for co_recv
         * because we may send data to update vdi objects */
        s->co_recv = NULL;
        if (!is_data_obj(aio_req->oid)) {
            break;
        }
        idx = data_oid_to_idx(aio_req->oid);

        if (s->inode.data_vdi_id[idx] != s->inode.vdi_id) {
            /*
             * If the object is newly created one, we need to update
             * the vdi object (metadata object).  min_dirty_data_idx
             * and max_dirty_data_idx are changed to include updated
             * index between them.
             */
            s->inode.data_vdi_id[idx] = s->inode.vdi_id;
            s->max_dirty_data_idx = MAX(idx, s->max_dirty_data_idx);
            s->min_dirty_data_idx = MIN(idx, s->min_dirty_data_idx);

            /*
             * Some requests may be blocked because simultaneous
             * create requests are not allowed, so we search the
             * pending requests here.
             */
            send_pending_req(s, vid_to_data_oid(s->inode.vdi_id, idx));
        }
        break;
    case AIOCB_READ_UDATA:
        ret = qemu_co_recvv(fd, acb->qiov->iov, acb->qiov->niov,
                            aio_req->iov_offset, rsp.data_length);
        if (ret < 0) {
            error_report("failed to get the data, %s", strerror(errno));
            goto out;
        }
        break;
    }

    if (rsp.result != SD_RES_SUCCESS) {
        acb->ret = -EIO;
        error_report("%s", sd_strerror(rsp.result));
    }

    free_aio_req(s, aio_req);
    if (!acb->nr_pending) {
        /*
         * We've finished all requests which belong to the AIOCB, so
         * we can switch back to sd_co_readv/writev now.
         */
        acb->aio_done_func(acb);
    }
out:
    s->co_recv = NULL;
}

static void co_read_response(void *opaque)
{
    BDRVSheepdogState *s = opaque;

    if (!s->co_recv) {
        s->co_recv = qemu_coroutine_create(aio_read_response);
    }

    qemu_coroutine_enter(s->co_recv, opaque);
}

static void co_write_request(void *opaque)
{
    BDRVSheepdogState *s = opaque;

    qemu_coroutine_enter(s->co_send, NULL);
}

static int aio_flush_request(void *opaque)
{
    BDRVSheepdogState *s = opaque;

    return !QLIST_EMPTY(&s->inflight_aio_head) ||
        !QLIST_EMPTY(&s->pending_aio_head);
}

static int set_nodelay(int fd)
{
    int ret, opt;

    opt = 1;
    ret = setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&opt, sizeof(opt));
    return ret;
}

/*
 * Return a socket discriptor to read/write objects.
 *
 * We cannot use this discriptor for other operations because
 * the block driver may be on waiting response from the server.
 */
static int get_sheep_fd(BDRVSheepdogState *s)
{
    int ret, fd;

    fd = connect_to_sdog(s->addr, s->port);
    if (fd < 0) {
        error_report("%s", strerror(errno));
        return fd;
    }

    socket_set_nonblock(fd);

    ret = set_nodelay(fd);
    if (ret) {
        error_report("%s", strerror(errno));
        closesocket(fd);
        return -errno;
    }

    qemu_aio_set_fd_handler(fd, co_read_response, NULL, aio_flush_request, s);
    return fd;
}

/*
 * Parse a filename
 *
 * filename must be one of the following formats:
 *   1. [vdiname]
 *   2. [vdiname]:[snapid]
 *   3. [vdiname]:[tag]
 *   4. [hostname]:[port]:[vdiname]
 *   5. [hostname]:[port]:[vdiname]:[snapid]
 *   6. [hostname]:[port]:[vdiname]:[tag]
 *
 * You can boot from the snapshot images by specifying `snapid` or
 * `tag'.
 *
 * You can run VMs outside the Sheepdog cluster by specifying
 * `hostname' and `port' (experimental).
 */
static int parse_vdiname(BDRVSheepdogState *s, const char *filename,
                         char *vdi, uint32_t *snapid, char *tag)
{
    char *p, *q;
    int nr_sep;

    p = q = g_strdup(filename);

    /* count the number of separators */
    nr_sep = 0;
    while (*p) {
        if (*p == ':') {
            nr_sep++;
        }
        p++;
    }
    p = q;

    /* use the first two tokens as hostname and port number. */
    if (nr_sep >= 2) {
        s->addr = p;
        p = strchr(p, ':');
        *p++ = '\0';

        s->port = p;
        p = strchr(p, ':');
        *p++ = '\0';
    } else {
        s->addr = NULL;
        s->port = 0;
    }

    strncpy(vdi, p, SD_MAX_VDI_LEN);

    p = strchr(vdi, ':');
    if (p) {
        *p++ = '\0';
        *snapid = strtoul(p, NULL, 10);
        if (*snapid == 0) {
            strncpy(tag, p, SD_MAX_VDI_TAG_LEN);
        }
    } else {
        *snapid = CURRENT_VDI_ID; /* search current vdi */
    }

    if (s->addr == NULL) {
        g_free(q);
    }

    return 0;
}

static int find_vdi_name(BDRVSheepdogState *s, char *filename, uint32_t snapid,
                         char *tag, uint32_t *vid, int for_snapshot)
{
    int ret, fd;
    SheepdogVdiReq hdr;
    SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr;
    unsigned int wlen, rlen = 0;
    char buf[SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN];

    fd = connect_to_sdog(s->addr, s->port);
    if (fd < 0) {
        return fd;
    }

    memset(buf, 0, sizeof(buf));
    strncpy(buf, filename, SD_MAX_VDI_LEN);
    strncpy(buf + SD_MAX_VDI_LEN, tag, SD_MAX_VDI_TAG_LEN);

    memset(&hdr, 0, sizeof(hdr));
    if (for_snapshot) {
        hdr.opcode = SD_OP_GET_VDI_INFO;
    } else {
        hdr.opcode = SD_OP_LOCK_VDI;
    }
    wlen = SD_MAX_VDI_LEN + SD_MAX_VDI_TAG_LEN;
    hdr.proto_ver = SD_PROTO_VER;
    hdr.data_length = wlen;
    hdr.snapid = snapid;
    hdr.flags = SD_FLAG_CMD_WRITE;

    ret = do_req(fd, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
    if (ret) {
        goto out;
    }

    if (rsp->result != SD_RES_SUCCESS) {
        error_report("cannot get vdi info, %s, %s %d %s",
                     sd_strerror(rsp->result), filename, snapid, tag);
        if (rsp->result == SD_RES_NO_VDI) {
            ret = -ENOENT;
        } else {
            ret = -EIO;
        }
        goto out;
    }
    *vid = rsp->vdi_id;

    ret = 0;
out:
    closesocket(fd);
    return ret;
}

static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
                           struct iovec *iov, int niov, int create,
                           enum AIOCBState aiocb_type)
{
    int nr_copies = s->inode.nr_copies;
    SheepdogObjReq hdr;
    unsigned int wlen;
    int ret;
    uint64_t oid = aio_req->oid;
    unsigned int datalen = aio_req->data_len;
    uint64_t offset = aio_req->offset;
    uint8_t flags = aio_req->flags;
    uint64_t old_oid = aio_req->base_oid;

    if (!nr_copies) {
        error_report("bug");
    }

    memset(&hdr, 0, sizeof(hdr));

    if (aiocb_type == AIOCB_READ_UDATA) {
        wlen = 0;
        hdr.opcode = SD_OP_READ_OBJ;
        hdr.flags = flags;
    } else if (create) {
        wlen = datalen;
        hdr.opcode = SD_OP_CREATE_AND_WRITE_OBJ;
        hdr.flags = SD_FLAG_CMD_WRITE | flags;
    } else {
        wlen = datalen;
        hdr.opcode = SD_OP_WRITE_OBJ;
        hdr.flags = SD_FLAG_CMD_WRITE | flags;
    }

    if (s->cache_enabled) {
        hdr.flags |= SD_FLAG_CMD_CACHE;
    }

    hdr.oid = oid;
    hdr.cow_oid = old_oid;
    hdr.copies = s->inode.nr_copies;

    hdr.data_length = datalen;
    hdr.offset = offset;

    hdr.id = aio_req->id;

    qemu_co_mutex_lock(&s->lock);
    s->co_send = qemu_coroutine_self();
    qemu_aio_set_fd_handler(s->fd, co_read_response, co_write_request,
                            aio_flush_request, s);
    socket_set_cork(s->fd, 1);

    /* send a header */
    ret = qemu_co_send(s->fd, &hdr, sizeof(hdr));
    if (ret < 0) {
        qemu_co_mutex_unlock(&s->lock);
        error_report("failed to send a req, %s", strerror(errno));
        return -errno;
    }

    if (wlen) {
        ret = qemu_co_sendv(s->fd, iov, niov, aio_req->iov_offset, wlen);
        if (ret < 0) {
            qemu_co_mutex_unlock(&s->lock);
            error_report("failed to send a data, %s", strerror(errno));
            return -errno;
        }
    }

    socket_set_cork(s->fd, 0);
    qemu_aio_set_fd_handler(s->fd, co_read_response, NULL,
                            aio_flush_request, s);
    qemu_co_mutex_unlock(&s->lock);

    return 0;
}

static int read_write_object(int fd, char *buf, uint64_t oid, int copies,
                             unsigned int datalen, uint64_t offset,
                             int write, int create, uint8_t cache)
{
    SheepdogObjReq hdr;
    SheepdogObjRsp *rsp = (SheepdogObjRsp *)&hdr;
    unsigned int wlen, rlen;
    int ret;

    memset(&hdr, 0, sizeof(hdr));

    if (write) {
        wlen = datalen;
        rlen = 0;
        hdr.flags = SD_FLAG_CMD_WRITE;
        if (create) {
            hdr.opcode = SD_OP_CREATE_AND_WRITE_OBJ;
        } else {
            hdr.opcode = SD_OP_WRITE_OBJ;
        }
    } else {
        wlen = 0;
        rlen = datalen;
        hdr.opcode = SD_OP_READ_OBJ;
    }

    if (cache) {
        hdr.flags |= SD_FLAG_CMD_CACHE;
    }

    hdr.oid = oid;
    hdr.data_length = datalen;
    hdr.offset = offset;
    hdr.copies = copies;

    ret = do_req(fd, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
    if (ret) {
        error_report("failed to send a request to the sheep");
        return ret;
    }

    switch (rsp->result) {
    case SD_RES_SUCCESS:
        return 0;
    default:
        error_report("%s", sd_strerror(rsp->result));
        return -EIO;
    }
}

static int read_object(int fd, char *buf, uint64_t oid, int copies,
                       unsigned int datalen, uint64_t offset, uint8_t cache)
{
    return read_write_object(fd, buf, oid, copies, datalen, offset, 0, 0,
                             cache);
}

static int write_object(int fd, char *buf, uint64_t oid, int copies,
                        unsigned int datalen, uint64_t offset, int create,
                        uint8_t cache)
{
    return read_write_object(fd, buf, oid, copies, datalen, offset, 1, create,
                             cache);
}

static int sd_open(BlockDriverState *bs, const char *filename, int flags)
{
    int ret, fd;
    uint32_t vid = 0;
    BDRVSheepdogState *s = bs->opaque;
    char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN];
    uint32_t snapid;
    char *buf = NULL;

    strstart(filename, "sheepdog:", (const char **)&filename);

    QLIST_INIT(&s->inflight_aio_head);
    QLIST_INIT(&s->pending_aio_head);
    s->fd = -1;

    memset(vdi, 0, sizeof(vdi));
    memset(tag, 0, sizeof(tag));
    if (parse_vdiname(s, filename, vdi, &snapid, tag) < 0) {
        ret = -EINVAL;
        goto out;
    }
    s->fd = get_sheep_fd(s);
    if (s->fd < 0) {
        ret = s->fd;
        goto out;
    }

    ret = find_vdi_name(s, vdi, snapid, tag, &vid, 0);
    if (ret) {
        goto out;
    }

    if (flags & BDRV_O_CACHE_WB) {
        s->cache_enabled = 1;
        s->flush_fd = connect_to_sdog(s->addr, s->port);
        if (s->flush_fd < 0) {
            error_report("failed to connect");
            ret = s->flush_fd;
            goto out;
        }
    }

    if (snapid || tag[0] != '\0') {
        dprintf("%" PRIx32 " snapshot inode was open.\n", vid);
        s->is_snapshot = 1;
    }

    fd = connect_to_sdog(s->addr, s->port);
    if (fd < 0) {
        error_report("failed to connect");
        ret = fd;
        goto out;
    }

    buf = g_malloc(SD_INODE_SIZE);
    ret = read_object(fd, buf, vid_to_vdi_oid(vid), 0, SD_INODE_SIZE, 0,
                      s->cache_enabled);

    closesocket(fd);

    if (ret) {
        goto out;
    }

    memcpy(&s->inode, buf, sizeof(s->inode));
    s->min_dirty_data_idx = UINT32_MAX;
    s->max_dirty_data_idx = 0;

    bs->total_sectors = s->inode.vdi_size / SECTOR_SIZE;
    strncpy(s->name, vdi, sizeof(s->name));
    qemu_co_mutex_init(&s->lock);
    g_free(buf);
    return 0;
out:
    qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL);
    if (s->fd >= 0) {
        closesocket(s->fd);
    }
    g_free(buf);
    return ret;
}

static int do_sd_create(char *filename, int64_t vdi_size,
                        uint32_t base_vid, uint32_t *vdi_id, int snapshot,
                        const char *addr, const char *port)
{
    SheepdogVdiReq hdr;
    SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr;
    int fd, ret;
    unsigned int wlen, rlen = 0;
    char buf[SD_MAX_VDI_LEN];

    fd = connect_to_sdog(addr, port);
    if (fd < 0) {
        return fd;
    }

    memset(buf, 0, sizeof(buf));
    strncpy(buf, filename, SD_MAX_VDI_LEN);

    memset(&hdr, 0, sizeof(hdr));
    hdr.opcode = SD_OP_NEW_VDI;
    hdr.base_vdi_id = base_vid;

    wlen = SD_MAX_VDI_LEN;

    hdr.flags = SD_FLAG_CMD_WRITE;
    hdr.snapid = snapshot;

    hdr.data_length = wlen;
    hdr.vdi_size = vdi_size;

    ret = do_req(fd, (SheepdogReq *)&hdr, buf, &wlen, &rlen);

    closesocket(fd);

    if (ret) {
        return ret;
    }

    if (rsp->result != SD_RES_SUCCESS) {
        error_report("%s, %s", sd_strerror(rsp->result), filename);
        return -EIO;
    }

    if (vdi_id) {
        *vdi_id = rsp->vdi_id;
    }

    return 0;
}

static int sd_prealloc(const char *filename)
{
    BlockDriverState *bs = NULL;
    uint32_t idx, max_idx;
    int64_t vdi_size;
    void *buf = g_malloc0(SD_DATA_OBJ_SIZE);
    int ret;

    ret = bdrv_file_open(&bs, filename, BDRV_O_RDWR);
    if (ret < 0) {
        goto out;
    }

    vdi_size = bdrv_getlength(bs);
    if (vdi_size < 0) {
        ret = vdi_size;
        goto out;
    }
    max_idx = DIV_ROUND_UP(vdi_size, SD_DATA_OBJ_SIZE);

    for (idx = 0; idx < max_idx; idx++) {
        /*
         * The created image can be a cloned image, so we need to read
         * a data from the source image.
         */
        ret = bdrv_pread(bs, idx * SD_DATA_OBJ_SIZE, buf, SD_DATA_OBJ_SIZE);
        if (ret < 0) {
            goto out;
        }
        ret = bdrv_pwrite(bs, idx * SD_DATA_OBJ_SIZE, buf, SD_DATA_OBJ_SIZE);
        if (ret < 0) {
            goto out;
        }
    }
out:
    if (bs) {
        bdrv_delete(bs);
    }
    g_free(buf);

    return ret;
}

static int sd_create(const char *filename, QEMUOptionParameter *options)
{
    int ret = 0;
    uint32_t vid = 0, base_vid = 0;
    int64_t vdi_size = 0;
    char *backing_file = NULL;
    BDRVSheepdogState *s;
    char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN];
    uint32_t snapid;
    int prealloc = 0;
    const char *vdiname;

    s = g_malloc0(sizeof(BDRVSheepdogState));

    strstart(filename, "sheepdog:", &vdiname);

    memset(vdi, 0, sizeof(vdi));
    memset(tag, 0, sizeof(tag));
    if (parse_vdiname(s, vdiname, vdi, &snapid, tag) < 0) {
        error_report("invalid filename");
        ret = -EINVAL;
        goto out;
    }

    while (options && options->name) {
        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
            vdi_size = options->value.n;
        } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
            backing_file = options->value.s;
        } else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
            if (!options->value.s || !strcmp(options->value.s, "off")) {
                prealloc = 0;
            } else if (!strcmp(options->value.s, "full")) {
                prealloc = 1;
            } else {
                error_report("Invalid preallocation mode: '%s'",
                             options->value.s);
                ret = -EINVAL;
                goto out;
            }
        }
        options++;
    }

    if (vdi_size > SD_MAX_VDI_SIZE) {
        error_report("too big image size");
        ret = -EINVAL;
        goto out;
    }

    if (backing_file) {
        BlockDriverState *bs;
        BDRVSheepdogState *s;
        BlockDriver *drv;

        /* Currently, only Sheepdog backing image is supported. */
        drv = bdrv_find_protocol(backing_file);
        if (!drv || strcmp(drv->protocol_name, "sheepdog") != 0) {
            error_report("backing_file must be a sheepdog image");
            ret = -EINVAL;
            goto out;
        }

        ret = bdrv_file_open(&bs, backing_file, 0);
        if (ret < 0) {
            goto out;
        }

        s = bs->opaque;

        if (!is_snapshot(&s->inode)) {
            error_report("cannot clone from a non snapshot vdi");
            bdrv_delete(bs);
            ret = -EINVAL;
            goto out;
        }

        base_vid = s->inode.vdi_id;
        bdrv_delete(bs);
    }

    ret = do_sd_create(vdi, vdi_size, base_vid, &vid, 0, s->addr, s->port);
    if (!prealloc || ret) {
        goto out;
    }

    ret = sd_prealloc(filename);
out:
    g_free(s);
    return ret;
}

static void sd_close(BlockDriverState *bs)
{
    BDRVSheepdogState *s = bs->opaque;
    SheepdogVdiReq hdr;
    SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr;
    unsigned int wlen, rlen = 0;
    int fd, ret;

    dprintf("%s\n", s->name);

    fd = connect_to_sdog(s->addr, s->port);
    if (fd < 0) {
        return;
    }

    memset(&hdr, 0, sizeof(hdr));

    hdr.opcode = SD_OP_RELEASE_VDI;
    wlen = strlen(s->name) + 1;
    hdr.data_length = wlen;
    hdr.flags = SD_FLAG_CMD_WRITE;

    ret = do_req(fd, (SheepdogReq *)&hdr, s->name, &wlen, &rlen);

    closesocket(fd);

    if (!ret && rsp->result != SD_RES_SUCCESS &&
        rsp->result != SD_RES_VDI_NOT_LOCKED) {
        error_report("%s, %s", sd_strerror(rsp->result), s->name);
    }

    qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL);
    closesocket(s->fd);
    if (s->cache_enabled) {
        closesocket(s->flush_fd);
    }
    g_free(s->addr);
}

static int64_t sd_getlength(BlockDriverState *bs)
{
    BDRVSheepdogState *s = bs->opaque;

    return s->inode.vdi_size;
}

static int sd_truncate(BlockDriverState *bs, int64_t offset)
{
    BDRVSheepdogState *s = bs->opaque;
    int ret, fd;
    unsigned int datalen;

    if (offset < s->inode.vdi_size) {
        error_report("shrinking is not supported");
        return -EINVAL;
    } else if (offset > SD_MAX_VDI_SIZE) {
        error_report("too big image size");
        return -EINVAL;
    }

    fd = connect_to_sdog(s->addr, s->port);
    if (fd < 0) {
        return fd;
    }

    /* we don't need to update entire object */
    datalen = SD_INODE_SIZE - sizeof(s->inode.data_vdi_id);
    s->inode.vdi_size = offset;
    ret = write_object(fd, (char *)&s->inode, vid_to_vdi_oid(s->inode.vdi_id),
                       s->inode.nr_copies, datalen, 0, 0, s->cache_enabled);
    close(fd);

    if (ret < 0) {
        error_report("failed to update an inode.");
    }

    return ret;
}

/*
 * This function is called after writing data objects.  If we need to
 * update metadata, this sends a write request to the vdi object.
 * Otherwise, this switches back to sd_co_readv/writev.
 */
static void coroutine_fn sd_write_done(SheepdogAIOCB *acb)
{
    int ret;
    BDRVSheepdogState *s = acb->common.bs->opaque;
    struct iovec iov;
    AIOReq *aio_req;
    uint32_t offset, data_len, mn, mx;

    mn = s->min_dirty_data_idx;
    mx = s->max_dirty_data_idx;
    if (mn <= mx) {
        /* we need to update the vdi object. */
        offset = sizeof(s->inode) - sizeof(s->inode.data_vdi_id) +
            mn * sizeof(s->inode.data_vdi_id[0]);
        data_len = (mx - mn + 1) * sizeof(s->inode.data_vdi_id[0]);

        s->min_dirty_data_idx = UINT32_MAX;
        s->max_dirty_data_idx = 0;

        iov.iov_base = &s->inode;
        iov.iov_len = sizeof(s->inode);
        aio_req = alloc_aio_req(s, acb, vid_to_vdi_oid(s->inode.vdi_id),
                                data_len, offset, 0, 0, offset);
        QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
        ret = add_aio_request(s, aio_req, &iov, 1, 0, AIOCB_WRITE_UDATA);
        if (ret) {
            free_aio_req(s, aio_req);
            acb->ret = -EIO;
            goto out;
        }

        acb->aio_done_func = sd_finish_aiocb;
        acb->aiocb_type = AIOCB_WRITE_UDATA;
        return;
    }
out:
    sd_finish_aiocb(acb);
}

/*
 * Create a writable VDI from a snapshot
 */
static int sd_create_branch(BDRVSheepdogState *s)
{
    int ret, fd;
    uint32_t vid;
    char *buf;

    dprintf("%" PRIx32 " is snapshot.\n", s->inode.vdi_id);

    buf = g_malloc(SD_INODE_SIZE);

    ret = do_sd_create(s->name, s->inode.vdi_size, s->inode.vdi_id, &vid, 1,
                       s->addr, s->port);
    if (ret) {
        goto out;
    }

    dprintf("%" PRIx32 " is created.\n", vid);

    fd = connect_to_sdog(s->addr, s->port);
    if (fd < 0) {
        error_report("failed to connect");
        ret = fd;
        goto out;
    }

    ret = read_object(fd, buf, vid_to_vdi_oid(vid), s->inode.nr_copies,
                      SD_INODE_SIZE, 0, s->cache_enabled);

    closesocket(fd);

    if (ret < 0) {
        goto out;
    }

    memcpy(&s->inode, buf, sizeof(s->inode));

    s->is_snapshot = 0;
    ret = 0;
    dprintf("%" PRIx32 " was newly created.\n", s->inode.vdi_id);

out:
    g_free(buf);

    return ret;
}

/*
 * Send I/O requests to the server.
 *
 * This function sends requests to the server, links the requests to
 * the inflight_list in BDRVSheepdogState, and exits without
 * waiting the response.  The responses are received in the
 * `aio_read_response' function which is called from the main loop as
 * a fd handler.
 *
 * Returns 1 when we need to wait a response, 0 when there is no sent
 * request and -errno in error cases.
 */
static int coroutine_fn sd_co_rw_vector(void *p)
{
    SheepdogAIOCB *acb = p;
    int ret = 0;
    unsigned long len, done = 0, total = acb->nb_sectors * SECTOR_SIZE;
    unsigned long idx = acb->sector_num * SECTOR_SIZE / SD_DATA_OBJ_SIZE;
    uint64_t oid;
    uint64_t offset = (acb->sector_num * SECTOR_SIZE) % SD_DATA_OBJ_SIZE;
    BDRVSheepdogState *s = acb->common.bs->opaque;
    SheepdogInode *inode = &s->inode;
    AIOReq *aio_req;

    if (acb->aiocb_type == AIOCB_WRITE_UDATA && s->is_snapshot) {
        /*
         * In the case we open the snapshot VDI, Sheepdog creates the
         * writable VDI when we do a write operation first.
         */
        ret = sd_create_branch(s);
        if (ret) {
            acb->ret = -EIO;
            goto out;
        }
    }

    /*
     * Make sure we don't free the aiocb before we are done with all requests.
     * This additional reference is dropped at the end of this function.
     */
    acb->nr_pending++;

    while (done != total) {
        uint8_t flags = 0;
        uint64_t old_oid = 0;
        int create = 0;

        oid = vid_to_data_oid(inode->data_vdi_id[idx], idx);

        len = MIN(total - done, SD_DATA_OBJ_SIZE - offset);

        switch (acb->aiocb_type) {
        case AIOCB_READ_UDATA:
            if (!inode->data_vdi_id[idx]) {
                qemu_iovec_memset(acb->qiov, done, 0, len);
                goto done;
            }
            break;
        case AIOCB_WRITE_UDATA:
            if (!inode->data_vdi_id[idx]) {
                create = 1;
            } else if (!is_data_obj_writable(inode, idx)) {
                /* Copy-On-Write */
                create = 1;
                old_oid = oid;
                flags = SD_FLAG_CMD_COW;
            }
            break;
        default:
            break;
        }

        if (create) {
            dprintf("update ino (%" PRIu32 ") %" PRIu64 " %" PRIu64 " %ld\n",
                    inode->vdi_id, oid,
                    vid_to_data_oid(inode->data_vdi_id[idx], idx), idx);
            oid = vid_to_data_oid(inode->vdi_id, idx);
            dprintf("new oid %" PRIx64 "\n", oid);
        }

        aio_req = alloc_aio_req(s, acb, oid, len, offset, flags, old_oid, done);

        if (create) {
            AIOReq *areq;
            QLIST_FOREACH(areq, &s->inflight_aio_head, aio_siblings) {
                if (areq->oid == oid) {
                    /*
                     * Sheepdog cannot handle simultaneous create
                     * requests to the same object.  So we cannot send
                     * the request until the previous request
                     * finishes.
                     */
                    aio_req->flags = 0;
                    aio_req->base_oid = 0;
                    QLIST_INSERT_HEAD(&s->pending_aio_head, aio_req,
                                      aio_siblings);
                    goto done;
                }
            }
        }

        QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
        ret = add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov,
                              create, acb->aiocb_type);
        if (ret < 0) {
            error_report("add_aio_request is failed");
            free_aio_req(s, aio_req);
            acb->ret = -EIO;
            goto out;
        }
    done:
        offset = 0;
        idx++;
        done += len;
    }
out:
    if (!--acb->nr_pending) {
        return acb->ret;
    }
    return 1;
}

static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num,
                        int nb_sectors, QEMUIOVector *qiov)
{
    SheepdogAIOCB *acb;
    int ret;

    if (bs->growable && sector_num + nb_sectors > bs->total_sectors) {
        ret = sd_truncate(bs, (sector_num + nb_sectors) * SECTOR_SIZE);
        if (ret < 0) {
            return ret;
        }
        bs->total_sectors = sector_num + nb_sectors;
    }

    acb = sd_aio_setup(bs, qiov, sector_num, nb_sectors, NULL, NULL);
    acb->aio_done_func = sd_write_done;
    acb->aiocb_type = AIOCB_WRITE_UDATA;

    ret = sd_co_rw_vector(acb);
    if (ret <= 0) {
        qemu_aio_release(acb);
        return ret;
    }

    qemu_coroutine_yield();

    return acb->ret;
}

static coroutine_fn int sd_co_readv(BlockDriverState *bs, int64_t sector_num,
                       int nb_sectors, QEMUIOVector *qiov)
{
    SheepdogAIOCB *acb;
    int ret;

    acb = sd_aio_setup(bs, qiov, sector_num, nb_sectors, NULL, NULL);
    acb->aiocb_type = AIOCB_READ_UDATA;
    acb->aio_done_func = sd_finish_aiocb;

    ret = sd_co_rw_vector(acb);
    if (ret <= 0) {
        qemu_aio_release(acb);
        return ret;
    }

    qemu_coroutine_yield();

    return acb->ret;
}

static int coroutine_fn sd_co_flush_to_disk(BlockDriverState *bs)
{
    BDRVSheepdogState *s = bs->opaque;
    SheepdogObjReq hdr = { 0 };
    SheepdogObjRsp *rsp = (SheepdogObjRsp *)&hdr;
    SheepdogInode *inode = &s->inode;
    int ret;
    unsigned int wlen = 0, rlen = 0;

    if (!s->cache_enabled) {
        return 0;
    }

    hdr.opcode = SD_OP_FLUSH_VDI;
    hdr.oid = vid_to_vdi_oid(inode->vdi_id);

    ret = do_req(s->flush_fd, (SheepdogReq *)&hdr, NULL, &wlen, &rlen);
    if (ret) {
        error_report("failed to send a request to the sheep");
        return ret;
    }

    if (rsp->result == SD_RES_INVALID_PARMS) {
        dprintf("disable write cache since the server doesn't support it\n");

        s->cache_enabled = 0;
        closesocket(s->flush_fd);
        return 0;
    }

    if (rsp->result != SD_RES_SUCCESS) {
        error_report("%s", sd_strerror(rsp->result));
        return -EIO;
    }

    return 0;
}

static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
{
    BDRVSheepdogState *s = bs->opaque;
    int ret, fd;
    uint32_t new_vid;
    SheepdogInode *inode;
    unsigned int datalen;

    dprintf("sn_info: name %s id_str %s s: name %s vm_state_size %" PRId64 " "
            "is_snapshot %d\n", sn_info->name, sn_info->id_str,
            s->name, sn_info->vm_state_size, s->is_snapshot);

    if (s->is_snapshot) {
        error_report("You can't create a snapshot of a snapshot VDI, "
                     "%s (%" PRIu32 ").", s->name, s->inode.vdi_id);

        return -EINVAL;
    }

    dprintf("%s %s\n", sn_info->name, sn_info->id_str);

    s->inode.vm_state_size = sn_info->vm_state_size;
    s->inode.vm_clock_nsec = sn_info->vm_clock_nsec;
    strncpy(s->inode.tag, sn_info->name, sizeof(s->inode.tag));
    /* we don't need to update entire object */
    datalen = SD_INODE_SIZE - sizeof(s->inode.data_vdi_id);

    /* refresh inode. */
    fd = connect_to_sdog(s->addr, s->port);
    if (fd < 0) {
        ret = fd;
        goto cleanup;
    }

    ret = write_object(fd, (char *)&s->inode, vid_to_vdi_oid(s->inode.vdi_id),
                       s->inode.nr_copies, datalen, 0, 0, s->cache_enabled);
    if (ret < 0) {
        error_report("failed to write snapshot's inode.");
        goto cleanup;
    }

    ret = do_sd_create(s->name, s->inode.vdi_size, s->inode.vdi_id, &new_vid, 1,
                       s->addr, s->port);
    if (ret < 0) {
        error_report("failed to create inode for snapshot. %s",
                     strerror(errno));
        goto cleanup;
    }

    inode = (SheepdogInode *)g_malloc(datalen);

    ret = read_object(fd, (char *)inode, vid_to_vdi_oid(new_vid),
                      s->inode.nr_copies, datalen, 0, s->cache_enabled);

    if (ret < 0) {
        error_report("failed to read new inode info. %s", strerror(errno));
        goto cleanup;
    }

    memcpy(&s->inode, inode, datalen);
    dprintf("s->inode: name %s snap_id %x oid %x\n",
            s->inode.name, s->inode.snap_id, s->inode.vdi_id);

cleanup:
    closesocket(fd);
    return ret;
}

static int sd_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
{
    BDRVSheepdogState *s = bs->opaque;
    BDRVSheepdogState *old_s;
    char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN];
    char *buf = NULL;
    uint32_t vid;
    uint32_t snapid = 0;
    int ret = 0, fd;

    old_s = g_malloc(sizeof(BDRVSheepdogState));

    memcpy(old_s, s, sizeof(BDRVSheepdogState));

    memset(vdi, 0, sizeof(vdi));
    strncpy(vdi, s->name, sizeof(vdi));

    memset(tag, 0, sizeof(tag));
    snapid = strtoul(snapshot_id, NULL, 10);
    if (!snapid) {
        strncpy(tag, s->name, sizeof(tag));
    }

    ret = find_vdi_name(s, vdi, snapid, tag, &vid, 1);
    if (ret) {
        error_report("Failed to find_vdi_name");
        goto out;
    }

    fd = connect_to_sdog(s->addr, s->port);
    if (fd < 0) {
        error_report("failed to connect");
        ret = fd;
        goto out;
    }

    buf = g_malloc(SD_INODE_SIZE);
    ret = read_object(fd, buf, vid_to_vdi_oid(vid), s->inode.nr_copies,
                      SD_INODE_SIZE, 0, s->cache_enabled);

    closesocket(fd);

    if (ret) {
        goto out;
    }

    memcpy(&s->inode, buf, sizeof(s->inode));

    if (!s->inode.vm_state_size) {
        error_report("Invalid snapshot");
        ret = -ENOENT;
        goto out;
    }

    s->is_snapshot = 1;

    g_free(buf);
    g_free(old_s);

    return 0;
out:
    /* recover bdrv_sd_state */
    memcpy(s, old_s, sizeof(BDRVSheepdogState));
    g_free(buf);
    g_free(old_s);

    error_report("failed to open. recover old bdrv_sd_state.");

    return ret;
}

static int sd_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
{
    /* FIXME: Delete specified snapshot id.  */
    return 0;
}

static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
{
    BDRVSheepdogState *s = bs->opaque;
    SheepdogReq req;
    int fd, nr = 1024, ret, max = BITS_TO_LONGS(SD_NR_VDIS) * sizeof(long);
    QEMUSnapshotInfo *sn_tab = NULL;
    unsigned wlen, rlen;
    int found = 0;
    static SheepdogInode inode;
    unsigned long *vdi_inuse;
    unsigned int start_nr;
    uint64_t hval;
    uint32_t vid;

    vdi_inuse = g_malloc(max);

    fd = connect_to_sdog(s->addr, s->port);
    if (fd < 0) {
        ret = fd;
        goto out;
    }

    rlen = max;
    wlen = 0;

    memset(&req, 0, sizeof(req));

    req.opcode = SD_OP_READ_VDIS;
    req.data_length = max;

    ret = do_req(fd, (SheepdogReq *)&req, vdi_inuse, &wlen, &rlen);

    closesocket(fd);
    if (ret) {
        goto out;
    }

    sn_tab = g_malloc0(nr * sizeof(*sn_tab));

    /* calculate a vdi id with hash function */
    hval = fnv_64a_buf(s->name, strlen(s->name), FNV1A_64_INIT);
    start_nr = hval & (SD_NR_VDIS - 1);

    fd = connect_to_sdog(s->addr, s->port);
    if (fd < 0) {
        error_report("failed to connect");
        ret = fd;
        goto out;
    }

    for (vid = start_nr; found < nr; vid = (vid + 1) % SD_NR_VDIS) {
        if (!test_bit(vid, vdi_inuse)) {
            break;
        }

        /* we don't need to read entire object */
        ret = read_object(fd, (char *)&inode, vid_to_vdi_oid(vid),
                          0, SD_INODE_SIZE - sizeof(inode.data_vdi_id), 0,
                          s->cache_enabled);

        if (ret) {
            continue;
        }

        if (!strcmp(inode.name, s->name) && is_snapshot(&inode)) {
            sn_tab[found].date_sec = inode.snap_ctime >> 32;
            sn_tab[found].date_nsec = inode.snap_ctime & 0xffffffff;
            sn_tab[found].vm_state_size = inode.vm_state_size;
            sn_tab[found].vm_clock_nsec = inode.vm_clock_nsec;

            snprintf(sn_tab[found].id_str, sizeof(sn_tab[found].id_str), "%u",
                     inode.snap_id);
            strncpy(sn_tab[found].name, inode.tag,
                    MIN(sizeof(sn_tab[found].name), sizeof(inode.tag)));
            found++;
        }
    }

    closesocket(fd);
out:
    *psn_tab = sn_tab;

    g_free(vdi_inuse);

    if (ret < 0) {
        return ret;
    }

    return found;
}

static int do_load_save_vmstate(BDRVSheepdogState *s, uint8_t *data,
                                int64_t pos, int size, int load)
{
    int fd, create;
    int ret = 0, remaining = size;
    unsigned int data_len;
    uint64_t vmstate_oid;
    uint32_t vdi_index;
    uint64_t offset;

    fd = connect_to_sdog(s->addr, s->port);
    if (fd < 0) {
        return fd;
    }

    while (remaining) {
        vdi_index = pos / SD_DATA_OBJ_SIZE;
        offset = pos % SD_DATA_OBJ_SIZE;

        data_len = MIN(remaining, SD_DATA_OBJ_SIZE);

        vmstate_oid = vid_to_vmstate_oid(s->inode.vdi_id, vdi_index);

        create = (offset == 0);
        if (load) {
            ret = read_object(fd, (char *)data, vmstate_oid,
                              s->inode.nr_copies, data_len, offset,
                              s->cache_enabled);
        } else {
            ret = write_object(fd, (char *)data, vmstate_oid,
                               s->inode.nr_copies, data_len, offset, create,
                               s->cache_enabled);
        }

        if (ret < 0) {
            error_report("failed to save vmstate %s", strerror(errno));
            goto cleanup;
        }

        pos += data_len;
        remaining -= data_len;
    }
    ret = size;
cleanup:
    closesocket(fd);
    return ret;
}

static int sd_save_vmstate(BlockDriverState *bs, const uint8_t *data,
                           int64_t pos, int size)
{
    BDRVSheepdogState *s = bs->opaque;

    return do_load_save_vmstate(s, (uint8_t *)data, pos, size, 0);
}

static int sd_load_vmstate(BlockDriverState *bs, uint8_t *data,
                           int64_t pos, int size)
{
    BDRVSheepdogState *s = bs->opaque;

    return do_load_save_vmstate(s, data, pos, size, 1);
}


static QEMUOptionParameter sd_create_options[] = {
    {
        .name = BLOCK_OPT_SIZE,
        .type = OPT_SIZE,
        .help = "Virtual disk size"
    },
    {
        .name = BLOCK_OPT_BACKING_FILE,
        .type = OPT_STRING,
        .help = "File name of a base image"
    },
    {
        .name = BLOCK_OPT_PREALLOC,
        .type = OPT_STRING,
        .help = "Preallocation mode (allowed values: off, full)"
    },
    { NULL }
};

BlockDriver bdrv_sheepdog = {
    .format_name    = "sheepdog",
    .protocol_name  = "sheepdog",
    .instance_size  = sizeof(BDRVSheepdogState),
    .bdrv_file_open = sd_open,
    .bdrv_close     = sd_close,
    .bdrv_create    = sd_create,
    .bdrv_getlength = sd_getlength,
    .bdrv_truncate  = sd_truncate,

    .bdrv_co_readv  = sd_co_readv,
    .bdrv_co_writev = sd_co_writev,
    .bdrv_co_flush_to_disk  = sd_co_flush_to_disk,

    .bdrv_snapshot_create   = sd_snapshot_create,
    .bdrv_snapshot_goto     = sd_snapshot_goto,
    .bdrv_snapshot_delete   = sd_snapshot_delete,
    .bdrv_snapshot_list     = sd_snapshot_list,

    .bdrv_save_vmstate  = sd_save_vmstate,
    .bdrv_load_vmstate  = sd_load_vmstate,

    .create_options = sd_create_options,
};

static void bdrv_sheepdog_init(void)
{
    bdrv_register(&bdrv_sheepdog);
}
block_init(bdrv_sheepdog_init);
