summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghavendra G <rgowdapp@redhat.com>2015-06-26 11:53:11 +0530
committerRaghavendra G <rgowdapp@redhat.com>2015-07-01 03:55:44 -0700
commit1701239a4ef34c1780e2aa9cbc2843626bf61e2f (patch)
tree6aea79abb734fe81aaa2c75c96a978d614f53186
parentd56b2eecbb7067f11c88d94cc87335040bbad0a3 (diff)
cluster/dht: use refcount to manage memory used to store migration
information. Without refcounting, we might free up memory while other fops are still accessing it. BUG: 1235927 Change-Id: Ia4fa4a651cd6fe2394a0c20cef83c8d2cbc8750f Signed-off-by: Raghavendra G <rgowdapp@redhat.com> Reviewed-on: http://review.gluster.org/11418 Reviewed-by: Shyamsundar Ranganathan <srangana@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: N Balachandran <nbalacha@redhat.com> Tested-by: NetBSD Build System <jenkins@build.gluster.org>
-rw-r--r--xlators/cluster/dht/src/dht-common.h2
-rw-r--r--xlators/cluster/dht/src/dht-helper.c65
2 files changed, 46 insertions, 21 deletions
diff --git a/xlators/cluster/dht/src/dht-common.h b/xlators/cluster/dht/src/dht-common.h
index ad3bd0cd9d6..16e63f36644 100644
--- a/xlators/cluster/dht/src/dht-common.h
+++ b/xlators/cluster/dht/src/dht-common.h
@@ -15,6 +15,7 @@
#include "dht-messages.h"
#include "libxlator.h"
#include "syncop.h"
+#include "refcount.h"
#ifndef _DHT_H
#define _DHT_H
@@ -501,6 +502,7 @@ struct dir_dfmeta {
typedef struct dht_migrate_info {
xlator_t *src_subvol;
xlator_t *dst_subvol;
+ GF_REF_DECL;
} dht_migrate_info_t;
#define ENTRY_MISSING(op_ret, op_errno) (op_ret == -1 && op_errno == ENOENT)
diff --git a/xlators/cluster/dht/src/dht-helper.c b/xlators/cluster/dht/src/dht-helper.c
index afcf2f6592c..bbb0180076b 100644
--- a/xlators/cluster/dht/src/dht-helper.c
+++ b/xlators/cluster/dht/src/dht-helper.c
@@ -14,6 +14,17 @@
#include "dht-common.h"
#include "dht-helper.h"
+void
+dht_free_mig_info (void *data)
+{
+ dht_migrate_info_t *miginfo = NULL;
+
+ miginfo = data;
+ GF_FREE (miginfo);
+
+ return;
+}
+
static inline int
dht_inode_ctx_set_mig_info (xlator_t *this, inode_t *inode,
xlator_t *src_subvol, xlator_t *dst_subvol)
@@ -28,12 +39,13 @@ dht_inode_ctx_set_mig_info (xlator_t *this, inode_t *inode,
miginfo->src_subvol = src_subvol;
miginfo->dst_subvol = dst_subvol;
+ GF_REF_INIT (miginfo, dht_free_mig_info);
value = (uint64_t) miginfo;
ret = inode_ctx_set1 (inode, this, &value);
if (ret < 0) {
- GF_FREE (miginfo);
+ GF_REF_PUT (miginfo);
}
out:
@@ -49,11 +61,18 @@ dht_inode_ctx_get_mig_info (xlator_t *this, inode_t *inode,
uint64_t tmp_miginfo = 0;
dht_migrate_info_t *miginfo = NULL;
- ret = inode_ctx_get1 (inode, this, &tmp_miginfo);
- if ((ret < 0) || (tmp_miginfo == 0))
- goto out;
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_get1 (inode, this, &tmp_miginfo);
+ if ((ret < 0) || (tmp_miginfo == 0)) {
+ UNLOCK (&inode->lock);
+ goto out;
+ }
- miginfo = (dht_migrate_info_t *)tmp_miginfo;
+ miginfo = (dht_migrate_info_t *)tmp_miginfo;
+ GF_REF_GET (miginfo);
+ }
+ UNLOCK (&inode->lock);
if (src_subvol)
*src_subvol = miginfo->src_subvol;
@@ -61,6 +80,8 @@ dht_inode_ctx_get_mig_info (xlator_t *this, inode_t *inode,
if (dst_subvol)
*dst_subvol = miginfo->dst_subvol;
+ GF_REF_PUT (miginfo);
+
out:
return ret;
}
@@ -895,21 +916,22 @@ out:
int
dht_migration_complete_check_task (void *data)
{
- int ret = -1;
- xlator_t *src_node = NULL;
- xlator_t *dst_node = NULL, *linkto_target = NULL;
- dht_local_t *local = NULL;
- dict_t *dict = NULL;
- struct iatt stbuf = {0,};
- xlator_t *this = NULL;
- call_frame_t *frame = NULL;
- loc_t tmp_loc = {0,};
- char *path = NULL;
- dht_conf_t *conf = NULL;
- inode_t *inode = NULL;
- fd_t *iter_fd = NULL;
- uint64_t tmp_miginfo = 0;
- int open_failed = 0;
+ int ret = -1;
+ xlator_t *src_node = NULL;
+ xlator_t *dst_node = NULL, *linkto_target = NULL;
+ dht_local_t *local = NULL;
+ dict_t *dict = NULL;
+ struct iatt stbuf = {0,};
+ xlator_t *this = NULL;
+ call_frame_t *frame = NULL;
+ loc_t tmp_loc = {0,};
+ char *path = NULL;
+ dht_conf_t *conf = NULL;
+ inode_t *inode = NULL;
+ fd_t *iter_fd = NULL;
+ uint64_t tmp_miginfo = 0;
+ dht_migrate_info_t *miginfo = NULL;
+ int open_failed = 0;
this = THIS;
frame = data;
@@ -1005,7 +1027,8 @@ dht_migration_complete_check_task (void *data)
done on all the fd of inode */
ret = inode_ctx_reset1 (inode, this, &tmp_miginfo);
if (tmp_miginfo) {
- GF_FREE ((void *)tmp_miginfo);
+ miginfo = (void *)tmp_miginfo;
+ GF_REF_PUT (miginfo);
goto out;
}