sheepdog: multiplex the rw FD to flush cache
This will reduce sockfds connected to the sheep server to one, which simply the future hacks. Cc: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp> Cc: Kevin Wolf <kwolf@redhat.com> Cc: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Liu Yuan <tailai.ly@taobao.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
df702c9b4c
commit
4778307278
@ -266,6 +266,7 @@ typedef struct AIOReq {
|
|||||||
enum AIOCBState {
|
enum AIOCBState {
|
||||||
AIOCB_WRITE_UDATA,
|
AIOCB_WRITE_UDATA,
|
||||||
AIOCB_READ_UDATA,
|
AIOCB_READ_UDATA,
|
||||||
|
AIOCB_FLUSH_CACHE,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SheepdogAIOCB {
|
struct SheepdogAIOCB {
|
||||||
@ -299,7 +300,6 @@ typedef struct BDRVSheepdogState {
|
|||||||
char *addr;
|
char *addr;
|
||||||
char *port;
|
char *port;
|
||||||
int fd;
|
int fd;
|
||||||
int flush_fd;
|
|
||||||
|
|
||||||
CoMutex lock;
|
CoMutex lock;
|
||||||
Coroutine *co_send;
|
Coroutine *co_send;
|
||||||
@ -736,6 +736,13 @@ static void coroutine_fn aio_read_response(void *opaque)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case AIOCB_FLUSH_CACHE:
|
||||||
|
if (rsp.result == SD_RES_INVALID_PARMS) {
|
||||||
|
dprintf("disable cache since the server doesn't support it\n");
|
||||||
|
s->cache_flags = SD_FLAG_CMD_DIRECT;
|
||||||
|
rsp.result = SD_RES_SUCCESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rsp.result != SD_RES_SUCCESS) {
|
if (rsp.result != SD_RES_SUCCESS) {
|
||||||
@ -950,7 +957,7 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
|
|||||||
{
|
{
|
||||||
int nr_copies = s->inode.nr_copies;
|
int nr_copies = s->inode.nr_copies;
|
||||||
SheepdogObjReq hdr;
|
SheepdogObjReq hdr;
|
||||||
unsigned int wlen;
|
unsigned int wlen = 0;
|
||||||
int ret;
|
int ret;
|
||||||
uint64_t oid = aio_req->oid;
|
uint64_t oid = aio_req->oid;
|
||||||
unsigned int datalen = aio_req->data_len;
|
unsigned int datalen = aio_req->data_len;
|
||||||
@ -964,18 +971,23 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
|
|||||||
|
|
||||||
memset(&hdr, 0, sizeof(hdr));
|
memset(&hdr, 0, sizeof(hdr));
|
||||||
|
|
||||||
if (aiocb_type == AIOCB_READ_UDATA) {
|
switch (aiocb_type) {
|
||||||
wlen = 0;
|
case AIOCB_FLUSH_CACHE:
|
||||||
|
hdr.opcode = SD_OP_FLUSH_VDI;
|
||||||
|
break;
|
||||||
|
case AIOCB_READ_UDATA:
|
||||||
hdr.opcode = SD_OP_READ_OBJ;
|
hdr.opcode = SD_OP_READ_OBJ;
|
||||||
hdr.flags = flags;
|
hdr.flags = flags;
|
||||||
} else if (create) {
|
break;
|
||||||
|
case AIOCB_WRITE_UDATA:
|
||||||
|
if (create) {
|
||||||
|
hdr.opcode = SD_OP_CREATE_AND_WRITE_OBJ;
|
||||||
|
} else {
|
||||||
|
hdr.opcode = SD_OP_WRITE_OBJ;
|
||||||
|
}
|
||||||
wlen = datalen;
|
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;
|
hdr.flags = SD_FLAG_CMD_WRITE | flags;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->cache_flags) {
|
if (s->cache_flags) {
|
||||||
@ -1127,15 +1139,6 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags)
|
|||||||
s->cache_flags = SD_FLAG_CMD_DIRECT;
|
s->cache_flags = SD_FLAG_CMD_DIRECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->cache_flags == SD_FLAG_CMD_CACHE) {
|
|
||||||
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') {
|
if (snapid || tag[0] != '\0') {
|
||||||
dprintf("%" PRIx32 " snapshot inode was open.\n", vid);
|
dprintf("%" PRIx32 " snapshot inode was open.\n", vid);
|
||||||
s->is_snapshot = true;
|
s->is_snapshot = true;
|
||||||
@ -1397,9 +1400,6 @@ static void sd_close(BlockDriverState *bs)
|
|||||||
|
|
||||||
qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL);
|
qemu_aio_set_fd_handler(s->fd, NULL, NULL, NULL, NULL);
|
||||||
closesocket(s->fd);
|
closesocket(s->fd);
|
||||||
if (s->cache_flags) {
|
|
||||||
closesocket(s->flush_fd);
|
|
||||||
}
|
|
||||||
g_free(s->addr);
|
g_free(s->addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1711,39 +1711,31 @@ static coroutine_fn int sd_co_readv(BlockDriverState *bs, int64_t sector_num,
|
|||||||
static int coroutine_fn sd_co_flush_to_disk(BlockDriverState *bs)
|
static int coroutine_fn sd_co_flush_to_disk(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
BDRVSheepdogState *s = bs->opaque;
|
BDRVSheepdogState *s = bs->opaque;
|
||||||
SheepdogObjReq hdr = { 0 };
|
SheepdogAIOCB *acb;
|
||||||
SheepdogObjRsp *rsp = (SheepdogObjRsp *)&hdr;
|
AIOReq *aio_req;
|
||||||
SheepdogInode *inode = &s->inode;
|
|
||||||
int ret;
|
int ret;
|
||||||
unsigned int wlen = 0, rlen = 0;
|
|
||||||
|
|
||||||
if (s->cache_flags != SD_FLAG_CMD_CACHE) {
|
if (s->cache_flags != SD_FLAG_CMD_CACHE) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
hdr.opcode = SD_OP_FLUSH_VDI;
|
acb = sd_aio_setup(bs, NULL, 0, 0, NULL, NULL);
|
||||||
hdr.oid = vid_to_vdi_oid(inode->vdi_id);
|
acb->aiocb_type = AIOCB_FLUSH_CACHE;
|
||||||
|
acb->aio_done_func = sd_finish_aiocb;
|
||||||
|
|
||||||
ret = do_req(s->flush_fd, (SheepdogReq *)&hdr, NULL, &wlen, &rlen);
|
aio_req = alloc_aio_req(s, acb, vid_to_vdi_oid(s->inode.vdi_id),
|
||||||
if (ret) {
|
0, 0, 0, 0, 0);
|
||||||
error_report("failed to send a request to the sheep");
|
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
|
||||||
|
ret = add_aio_request(s, aio_req, NULL, 0, false, acb->aiocb_type);
|
||||||
|
if (ret < 0) {
|
||||||
|
error_report("add_aio_request is failed");
|
||||||
|
free_aio_req(s, aio_req);
|
||||||
|
qemu_aio_release(acb);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rsp->result == SD_RES_INVALID_PARMS) {
|
qemu_coroutine_yield();
|
||||||
dprintf("disable write cache since the server doesn't support it\n");
|
return acb->ret;
|
||||||
|
|
||||||
s->cache_flags = SD_FLAG_CMD_DIRECT;
|
|
||||||
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)
|
static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
|
||||||
|
Loading…
Reference in New Issue
Block a user