summaryrefslogtreecommitdiffstats
path: root/api
diff options
context:
space:
mode:
authorSoumya Koduri <skoduri@redhat.com>2018-11-18 23:38:08 +0530
committerShyamsundar Ranganathan <srangana@redhat.com>2018-12-12 12:53:23 +0000
commitb710f812101233c0b25edcb0f59d197bcd9d0026 (patch)
tree66d6ab86a459ef8eac97ffda9eedd6c3512fe4f4 /api
parentf17188e4aa5e02d266cf147cf418e6cc27f5db21 (diff)
gfapi: Offload callback notifications to synctask
Upcall notifications are received from server via epoll and same thread is used to forward these notifications to the application. This may lead to deadlock and hang in the following scenario. Consider if as part of handling these callbacks, application has to do some operations which involve sending I/Os to gfapi stack which inturn have to wait for epoll threads to receive repsonse. Thus this may lead to deadlock if all the epoll threads are waiting to complete these callback notifications. To address it, instead of using epoll thread itself, make use of synctask to send those notificaitons to the application. Change-Id: If614e0d09246e4279b9d1f40d883a32a39c8fd90 updates: bz#1651323 Signed-off-by: Soumya Koduri <skoduri@redhat.com> (cherry picked from commit ad35193718a99494ab1b852ca4cbdf054f73de88)
Diffstat (limited to 'api')
-rw-r--r--api/src/gfapi-messages.h2
-rw-r--r--api/src/glfs-fops.c53
2 files changed, 45 insertions, 10 deletions
diff --git a/api/src/gfapi-messages.h b/api/src/gfapi-messages.h
index 20418627690..03269a1c9d8 100644
--- a/api/src/gfapi-messages.h
+++ b/api/src/gfapi-messages.h
@@ -49,6 +49,6 @@ GLFS_MSGID(API, API_MSG_MEM_ACCT_INIT_FAILED, API_MSG_MASTER_XLATOR_INIT_FAILED,
API_MSG_INODE_LINK_FAILED, API_MSG_STATEDUMP_FAILED,
API_MSG_XREADDIRP_R_FAILED, API_MSG_LOCK_INSERT_MERGE_FAILED,
API_MSG_SETTING_LOCK_TYPE_FAILED, API_MSG_INODE_FIND_FAILED,
- API_MSG_FDCTX_SET_FAILED);
+ API_MSG_FDCTX_SET_FAILED, API_MSG_UPCALL_SYNCOP_FAILED);
#endif /* !_GFAPI_MESSAGES_H__ */
diff --git a/api/src/glfs-fops.c b/api/src/glfs-fops.c
index 104d3ffd4b1..0bb779a7be1 100644
--- a/api/src/glfs-fops.c
+++ b/api/src/glfs-fops.c
@@ -31,6 +31,11 @@
#define GF_NAME_MAX 255
#endif
+struct upcall_syncop_args {
+ struct glfs *fs;
+ struct gf_upcall *upcall_data;
+};
+
#define READDIRBUF_SIZE (sizeof(struct dirent) + GF_NAME_MAX + 1)
typedef void (*glfs_io_cbk34)(glfs_fd_t *fd, ssize_t ret, void *data);
@@ -4863,19 +4868,17 @@ out:
return ret;
}
-static void
-glfs_cbk_upcall_data(struct glfs *fs, struct gf_upcall *upcall_data)
+static int
+glfs_cbk_upcall_syncop(void *opaque)
{
+ struct upcall_syncop_args *args = opaque;
int ret = -1;
struct glfs_upcall *up_arg = NULL;
+ struct glfs *fs;
+ struct gf_upcall *upcall_data;
- if (!fs || !upcall_data)
- goto out;
-
- if (!(fs->upcall_events & upcall_data->event_type)) {
- /* ignore events which application hasn't registered*/
- goto out;
- }
+ fs = args->fs;
+ upcall_data = args->upcall_data;
up_arg = GLFS_CALLOC(1, sizeof(struct gf_upcall), glfs_release_upcall,
glfs_mt_upcall_entry_t);
@@ -4922,6 +4925,38 @@ out:
GLFS_FREE(up_arg);
}
+ return ret;
+}
+
+static void
+glfs_cbk_upcall_data(struct glfs *fs, struct gf_upcall *upcall_data)
+{
+ struct upcall_syncop_args args = {
+ 0,
+ };
+ int ret = -1;
+
+ if (!fs || !upcall_data)
+ goto out;
+
+ if (!(fs->upcall_events & upcall_data->event_type)) {
+ /* ignore events which application hasn't registered*/
+ goto out;
+ }
+
+ args.fs = fs;
+ args.upcall_data = upcall_data;
+
+ ret = synctask_new(THIS->ctx->env, glfs_cbk_upcall_syncop, NULL, NULL,
+ &args);
+ /* should we retry incase of failure? */
+ if (ret) {
+ gf_msg(THIS->name, GF_LOG_ERROR, errno, API_MSG_UPCALL_SYNCOP_FAILED,
+ "Synctak for Upcall event_type(%d) and gfid(%s) failed",
+ upcall_data->event_type, (char *)(upcall_data->gfid));
+ }
+
+out:
return;
}