diff options
-rw-r--r-- | api/src/glfs-fops.c | 164 |
1 files changed, 131 insertions, 33 deletions
diff --git a/api/src/glfs-fops.c b/api/src/glfs-fops.c index 396f18ccf5f..e6adea5ea9f 100644 --- a/api/src/glfs-fops.c +++ b/api/src/glfs-fops.c @@ -34,7 +34,7 @@ struct upcall_syncop_args { struct glfs *fs; - struct glfs_upcall *up_arg; + struct gf_upcall upcall_data; }; #define READDIRBUF_SIZE (sizeof(struct dirent) + GF_NAME_MAX + 1) @@ -5716,8 +5716,28 @@ out: static int upcall_syncop_args_free(struct upcall_syncop_args *args) { - if (args && args->up_arg) - GLFS_FREE(args->up_arg); + dict_t *dict = NULL; + struct gf_upcall *upcall_data = NULL; + + if (args) { + upcall_data = &args->upcall_data; + switch (upcall_data->event_type) { + case GF_UPCALL_CACHE_INVALIDATION: + dict = ((struct gf_upcall_cache_invalidation *)(upcall_data + ->data)) + ->dict; + break; + case GF_UPCALL_RECALL_LEASE: + dict = ((struct gf_upcall_recall_lease *)(upcall_data->data)) + ->dict; + break; + } + if (dict) + dict_unref(dict); + + GF_FREE(upcall_data->client_uid); + GF_FREE(upcall_data->data); + } GF_FREE(args); return 0; } @@ -5727,14 +5747,7 @@ glfs_upcall_syncop_cbk(int ret, call_frame_t *frame, void *opaque) { struct upcall_syncop_args *args = opaque; - /* Here we not using upcall_syncop_args_free as application - * will be cleaning up the args->up_arg using glfs_free - * post processing upcall. - */ - if (ret) { - upcall_syncop_args_free(args); - } else - GF_FREE(args); + (void)upcall_syncop_args_free(args); return 0; } @@ -5743,29 +5756,17 @@ static int glfs_cbk_upcall_syncop(void *opaque) { struct upcall_syncop_args *args = opaque; + struct gf_upcall *upcall_data = NULL; struct glfs_upcall *up_arg = NULL; struct glfs *fs; + int ret = -1; fs = args->fs; - up_arg = args->up_arg; - - if (fs->up_cbk && up_arg) { - (fs->up_cbk)(up_arg, fs->up_data); - return 0; - } - - return -1; -} + upcall_data = &args->upcall_data; -static struct upcall_syncop_args * -upcall_syncop_args_init(struct glfs *fs, struct gf_upcall *upcall_data) -{ - struct upcall_syncop_args *args = NULL; - int ret = -1; - struct glfs_upcall *up_arg = NULL; - - if (!fs || !upcall_data) + if (!upcall_data) { goto out; + } up_arg = GLFS_CALLOC(1, sizeof(struct gf_upcall), glfs_release_upcall, glfs_mt_upcall_entry_t); @@ -5795,6 +5796,8 @@ upcall_syncop_args_init(struct glfs *fs, struct gf_upcall *upcall_data) if (up_arg->reason == GLFS_UPCALL_EVENT_NULL) { gf_msg(THIS->name, GF_LOG_DEBUG, errno, API_MSG_INVALID_ENTRY, "Upcall_EVENT_NULL received. Skipping it."); + ret = 0; + GLFS_FREE(up_arg); goto out; } else if (ret) { gf_msg(THIS->name, GF_LOG_ERROR, errno, API_MSG_INVALID_ENTRY, @@ -5802,6 +5805,85 @@ upcall_syncop_args_init(struct glfs *fs, struct gf_upcall *upcall_data) goto out; } + if (fs->up_cbk && up_arg) + (fs->up_cbk)(up_arg, fs->up_data); + + /* application takes care of calling glfs_free on up_arg post + * their processing */ + +out: + return ret; +} + +static struct gf_upcall_cache_invalidation * +gf_copy_cache_invalidation(struct gf_upcall_cache_invalidation *src) +{ + struct gf_upcall_cache_invalidation *dst = NULL; + + if (!src) + goto out; + + dst = GF_CALLOC(1, sizeof(struct gf_upcall_cache_invalidation), + glfs_mt_upcall_entry_t); + + if (!dst) { + gf_msg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_ALLOC_FAILED, + "Upcall entry allocation failed."); + goto out; + } + + dst->flags = src->flags; + dst->expire_time_attr = src->expire_time_attr; + dst->stat = src->stat; + dst->p_stat = src->p_stat; + dst->oldp_stat = src->oldp_stat; + + if (src->dict) + dst->dict = dict_copy_with_ref(src->dict, NULL); + + return dst; +out: + return NULL; +} + +static struct gf_upcall_recall_lease * +gf_copy_recall_lease(struct gf_upcall_recall_lease *src) +{ + struct gf_upcall_recall_lease *dst = NULL; + + if (!src) + goto out; + + dst = GF_CALLOC(1, sizeof(struct gf_upcall_recall_lease), + glfs_mt_upcall_entry_t); + + if (!dst) { + gf_msg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_ALLOC_FAILED, + "Upcall entry allocation failed."); + goto out; + } + + dst->lease_type = src->lease_type; + memcpy(dst->tid, src->tid, 16); + + if (src->dict) + dst->dict = dict_copy_with_ref(src->dict, NULL); + + return dst; +out: + return NULL; +} + +static struct upcall_syncop_args * +upcall_syncop_args_init(struct glfs *fs, struct gf_upcall *upcall_data) +{ + struct upcall_syncop_args *args = NULL; + int ret = -1; + struct gf_upcall *t_data = NULL; + + if (!fs || !upcall_data) + goto out; + args = GF_CALLOC(1, sizeof(struct upcall_syncop_args), glfs_mt_upcall_entry_t); if (!args) { @@ -5819,15 +5901,31 @@ upcall_syncop_args_init(struct glfs *fs, struct gf_upcall *upcall_data) * notification without taking any lock/ref. */ args->fs = fs; - args->up_arg = up_arg; + t_data = &(args->upcall_data); + t_data->client_uid = gf_strdup(upcall_data->client_uid); - /* application takes care of calling glfs_free on up_arg post - * their processing */ + gf_uuid_copy(t_data->gfid, upcall_data->gfid); + t_data->event_type = upcall_data->event_type; + + switch (t_data->event_type) { + case GF_UPCALL_CACHE_INVALIDATION: + t_data->data = gf_copy_cache_invalidation( + (struct gf_upcall_cache_invalidation *)upcall_data->data); + break; + case GF_UPCALL_RECALL_LEASE: + t_data->data = gf_copy_recall_lease( + (struct gf_upcall_recall_lease *)upcall_data->data); + break; + } + + if (!t_data->data) + goto out; return args; out: - if (up_arg) { - GLFS_FREE(up_arg); + if (ret) { + GF_FREE(args->upcall_data.client_uid); + GF_FREE(args); } return NULL; |