7f4c2a
From 8f811b1ef400035eaf1adf38db24cc33a8726aab Mon Sep 17 00:00:00 2001
7f4c2a
From: Raghavendra G <rgowdapp@redhat.com>
7f4c2a
Date: Fri, 26 Jun 2015 11:53:11 +0530
7f4c2a
Subject: [PATCH 197/200] cluster/dht: use refcount to manage memory used to store migration
7f4c2a
 information.
7f4c2a
7f4c2a
Without refcounting, we might free up memory while other fops are
7f4c2a
still accessing it.
7f4c2a
7f4c2a
BUG: 1238167
7f4c2a
Change-Id: Ia4fa4a651cd6fe2394a0c20cef83c8d2cbc8750f
7f4c2a
Signed-off-by: Raghavendra G <rgowdapp@redhat.com>
7f4c2a
Reviewed-on: http://review.gluster.org/11418
7f4c2a
Reviewed-by: Shyamsundar Ranganathan <srangana@redhat.com>
7f4c2a
Tested-by: Gluster Build System <jenkins@build.gluster.com>
7f4c2a
Reviewed-by: N Balachandran <nbalacha@redhat.com>
7f4c2a
Tested-by: NetBSD Build System <jenkins@build.gluster.org>
7f4c2a
Reviewed-on: https://code.engineering.redhat.com/gerrit/52107
7f4c2a
Reviewed-by: Nithya Balachandran <nbalacha@redhat.com>
7f4c2a
---
7f4c2a
 xlators/cluster/dht/src/dht-common.h |    2 +
7f4c2a
 xlators/cluster/dht/src/dht-helper.c |   65 +++++++++++++++++++++++-----------
7f4c2a
 2 files changed, 46 insertions(+), 21 deletions(-)
7f4c2a
7f4c2a
diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h
7f4c2a
index c04e85d..5e86b32 100644
7f4c2a
--- a/xlators/cluster/dht/src/dht-common.h
7f4c2a
+++ b/xlators/cluster/dht/src/dht-common.h
7f4c2a
@@ -20,6 +20,7 @@
7f4c2a
 #include "dht-messages.h"
7f4c2a
 #include "libxlator.h"
7f4c2a
 #include "syncop.h"
7f4c2a
+#include "refcount.h"
7f4c2a
 
7f4c2a
 #ifndef _DHT_H
7f4c2a
 #define _DHT_H
