|
|
50dc83 |
From bd553499909d2d57fd05696dc7604901cef3a36a Mon Sep 17 00:00:00 2001
|
|
|
50dc83 |
From: Soumya Koduri <skoduri@redhat.com>
|
|
|
50dc83 |
Date: Fri, 7 Jun 2019 17:20:15 +0530
|
|
|
50dc83 |
Subject: [PATCH 200/221] gfapi: fix incorrect initialization of upcall syncop
|
|
|
50dc83 |
arguments
|
|
|
50dc83 |
|
|
|
50dc83 |
While sending upcall notifications via synctasks, the argument used to
|
|
|
50dc83 |
carry relevant data for these tasks is not initialized properly. This patch
|
|
|
50dc83 |
is to fix the same.
|
|
|
50dc83 |
|
|
|
50dc83 |
This is backport of below upstream fix -
|
|
|
50dc83 |
mainline: https://review.gluster.org/22839
|
|
|
50dc83 |
release-6: https://review.gluster.org/22871
|
|
|
50dc83 |
|
|
|
50dc83 |
Change-Id: I9fa8f841e71d3c37d3819fbd430382928c07176c
|
|
|
50dc83 |
fixes: bz#1717784
|
|
|
50dc83 |
Signed-off-by: Soumya Koduri <skoduri@redhat.com>
|
|
|
50dc83 |
Reviewed-on: https://code.engineering.redhat.com/gerrit/173508
|
|
|
50dc83 |
Tested-by: RHGS Build Bot <nigelb@redhat.com>
|
|
|
50dc83 |
Reviewed-by: Kaleb Keithley <kkeithle@redhat.com>
|
|
|
50dc83 |
---
|
|
|
50dc83 |
api/src/glfs-fops.c | 109 ++++++++++++++++++++++++++++++++++------------------
|
|
|
50dc83 |
1 file changed, 72 insertions(+), 37 deletions(-)
|
|
|
50dc83 |
|
|
|
50dc83 |
diff --git a/api/src/glfs-fops.c b/api/src/glfs-fops.c
|
|
|
50dc83 |
index 01ba60b..396f18c 100644
|
|
|
50dc83 |
--- a/api/src/glfs-fops.c
|
|
|
50dc83 |
+++ b/api/src/glfs-fops.c
|
|
|
50dc83 |
@@ -34,7 +34,7 @@
|
|
|
50dc83 |
|
|
|
50dc83 |
struct upcall_syncop_args {
|
|
|
50dc83 |
struct glfs *fs;
|
|
|
50dc83 |
- struct gf_upcall *upcall_data;
|
|
|
50dc83 |
+ struct glfs_upcall *up_arg;
|
|
|
50dc83 |
};
|
|
|
50dc83 |
|
|
|
50dc83 |
#define READDIRBUF_SIZE (sizeof(struct dirent) + GF_NAME_MAX + 1)
|
|
|
50dc83 |
@@ -5714,12 +5714,28 @@ out:
|
|
|
50dc83 |
}
|
|
|
50dc83 |
|
|
|
50dc83 |
static int
|
|
|
50dc83 |
+upcall_syncop_args_free(struct upcall_syncop_args *args)
|
|
|
50dc83 |
+{
|
|
|
50dc83 |
+ if (args && args->up_arg)
|
|
|
50dc83 |
+ GLFS_FREE(args->up_arg);
|
|
|
50dc83 |
+ GF_FREE(args);
|
|
|
50dc83 |
+ return 0;
|
|
|
50dc83 |
+}
|
|
|
50dc83 |
+
|
|
|
50dc83 |
+static int
|
|
|
50dc83 |
glfs_upcall_syncop_cbk(int ret, call_frame_t *frame, void *opaque)
|
|
|
50dc83 |
{
|
|
|
50dc83 |
struct upcall_syncop_args *args = opaque;
|
|
|
50dc83 |
|
|
|
50dc83 |
- GF_FREE(args->upcall_data);
|
|
|
50dc83 |
- GF_FREE(args);
|
|
|
50dc83 |
+ /* Here we not using upcall_syncop_args_free as application
|
|
|
50dc83 |
+ * will be cleaning up the args->up_arg using glfs_free
|
|
|
50dc83 |
+ * post processing upcall.
|
|
|
50dc83 |
+ */
|
|
|
50dc83 |
+ if (ret) {
|
|
|
50dc83 |
+ upcall_syncop_args_free(args);
|
|
|
50dc83 |
+ } else
|
|
|
50dc83 |
+ GF_FREE(args);
|
|
|
50dc83 |
+
|
|
|
50dc83 |
return 0;
|
|
|
50dc83 |
}
|
|
|
50dc83 |
|
|
|
50dc83 |
@@ -5727,13 +5743,29 @@ static int
|
|
|
50dc83 |
glfs_cbk_upcall_syncop(void *opaque)
|
|
|
50dc83 |
{
|
|
|
50dc83 |
struct upcall_syncop_args *args = opaque;
|
|
|
50dc83 |
- int ret = -1;
|
|
|
50dc83 |
struct glfs_upcall *up_arg = NULL;
|
|
|
50dc83 |
struct glfs *fs;
|
|
|
50dc83 |
- struct gf_upcall *upcall_data;
|
|
|
50dc83 |
|
|
|
50dc83 |
fs = args->fs;
|
|
|
50dc83 |
- upcall_data = args->upcall_data;
|
|
|
50dc83 |
+ up_arg = args->up_arg;
|
|
|
50dc83 |
+
|
|
|
50dc83 |
+ if (fs->up_cbk && up_arg) {
|
|
|
50dc83 |
+ (fs->up_cbk)(up_arg, fs->up_data);
|
|
|
50dc83 |
+ return 0;
|
|
|
50dc83 |
+ }
|
|
|
50dc83 |
+
|
|
|
50dc83 |
+ return -1;
|
|
|
50dc83 |
+}
|
|
|
50dc83 |
+
|
|
|
50dc83 |
+static struct upcall_syncop_args *
|
|
|
50dc83 |
+upcall_syncop_args_init(struct glfs *fs, struct gf_upcall *upcall_data)
|
|
|
50dc83 |
+{
|
|
|
50dc83 |
+ struct upcall_syncop_args *args = NULL;
|
|
|
50dc83 |
+ int ret = -1;
|
|
|
50dc83 |
+ struct glfs_upcall *up_arg = NULL;
|
|
|
50dc83 |
+
|
|
|
50dc83 |
+ if (!fs || !upcall_data)
|
|
|
50dc83 |
+ goto out;
|
|
|
50dc83 |
|
|
|
50dc83 |
up_arg = GLFS_CALLOC(1, sizeof(struct gf_upcall), glfs_release_upcall,
|
|
|
50dc83 |
glfs_mt_upcall_entry_t);
|
|
|
50dc83 |
@@ -5754,33 +5786,51 @@ glfs_cbk_upcall_syncop(void *opaque)
|
|
|
50dc83 |
errno = EINVAL;
|
|
|
50dc83 |
}
|
|
|
50dc83 |
|
|
|
50dc83 |
- if (!ret && (up_arg->reason != GLFS_UPCALL_EVENT_NULL)) {
|
|
|
50dc83 |
- /* It could so happen that the file which got
|
|
|
50dc83 |
- * upcall notification may have got deleted by
|
|
|
50dc83 |
- * the same client. In such cases up_arg->reason
|
|
|
50dc83 |
- * is set to GLFS_UPCALL_EVENT_NULL. No need to
|
|
|
50dc83 |
- * send upcall then */
|
|
|
50dc83 |
- (fs->up_cbk)(up_arg, fs->up_data);
|
|
|
50dc83 |
- } else if (up_arg->reason == GLFS_UPCALL_EVENT_NULL) {
|
|
|
50dc83 |
+ /* It could so happen that the file which got
|
|
|
50dc83 |
+ * upcall notification may have got deleted by
|
|
|
50dc83 |
+ * the same client. In such cases up_arg->reason
|
|
|
50dc83 |
+ * is set to GLFS_UPCALL_EVENT_NULL. No need to
|
|
|
50dc83 |
+ * send upcall then
|
|
|
50dc83 |
+ */
|
|
|
50dc83 |
+ if (up_arg->reason == GLFS_UPCALL_EVENT_NULL) {
|
|
|
50dc83 |
gf_msg(THIS->name, GF_LOG_DEBUG, errno, API_MSG_INVALID_ENTRY,
|
|
|
50dc83 |
"Upcall_EVENT_NULL received. Skipping it.");
|
|
|
50dc83 |
goto out;
|
|
|
50dc83 |
- } else {
|
|
|
50dc83 |
+ } else if (ret) {
|
|
|
50dc83 |
gf_msg(THIS->name, GF_LOG_ERROR, errno, API_MSG_INVALID_ENTRY,
|
|
|
50dc83 |
"Upcall entry validation failed.");
|
|
|
50dc83 |
goto out;
|
|
|
50dc83 |
}
|
|
|
50dc83 |
|
|
|
50dc83 |
+ args = GF_CALLOC(1, sizeof(struct upcall_syncop_args),
|
|
|
50dc83 |
+ glfs_mt_upcall_entry_t);
|
|
|
50dc83 |
+ if (!args) {
|
|
|
50dc83 |
+ gf_msg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_ALLOC_FAILED,
|
|
|
50dc83 |
+ "Upcall syncop args allocation failed.");
|
|
|
50dc83 |
+ goto out;
|
|
|
50dc83 |
+ }
|
|
|
50dc83 |
+
|
|
|
50dc83 |
+ /* Note: we are not taking any ref on fs here.
|
|
|
50dc83 |
+ * Ideally applications have to unregister for upcall events
|
|
|
50dc83 |
+ * or stop polling for upcall events before performing
|
|
|
50dc83 |
+ * glfs_fini. And as for outstanding synctasks created, we wait
|
|
|
50dc83 |
+ * for all syncenv threads to finish tasks before cleaning up the
|
|
|
50dc83 |
+ * fs->ctx. Hence it seems safe to process these callback
|
|
|
50dc83 |
+ * notification without taking any lock/ref.
|
|
|
50dc83 |
+ */
|
|
|
50dc83 |
+ args->fs = fs;
|
|
|
50dc83 |
+ args->up_arg = up_arg;
|
|
|
50dc83 |
+
|
|
|
50dc83 |
/* application takes care of calling glfs_free on up_arg post
|
|
|
50dc83 |
* their processing */
|
|
|
50dc83 |
- ret = 0;
|
|
|
50dc83 |
|
|
|
50dc83 |
+ return args;
|
|
|
50dc83 |
out:
|
|
|
50dc83 |
- if (ret && up_arg) {
|
|
|
50dc83 |
+ if (up_arg) {
|
|
|
50dc83 |
GLFS_FREE(up_arg);
|
|
|
50dc83 |
}
|
|
|
50dc83 |
|
|
|
50dc83 |
- return 0;
|
|
|
50dc83 |
+ return NULL;
|
|
|
50dc83 |
}
|
|
|
50dc83 |
|
|
|
50dc83 |
static void
|
|
|
50dc83 |
@@ -5797,24 +5847,10 @@ glfs_cbk_upcall_data(struct glfs *fs, struct gf_upcall *upcall_data)
|
|
|
50dc83 |
goto out;
|
|
|
50dc83 |
}
|
|
|
50dc83 |
|
|
|
50dc83 |
- args = GF_CALLOC(1, sizeof(struct upcall_syncop_args),
|
|
|
50dc83 |
- glfs_mt_upcall_entry_t);
|
|
|
50dc83 |
- if (!args) {
|
|
|
50dc83 |
- gf_msg(THIS->name, GF_LOG_ERROR, ENOMEM, API_MSG_ALLOC_FAILED,
|
|
|
50dc83 |
- "Upcall syncop args allocation failed.");
|
|
|
50dc83 |
- goto out;
|
|
|
50dc83 |
- }
|
|
|
50dc83 |
+ args = upcall_syncop_args_init(fs, upcall_data);
|
|
|
50dc83 |
|
|
|
50dc83 |
- /* Note: we are not taking any ref on fs here.
|
|
|
50dc83 |
- * Ideally applications have to unregister for upcall events
|
|
|
50dc83 |
- * or stop polling for upcall events before performing
|
|
|
50dc83 |
- * glfs_fini. And as for outstanding synctasks created, we wait
|
|
|
50dc83 |
- * for all syncenv threads to finish tasks before cleaning up the
|
|
|
50dc83 |
- * fs->ctx. Hence it seems safe to process these callback
|
|
|
50dc83 |
- * notification without taking any lock/ref.
|
|
|
50dc83 |
- */
|
|
|
50dc83 |
- args->fs = fs;
|
|
|
50dc83 |
- args->upcall_data = gf_memdup(upcall_data, sizeof(*upcall_data));
|
|
|
50dc83 |
+ if (!args)
|
|
|
50dc83 |
+ goto out;
|
|
|
50dc83 |
|
|
|
50dc83 |
ret = synctask_new(THIS->ctx->env, glfs_cbk_upcall_syncop,
|
|
|
50dc83 |
glfs_upcall_syncop_cbk, NULL, args);
|
|
|
50dc83 |
@@ -5823,8 +5859,7 @@ glfs_cbk_upcall_data(struct glfs *fs, struct gf_upcall *upcall_data)
|
|
|
50dc83 |
gf_msg(THIS->name, GF_LOG_ERROR, errno, API_MSG_UPCALL_SYNCOP_FAILED,
|
|
|
50dc83 |
"Synctak for Upcall event_type(%d) and gfid(%s) failed",
|
|
|
50dc83 |
upcall_data->event_type, (char *)(upcall_data->gfid));
|
|
|
50dc83 |
- GF_FREE(args->upcall_data);
|
|
|
50dc83 |
- GF_FREE(args);
|
|
|
50dc83 |
+ upcall_syncop_args_free(args);
|
|
|
50dc83 |
}
|
|
|
50dc83 |
|
|
|
50dc83 |
out:
|
|
|
50dc83 |
--
|
|
|
50dc83 |
1.8.3.1
|
|
|
50dc83 |
|