summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanny Couture <couture.danny@gmail.com>2017-07-05 09:55:17 -0400
committerRaghavendra Talur <rtalur@redhat.com>2017-07-19 21:33:34 +0000
commit904c211802e1d834ec05c21831aa5b51a416341c (patch)
tree55ccf8c2723279b4a04f8095f6168cd828b062d1
parent9925b00d01fad2837359efc003cd7f00c4f8e56c (diff)
fuse: memory leak fixes
Fix fuse ctx memory leak in case an error occurs and the cleanup path is different than usual. Also fix a memory leak in logging if eh_save_history() fails. Cherry picked from commit 5ee383fed9f6408d303aa539dda071275021f8e4: > Change-Id: I7ec967c807b0ed91184e5b958be70702215c46c9 > BUG: 1470220 > Signed-off-by: Danny Couture <couture.danny@gmail.com> > Reviewed-on: https://review.gluster.org/17759 > Reviewed-by: Niels de Vos <ndevos@redhat.com> > Smoke: Gluster Build System <jenkins@build.gluster.org> > Reviewed-by: N Balachandran <nbalacha@redhat.com> > Reviewed-by: Prashanth Pai <ppai@redhat.com> > Reviewed-by: Amar Tumballi <amarts@redhat.com> > Tested-by: Amar Tumballi <amarts@redhat.com> > CentOS-regression: Gluster Build System <jenkins@build.gluster.org> > Reviewed-by: Raghavendra G <rgowdapp@redhat.com> Change-Id: I7ec967c807b0ed91184e5b958be70702215c46c9 BUG: 1471028 Signed-off-by: Niels de Vos <ndevos@redhat.com> Reviewed-on: https://review.gluster.org/17758 Smoke: Gluster Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org>
-rw-r--r--libglusterfs/src/logging.c2
-rw-r--r--xlators/mount/fuse/src/fuse-bridge.c68
2 files changed, 32 insertions, 38 deletions
diff --git a/libglusterfs/src/logging.c b/libglusterfs/src/logging.c
index 55cf2e97d2c..efaa44da653 100644
--- a/libglusterfs/src/logging.c
+++ b/libglusterfs/src/logging.c
@@ -2304,6 +2304,8 @@ _gf_log_eh (const char *function, const char *fmt, ...)
strcat (msg, str2);
ret = eh_save_history (this->history, msg);
+ if (ret < 0)
+ GF_FREE (msg);
out:
GF_FREE (str1);
diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c
index 6c4b02900ef..2a23a85bd68 100644
--- a/xlators/mount/fuse/src/fuse-bridge.c
+++ b/xlators/mount/fuse/src/fuse-bridge.c
@@ -113,6 +113,28 @@ out:
return fd_ctx;
}
+static void
+fuse_fd_ctx_destroy (xlator_t *this, fd_t *fd)
+{
+ fd_t *activefd = NULL;
+ uint64_t val = 0;
+ int ret = 0;
+ fuse_fd_ctx_t *fdctx = NULL;
+
+ ret = fd_ctx_del (fd, this, &val);
+ if (!ret) {
+ fdctx = (fuse_fd_ctx_t *)(unsigned long)val;
+ if (fdctx) {
+ activefd = fdctx->activefd;
+ if (activefd) {
+ fd_unref (activefd);
+ }
+
+ GF_FREE (fdctx);
+ }
+ }
+}
+
fuse_fd_ctx_t *
fuse_fd_ctx_get (xlator_t *this, fd_t *fd)
{
@@ -2496,10 +2518,12 @@ fuse_flush (xlator_t *this, fuse_in_header_t *finh, void *msg)
int
fuse_internal_release (xlator_t *this, fd_t *fd)
{
- //This is a place holder function to prevent "xlator does not implement
- //release_cbk" Warning log.
- //Actual release happens as part of fuse_release which gets executed
- //when kernel fuse sends it.
+ /* This is important we cleanup our context here to avoid a leak
+ in case an error occurs and we get cleanup up by
+ call_unwind_error->...->args_wipe instead of the normal path.
+ */
+ fuse_fd_ctx_destroy(this, fd);
+
return 0;
}
@@ -2507,12 +2531,8 @@ static void
fuse_release (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
struct fuse_release_in *fri = msg;
- fd_t *activefd = NULL;
fd_t *fd = NULL;
- uint64_t val = 0;
- int ret = 0;
fuse_state_t *state = NULL;
- fuse_fd_ctx_t *fdctx = NULL;
fuse_private_t *priv = NULL;
GET_STATE (this, finh, state);
@@ -2527,18 +2547,7 @@ fuse_release (xlator_t *this, fuse_in_header_t *finh, void *msg)
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": RELEASE %p", finh->unique, state->fd);
- ret = fd_ctx_del (fd, this, &val);
- if (!ret) {
- fdctx = (fuse_fd_ctx_t *)(unsigned long)val;
- if (fdctx) {
- activefd = fdctx->activefd;
- if (activefd) {
- fd_unref (activefd);
- }
-
- GF_FREE (fdctx);
- }
- }
+ fuse_fd_ctx_destroy(this, state->fd);
fd_unref (fd);
state->fd = NULL;
@@ -2996,11 +3005,7 @@ static void
fuse_releasedir (xlator_t *this, fuse_in_header_t *finh, void *msg)
{
struct fuse_release_in *fri = msg;
- fd_t *activefd = NULL;
- uint64_t val = 0;
- int ret = 0;
fuse_state_t *state = NULL;
- fuse_fd_ctx_t *fdctx = NULL;
fuse_private_t *priv = NULL;
GET_STATE (this, finh, state);
@@ -3015,20 +3020,7 @@ fuse_releasedir (xlator_t *this, fuse_in_header_t *finh, void *msg)
gf_log ("glusterfs-fuse", GF_LOG_TRACE,
"%"PRIu64": RELEASEDIR %p", finh->unique, state->fd);
- ret = fd_ctx_del (state->fd, this, &val);
-
- if (!ret) {
- fdctx = (fuse_fd_ctx_t *)(unsigned long)val;
- if (fdctx) {
- activefd = fdctx->activefd;
- if (activefd) {
- fd_unref (activefd);
- }
-
- GF_FREE (fdctx);
- }
- }
-
+ fuse_fd_ctx_destroy(this, state->fd);
fd_unref (state->fd);
gf_fdptr_put (priv->fdtable, state->fd);