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 |