summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghavendra G <raghavendra@gluster.com>2009-10-08 06:20:50 +0000
committerAnand V. Avati <avati@dev.gluster.com>2009-10-09 00:48:11 -0700
commit59d4142ff1938e3b327fb81bee49402057ae1382 (patch)
tree655ddf92d530fa5168b7ca7c68fce3b4a8396980
parent3949b2828a78e4ecb95edb06f09fb9e7e3e5ce9b (diff)
performance/stat-prefetch: fix memory leaks
- sp_cache_get_inode uses fd_lookup which internally increases the refcount of fd by 1. This needs to be unrefed once we get the cache. - for directories, stat is stored in the inode context in sp_lookup_cbk. but, while doing so, no check was being done for the presence of context in inode, resulting in leak of memory equal to sizeof (struct stat) when multiple lookups happened on the directory. - path constructed in sp_readdir was not freed. Signed-off-by: Anand V. Avati <avati@dev.gluster.com> BUG: 221 (stat prefetch implementation) URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=221
-rw-r--r--xlators/performance/stat-prefetch/src/stat-prefetch.c53
1 files changed, 37 insertions, 16 deletions
diff --git a/xlators/performance/stat-prefetch/src/stat-prefetch.c b/xlators/performance/stat-prefetch/src/stat-prefetch.c
index 31f624ad1..1f309b560 100644
--- a/xlators/performance/stat-prefetch/src/stat-prefetch.c
+++ b/xlators/performance/stat-prefetch/src/stat-prefetch.c
@@ -263,6 +263,8 @@ sp_get_cache_inode (xlator_t *this, inode_t *inode, int32_t pid)
}
cache = sp_get_cache_fd (this, fd);
+
+ fd_unref (fd);
out:
return cache;
}
@@ -365,31 +367,47 @@ sp_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
struct stat *buf, dict_t *dict, struct stat *postparent)
{
struct stat *stbuf = NULL;
- int32_t ret = -1;
+ int32_t ret = -1;
+ uint64_t value = 0;
if (op_ret == -1) {
goto out;
}
if (S_ISDIR (buf->st_mode)) {
- stbuf = CALLOC (1, sizeof (*stbuf));
- if (stbuf == NULL) {
- op_ret = -1;
- op_errno = ENOMEM;
- gf_log (this->name, GF_LOG_ERROR, "out of memory");
- goto out;
- }
+ LOCK (&inode->lock);
+ {
+ ret = __inode_ctx_get (inode, this, &value);
+ if (ret == 0) {
+ stbuf = (struct stat *)(long)value;
+ }
- memcpy (stbuf, buf, sizeof (*stbuf));
- ret = inode_ctx_put (inode, this, (long)stbuf);
- if (ret == -1) {
- op_ret = -1;
+ if (stbuf == NULL) {
+ stbuf = CALLOC (1, sizeof (*stbuf));
+ if (stbuf == NULL) {
+ op_ret = -1;
+ op_errno = ENOMEM;
+ gf_log (this->name, GF_LOG_ERROR,
+ "out of memory");
+ goto unlock;
+ }
- /* FIXME: EINVAL is not correct */
- op_errno = EINVAL;
- FREE (stbuf);
- goto out;
+ ret = __inode_ctx_put (inode, this,
+ (long)stbuf);
+ if (ret == -1) {
+ op_ret = -1;
+
+ /* FIXME: EINVAL is not correct */
+ op_errno = EINVAL;
+ FREE (stbuf);
+ goto unlock;
+ }
+ }
+
+ memcpy (stbuf, buf, sizeof (*stbuf));
}
+ unlock:
+ UNLOCK (&inode->lock);
}
out:
@@ -649,6 +667,9 @@ sp_readdir (call_frame_t *frame, xlator_t *this, fd_t *fd, size_t size,
}
ret = sp_cache_remove_parent_entry (frame, this, path);
+
+ FREE (path);
+
if (ret < 0) {
errno = -ret;
goto unwind;