diff options
author | Soumya Koduri <skoduri@redhat.com> | 2015-12-31 13:53:54 +0530 |
---|---|---|
committer | Raghavendra G <rgowdapp@redhat.com> | 2016-02-25 01:31:19 -0800 |
commit | 5bfd22123753fb88c1a2ea91ffd4f6767d89f278 (patch) | |
tree | 8769ead251d9d3b470ab3b0f96568fe65e5ba752 | |
parent | b7d01547dad88aeebc8cc2dbd68839885615bd66 (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.c | 33 |
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); |