[Sheepdog] [PATCH RFC 09/10] sheepfs: teach volumes to unmount

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


From: Liu Yuan <tailai.ly at taobao.com>


Signed-off-by: Liu Yuan <tailai.ly at taobao.com>
---
 include/sheep.h         |    1 +
 sheep/ops.c             |   19 +++++++++++++++++++
 sheep/sheepfs/VDI.c     |   14 ++++++++++++++
 sheep/sheepfs/core.c    |    3 ++-
 sheep/sheepfs/sheepfs.h |    3 +++
 sheep/sheepfs/volume.c  |   44 ++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 83 insertions(+), 1 deletions(-)

diff --git a/include/sheep.h b/include/sheep.h
index 7e287c4..4a45f9b 100644
--- a/include/sheep.h
+++ b/include/sheep.h
@@ -46,6 +46,7 @@
 #define SD_OP_TRACE          0x95
 #define SD_OP_TRACE_CAT      0x96
 #define SD_OP_STAT_RECOVERY  0x97
+#define SD_OP_FLUSH_DEL_CACHE  0x98
 
 #define SD_FLAG_CMD_IO_LOCAL   0x0010
 #define SD_FLAG_CMD_RECOVERY 0x0020
diff --git a/sheep/ops.c b/sheep/ops.c
index b6f8eb2..9cd6633 100644
--- a/sheep/ops.c
+++ b/sheep/ops.c
@@ -617,6 +617,20 @@ static int local_flush_vdi(const struct sd_req *req, struct sd_rsp *rsp, void *d
 	return SD_RES_SUCCESS;
 }
 
+static int local_flush_and_del(const struct sd_req *req, struct sd_rsp *rsp, void *data)
+{
+	struct sd_obj_req *hdr = (struct sd_obj_req *)req;
+	uint64_t oid = hdr->oid;
+	uint32_t vid = oid_to_vid(oid);
+	struct object_cache *cache = find_object_cache(vid, 0);
+
+	if (cache)
+		if (object_cache_flush_and_delete(cache) < 0)
+			return SD_RES_EIO;
+
+	return SD_RES_SUCCESS;
+}
+
 static int local_trace_ops(const struct sd_req *req, struct sd_rsp *rsp, void *data)
 {
 	int enable = req->data_length, ret;
@@ -1007,6 +1021,11 @@ static struct sd_op_template sd_ops[] = {
 		.process_work = local_flush_vdi,
 	},
 
+	[SD_OP_FLUSH_DEL_CACHE] = {
+		.type = SD_OP_TYPE_LOCAL,
+		.process_work = local_flush_and_del,
+	},
+
 	[SD_OP_TRACE] = {
 		.type = SD_OP_TYPE_LOCAL,
 		.force = 1,
diff --git a/sheep/sheepfs/VDI.c b/sheep/sheepfs/VDI.c
index 00c5b7d..84f28e1 100644
--- a/sheep/sheepfs/VDI.c
+++ b/sheep/sheepfs/VDI.c
@@ -16,6 +16,7 @@
 #define PATH_VDI	"/vdi"
 #define PATH_VDI_LIST	"/vdi/list"
 #define PATH_VDI_MOUNT	"/vdi/mount"
+#define PATH_VDI_UNMOUNT  "/vdi/unmount"
 
 int create_vdi_layout(void)
 {
@@ -32,6 +33,11 @@ int create_vdi_layout(void)
 	if (sheepfs_set_op(PATH_VDI_MOUNT, OP_VDI_MOUNT) < 0)
 		return -1;
 
+	if (shadow_file_create(PATH_VDI_UNMOUNT) < 0)
+		return -1;
+	if (sheepfs_set_op(PATH_VDI_UNMOUNT, OP_VDI_UNMOUNT) < 0)
+		return -1;
+
 	return 0;
 }
 
@@ -60,3 +66,11 @@ int vdi_mount_write(const char *path, const char *buf, size_t size,
 		return -EIO;
 	return size;
 }
+
+int vdi_unmount_write(const char *path, const char *buf, size_t size,
+		      off_t ignore)
+{
+	if (volume_remove_entry(buf) < 0)
+		return -EIO;
+	return size;
+}
diff --git a/sheep/sheepfs/core.c b/sheep/sheepfs/core.c
index 04fb934..02e17d6 100644
--- a/sheep/sheepfs/core.c
+++ b/sheep/sheepfs/core.c
@@ -26,7 +26,8 @@ static struct sheepfs_file_operation {
 	[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_VDI_MOUNT]    = { NULL, vdi_mount_write },
+	[OP_VDI_UNMOUNT]  = { NULL, vdi_unmount_write },
 	[OP_VOLUME]       = { volume_read, volume_write, volume_get_size,
 			      volume_sync, volume_open },
 };
diff --git a/sheep/sheepfs/sheepfs.h b/sheep/sheepfs/sheepfs.h
index a307bc5..fcc00f3 100644
--- a/sheep/sheepfs/sheepfs.h
+++ b/sheep/sheepfs/sheepfs.h
@@ -8,6 +8,7 @@ enum sheepfs_opcode {
 	OP_CLUSTER_INFO,
 	OP_VDI_LIST,
 	OP_VDI_MOUNT,
+	OP_VDI_UNMOUNT,
 	OP_VOLUME,
 };
 
@@ -36,6 +37,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_remove_entry(const char *entry);
 extern int volume_sync(const char *path);
 extern int volume_open(const char *path, struct fuse_file_info *);
 
@@ -50,5 +52,6 @@ extern int vdi_list_read(const char *path, char *buf, size_t size, off_t);
 extern size_t vdi_list_get_size(const char *path);
 
 extern int vdi_mount_write(const char *, const char *buf, size_t size, off_t);
+extern int vdi_unmount_write(const char *, const char *buf, size_t, off_t);
 
 #endif
diff --git a/sheep/sheepfs/volume.c b/sheep/sheepfs/volume.c
index f9d33e5..5a85ba9 100644
--- a/sheep/sheepfs/volume.c
+++ b/sheep/sheepfs/volume.c
@@ -322,3 +322,47 @@ int volume_create_entry(const char *entry)
 
 	return 0;
 }
+
+static int volume_sync_and_delete(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_DEL_CACHE;
+	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_remove_entry(const char *entry)
+{
+	char path[PATH_MAX], *ch;
+	uint32_t vid;
+
+	ch = strchr(entry, '\n');
+	if (ch != NULL)
+		*ch = '\0';
+
+	sprintf(path, "%s/%s", PATH_VOLUME, entry);
+	if (!shadow_file_exsit(path))
+		return 0;
+
+	if (shadow_file_getxattr(path, SH_VID_NAME, &vid, SH_VID_SIZE) < 0)
+		return -1;
+
+	if (volume_sync_and_delete(vid) < 0)
+		return -1;
+
+	shadow_file_delete(path);
+
+	return 0;
+}
-- 
1.7.8.2




More information about the sheepdog mailing list