summaryrefslogtreecommitdiffstats
path: root/libglusterfs
diff options
context:
space:
mode:
authorSoumya Koduri <skoduri@redhat.com>2015-12-31 13:53:54 +0530
committerKaleb KEITHLEY <kkeithle@redhat.com>2016-02-28 14:17:37 -0800
commit29adf166aa5f15202c5fe49369ad4f11df799c5b (patch)
tree54e4fed5f0437e2b9613c1d31fb932b92ee564c2 /libglusterfs
parente0e633cdce7586af92490730257ed7f0cffcff61 (diff)
inode: Retire the inodes from the lru list in inode_table_destroy
Inodes from the lru list are not moved to purge list unless they are retired. Also process the lru list first to unset their parent as we need to unset their dentry entries (the ones which may not be unset during '__inode_passivate' as they were hashed) which in turn shall unref their parent inodes which could be in active list. These parent inodes when unref'ed may well again fall into lru list and if we are at the end of traversing the list, we may miss to delete/retire that entry. Hence traverse the lru list till it gets empty. This is backport of the below patch - http://review.gluster.org/13125 Change-Id: Ib7666e235e9b9644144a7c7933afb5e407e506ca BUG: 1311441 Signed-off-by: Soumya Koduri <skoduri@redhat.com> Reviewed-on: http://review.gluster.org/13125 Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com> Reviewed-by: Raghavendra G <rgowdapp@redhat.com> Reviewed-on: http://review.gluster.org/13527 Smoke: Gluster Build System <jenkins@build.gluster.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.com>
Diffstat (limited to 'libglusterfs')
-rw-r--r--libglusterfs/src/inode.c33
1 files changed, 30 insertions, 3 deletions
diff --git a/libglusterfs/src/inode.c b/libglusterfs/src/inode.c
index 6c3d6e13093..097b6d3ccdf 100644
--- a/libglusterfs/src/inode.c
+++ b/libglusterfs/src/inode.c
@@ -1760,13 +1760,40 @@ inode_table_destroy (inode_table_t *inode_table) {
*/
pthread_mutex_lock (&inode_table->lock);
{
- list_for_each_entry_safe (trav, tmp, &inode_table->active, list) {
- __inode_ref_reduce_by_n (trav, 0);
+ /* Process lru list first as we need to unset their dentry
+ * entries (the ones which may not be unset during
+ * '__inode_passivate' as they were hashed) which in turn
+ * shall unref their parent
+ *
+ * These parent inodes when unref'ed may well again fall
+ * into lru list and if we are at the end of traversing
+ * the list, we may miss to delete/retire that entry. Hence
+ * traverse the lru list till it gets empty.
+ */
+ while (!list_empty (&inode_table->lru)) {
+ list_for_each_entry_safe (trav, tmp, &inode_table->lru,
+ list) {
+ __inode_forget (trav, 0);
+ __inode_retire (trav);
+ }
}
- list_for_each_entry_safe (trav, tmp, &inode_table->lru, list) {
+ list_for_each_entry_safe (trav, tmp, &inode_table->active,
+ list) {
+ /* forget and unref the inode to retire and add it to
+ * purge list. By this time there should not be any
+ * inodes present in the active list except for root
+ * inode. Its a ref_leak otherwise. */
+ if (trav != inode_table->root)
+ gf_msg_callingfn (THIS->name, GF_LOG_WARNING, 0,
+ LG_MSG_REF_COUNT,
+ "Active inode(%p) with refcount"
+ "(%d) found during cleanup",
+ trav, trav->ref);
__inode_forget (trav, 0);
+ __inode_ref_reduce_by_n (trav, 0);
}
+
}
pthread_mutex_unlock (&inode_table->lock);