From: Liu Yuan <tailai.ly at taobao.com> Signed-off-by: Liu Yuan <tailai.ly at taobao.com> --- sheep/sheepfs/core.c | 17 ++++++++++++++++- sheep/sheepfs/sheepfs.h | 1 + sheep/sheepfs/volume.c | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletions(-) diff --git a/sheep/sheepfs/core.c b/sheep/sheepfs/core.c index a518e83..612a36b 100644 --- a/sheep/sheepfs/core.c +++ b/sheep/sheepfs/core.c @@ -20,12 +20,14 @@ static struct sheepfs_file_operation { int (*read)(const char *path, char *buf, size_t size, off_t); int (*write)(const char *path, const char *buf, size_t size, off_t); size_t (*get_size)(const char *path); + int (*sync)(const char *path); } sheepfs_file_ops[] = { [OP_NULL] = { NULL, NULL, NULL }, [OP_CLUSTER_INFO] = { cluster_info_read, NULL, cluster_info_get_size }, [OP_VDI_LIST] = { vdi_list_read, NULL, vdi_list_get_size }, [OP_VDI_MOUNT] = { NULL, vdi_mount_write, NULL }, - [OP_VOLUME] = { volume_read, volume_write, volume_get_size }, + [OP_VOLUME] = { volume_read, volume_write, volume_get_size, + volume_sync }, }; int sheepfs_set_op(const char *path, unsigned opcode) @@ -144,12 +146,25 @@ static int sheepfs_truncate(const char *path, off_t size) return ret; } +static int sheepfs_fsync(const char *path, int datasync, + struct fuse_file_info *fi) +{ + int ret = 0; + unsigned op = sheepfs_get_op(path); + + if (sheepfs_file_ops[op].sync) + ret = sheepfs_file_ops[op].sync(path); + + return ret; +} + struct fuse_operations sheepfs_ops = { .getattr = sheepfs_getattr, .readdir = sheepfs_readdir, .truncate = sheepfs_truncate, .read = sheepfs_read, .write = sheepfs_write, + .fsync = sheepfs_fsync, }; static void sheepfs_main_loop(char *root) diff --git a/sheep/sheepfs/sheepfs.h b/sheep/sheepfs/sheepfs.h index f53b74c..faef834 100644 --- a/sheep/sheepfs/sheepfs.h +++ b/sheep/sheepfs/sheepfs.h @@ -34,6 +34,7 @@ extern int volume_read(const char *path, char *buf, size_t size, off_t offset); extern int volume_write(const char *, const char *buf, size_t size, off_t); extern size_t volume_get_size(const char *); extern int volume_create_entry(const char *entry); +extern int volume_sync(const char *path); /* cluster.c */ extern int cluster_info_read(const char *path, char *buf, size_t size, off_t); diff --git a/sheep/sheepfs/volume.c b/sheep/sheepfs/volume.c index d667952..17edf4c 100644 --- a/sheep/sheepfs/volume.c +++ b/sheep/sheepfs/volume.c @@ -211,6 +211,39 @@ size_t volume_get_size(const char *path) return size; } +static int volume_do_sync(uint32_t vid) +{ + struct sd_obj_req hdr = { 0 }; + struct sd_obj_rsp *rsp = (struct sd_obj_rsp *)&hdr; + int ret; + unsigned wlen = 0, rlen = 0; + + hdr.opcode = SD_OP_FLUSH_VDI; + hdr.oid = vid_to_vdi_oid(vid); + + ret = exec_req(sheep_fd, (struct sd_req *)&hdr, NULL, &wlen, &rlen); + + if (ret || rsp->result != SD_RES_SUCCESS) { + eprintf("failed to flush vdi %" PRIx32 "\n", vid); + return -1; + } + + return 0; +} + +int volume_sync(const char *path) +{ + uint32_t vid; + + if (shadow_file_getxattr(path, SH_VID_NAME, &vid, SH_VID_SIZE) < 0) + return -EIO; + + if (volume_do_sync(vid) < 0) + return -EIO; + + return 0; +} + static int init_vdi_info(const char *entry, uint32_t *vid, size_t *size) { struct strbuf *buf; -- 1.7.8.2 |