diff options
Diffstat (limited to 'libglusterfs/src/inode.c')
-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); |