summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPranith Kumar K <pranithk@gluster.com>2012-06-04 23:23:45 +0530
committerVijay Bellur <vbellur@redhat.com>2012-12-12 00:10:59 -0500
commit37cb91fd48e302816d74eb2571ff4afd4c64e709 (patch)
treea1a97e3d960e62a0289b20384556e6a3d307bc67
parent771276b01995540550c09eae85d2f13618b84eb0 (diff)
Self-heald: Fix inode leak
RCA: There is an inode-leak because inode_link returns linked inode by taking a reference. That needs to be unreffed. Fix: Added the code to perform unrefs. In addition to that updated the loc inode with the linked-inode because that is the best practice. The code to update the input inode's gfid can be removed later, its already removed in master. Tests: Checked that opendir comes with an loc with valid inode Checked that re-opendir happens successfully. Tested index, full self-heal work fine with the fix. BUG: 826580 Change-Id: I0c68192ff98f76152ed112b393d497b8fee93355 Signed-off-by: Pranith Kumar K <pranithk@gluster.com> Reviewed-on: http://review.gluster.org/3518 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Raghavendra Bhat <raghavendra@redhat.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com> Reviewed-on: https://code.engineering.redhat.com/gerrit/1851 Tested-by: Vijay Bellur <vbellur@redhat.com>
-rw-r--r--xlators/cluster/afr/src/afr-self-heald.c41
1 files changed, 29 insertions, 12 deletions
diff --git a/xlators/cluster/afr/src/afr-self-heald.c b/xlators/cluster/afr/src/afr-self-heald.c
index f425572b047..5a2172ce9e9 100644
--- a/xlators/cluster/afr/src/afr-self-heald.c
+++ b/xlators/cluster/afr/src/afr-self-heald.c
@@ -674,6 +674,25 @@ out:
}
int
+_link_inode_update_loc (xlator_t *this, loc_t *loc, struct iatt *iattr)
+{
+ inode_t *link_inode = NULL;
+ int ret = -1;
+
+ link_inode = inode_link (loc->inode, NULL, NULL, iattr);
+ if (link_inode == NULL) {
+ gf_log (this->name, GF_LOG_ERROR, "inode link failed "
+ "on the inode (%s)", uuid_utoa (iattr->ia_gfid));
+ goto out;
+ }
+ inode_unref (loc->inode);
+ loc->inode = link_inode;
+ ret = 0;
+out:
+ return ret;
+}
+
+int
afr_crawl_build_start_loc (xlator_t *this, afr_crawl_data_t *crawl_data,
loc_t *dirloc)
{
@@ -720,7 +739,9 @@ afr_crawl_build_start_loc (xlator_t *this, afr_crawl_data_t *crawl_data,
}
goto out;
}
- inode_link (dirloc->inode, NULL, NULL, &iattr);
+ ret = _link_inode_update_loc (this, dirloc, &iattr);
+ if (ret)
+ goto out;
}
ret = 0;
out:
@@ -806,7 +827,6 @@ _process_entries (xlator_t *this, loc_t *parentloc, gf_dirent_t *entries,
loc_t entry_loc = {0};
fd_t *fd = NULL;
struct iatt iattr = {0};
- inode_t *link_inode = NULL;
list_for_each_entry_safe (entry, tmp, &entries->list, list) {
if (!_crawl_proceed (this, crawl_data->child,
@@ -835,20 +855,17 @@ _process_entries (xlator_t *this, loc_t *parentloc, gf_dirent_t *entries,
ret = crawl_data->process_entry (this, crawl_data, entry,
&entry_loc, parentloc, &iattr);
- if (crawl_data->crawl == INDEX)
- continue;
-
- if (ret || !IA_ISDIR (iattr.ia_type))
+ if (ret)
continue;
- link_inode = inode_link (entry_loc.inode, NULL, NULL, &iattr);
- if (link_inode == NULL) {
- gf_log (this->name, GF_LOG_ERROR, "inode link failed "
- "on the inode (%s)",entry_loc.path);
- ret = -1;
+ ret = _link_inode_update_loc (this, &entry_loc, &iattr);
+ if (ret)
goto out;
- }
+ if (crawl_data->crawl == INDEX)
+ continue;
+ if (!IA_ISDIR (iattr.ia_type))
+ continue;
fd = NULL;
ret = afr_crawl_opendir (this, crawl_data, &fd, &entry_loc);
if (ret)