summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSoumya Koduri <skoduri@redhat.com>2015-12-31 13:53:54 +0530
committerRaghavendra G <rgowdapp@redhat.com>2016-02-25 01:31:19 -0800
commit5bfd22123753fb88c1a2ea91ffd4f6767d89f278 (patch)
tree8769ead251d9d3b470ab3b0f96568fe65e5ba752
parentb7d01547dad88aeebc8cc2dbd68839885615bd66 (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. Change-Id: Ib7666e235e9b9644144a7c7933afb5e407e506ca BUG: 1295107 Signed-off-by: Soumya Koduri <skoduri@redhat.com> Reviewed-on: http://review.gluster.org/13125 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> Reviewed-by: Kaleb KEITHLEY <kkeithle@redhat.com> Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
-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 26e0194a761..d66bcb2a038 100644
--- a/libglusterfs/src/inode.c
+++ b/libglusterfs/src/inode.c
@@ -1755,13 +1755,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);