diff options
| -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 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);  | 
