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