[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