[Sheepdog] [PATCH RFC 07/10] sheepfs: implement 'sync' operation for volumes

Liu Yuan namei.unix at gmail.com
Sat May 5 13:29:19 CEST 2012


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




More information about the sheepdog mailing list