7f4c2a
@@ -506,6 +507,7 @@ struct dir_dfmeta {
7f4c2a
 typedef struct dht_migrate_info {
7f4c2a
         xlator_t *src_subvol;
7f4c2a
         xlator_t *dst_subvol;
7f4c2a
+        GF_REF_DECL;
7f4c2a
 } dht_migrate_info_t;
7f4c2a
 
7f4c2a
 #define ENTRY_MISSING(op_ret, op_errno) (op_ret == -1 && op_errno == ENOENT)
7f4c2a
diff --git a/xlators/cluster/dht/src/dht-helper.c b/xlators/cluster/dht/src/dht-helper.c
7f4c2a
index 6742f29..d8cc61d 100644
7f4c2a
--- a/xlators/cluster/dht/src/dht-helper.c
7f4c2a
+++ b/xlators/cluster/dht/src/dht-helper.c
7f4c2a
@@ -19,6 +19,17 @@
7f4c2a
 #include "dht-common.h"
7f4c2a
 #include "dht-helper.h"
7f4c2a
 
7f4c2a
+void
7f4c2a
+dht_free_mig_info (void *data)
7f4c2a
+{
7f4c2a
+        dht_migrate_info_t *miginfo = NULL;
7f4c2a
+
7f4c2a
+        miginfo = data;
7f4c2a
+        GF_FREE (miginfo);
7f4c2a
+
7f4c2a
+        return;
7f4c2a
+}
7f4c2a
+
7f4c2a
 static inline int
7f4c2a
 dht_inode_ctx_set_mig_info (xlator_t *this, inode_t *inode,
7f4c2a
                             xlator_t *src_subvol, xlator_t *dst_subvol)
7f4c2a
@@ -33,12 +44,13 @@ dht_inode_ctx_set_mig_info (xlator_t *this, inode_t *inode,
7f4c2a
 
7f4c2a
         miginfo->src_subvol = src_subvol;
7f4c2a
         miginfo->dst_subvol = dst_subvol;
7f4c2a
+        GF_REF_INIT (miginfo, dht_free_mig_info);
7f4c2a
 
7f4c2a
         value = (uint64_t) miginfo;
7f4c2a
 
7f4c2a
         ret = inode_ctx_set1 (inode, this, &value);
7f4c2a
         if (ret < 0) {
7f4c2a
-                GF_FREE (miginfo);
7f4c2a
+                GF_REF_PUT (miginfo);
7f4c2a
         }
7f4c2a
 
7f4c2a
 out:
7f4c2a
@@ -54,11 +66,18 @@ dht_inode_ctx_get_mig_info (xlator_t *this, inode_t *inode,
7f4c2a
         uint64_t            tmp_miginfo = 0;
7f4c2a
         dht_migrate_info_t *miginfo     = NULL;
7f4c2a
 
7f4c2a
-        ret =  inode_ctx_get1 (inode, this, &tmp_miginfo);
7f4c2a
-        if ((ret < 0) || (tmp_miginfo == 0))
7f4c2a
-                goto out;
7f4c2a
+        LOCK (&inode->lock);
7f4c2a
+        {
7f4c2a
+                ret =  __inode_ctx_get1 (inode, this, &tmp_miginfo);
7f4c2a
+                if ((ret < 0) || (tmp_miginfo == 0)) {
7f4c2a
+                        UNLOCK (&inode->lock);
7f4c2a
+                        goto out;
7f4c2a
+                }
7f4c2a
 
7f4c2a
-        miginfo = (dht_migrate_info_t *)tmp_miginfo;
7f4c2a
+                miginfo = (dht_migrate_info_t *)tmp_miginfo;
7f4c2a
+                GF_REF_GET (miginfo);
7f4c2a
+        }
7f4c2a
+        UNLOCK (&inode->lock);
7f4c2a
 
7f4c2a
         if (src_subvol)
7f4c2a
                 *src_subvol = miginfo->src_subvol;
7f4c2a
@@ -66,6 +85,8 @@ dht_inode_ctx_get_mig_info (xlator_t *this, inode_t *inode,
7f4c2a
         if (dst_subvol)
7f4c2a
                 *dst_subvol = miginfo->dst_subvol;
7f4c2a
 
7f4c2a
+        GF_REF_PUT (miginfo);
7f4c2a
+
7f4c2a
 out:
7f4c2a
         return ret;
7f4c2a
 }
7f4c2a
@@ -900,21 +921,22 @@ out:
7f4c2a
 int
7f4c2a
 dht_migration_complete_check_task (void *data)
7f4c2a
 {
7f4c2a
-        int           ret         = -1;
7f4c2a
-        xlator_t     *src_node    = NULL;
7f4c2a
-        xlator_t     *dst_node    = NULL, *linkto_target = NULL;
7f4c2a
-        dht_local_t  *local       = NULL;
7f4c2a
-        dict_t       *dict        = NULL;
7f4c2a
-        struct iatt   stbuf       = {0,};
7f4c2a
-        xlator_t     *this        = NULL;
7f4c2a
-        call_frame_t *frame       = NULL;
7f4c2a
-        loc_t         tmp_loc     = {0,};
7f4c2a
-        char         *path        = NULL;
7f4c2a
-        dht_conf_t   *conf        = NULL;
7f4c2a
-        inode_t      *inode       = NULL;
7f4c2a
-        fd_t         *iter_fd     = NULL;
7f4c2a
-        uint64_t      tmp_miginfo = 0;
7f4c2a
-        int           open_failed = 0;
7f4c2a
+        int                 ret         = -1;
7f4c2a
+        xlator_t           *src_node    = NULL;
7f4c2a
+        xlator_t           *dst_node    = NULL, *linkto_target = NULL;
7f4c2a
+        dht_local_t        *local       = NULL;
7f4c2a
+        dict_t             *dict        = NULL;
7f4c2a
+        struct iatt         stbuf       = {0,};
7f4c2a
+        xlator_t           *this        = NULL;
7f4c2a
+        call_frame_t       *frame       = NULL;
7f4c2a
+        loc_t               tmp_loc     = {0,};
7f4c2a
+        char               *path        = NULL;
7f4c2a
+        dht_conf_t         *conf        = NULL;
7f4c2a
+        inode_t            *inode       = NULL;
7f4c2a
+        fd_t               *iter_fd     = NULL;
7f4c2a
+        uint64_t            tmp_miginfo = 0;
7f4c2a
+        dht_migrate_info_t *miginfo     = NULL;
7f4c2a
+        int                 open_failed = 0;
7f4c2a
 
7f4c2a
         this  = THIS;
7f4c2a
         frame = data;
7f4c2a
@@ -1018,7 +1040,8 @@ dht_migration_complete_check_task (void *data)
7f4c2a
            done on all the fd of inode */
7f4c2a
         ret = inode_ctx_reset1 (inode, this, &tmp_miginfo);
7f4c2a
         if (tmp_miginfo) {
7f4c2a
-                GF_FREE ((void *)tmp_miginfo);
7f4c2a
+                miginfo = (void *)tmp_miginfo;
7f4c2a
+                GF_REF_PUT (miginfo);
7f4c2a
                 goto out;
7f4c2a
         }
7f4c2a
 
7f4c2a
-- 
7f4c2a
1.7.1
7f4c2a