jblunck@xxxxxxx wrote:
Calling d_genocide() is only lowering the reference count of the dentries but doesn't add them to the unused list. Signed-off-by: Jan Blunck <jblunck@xxxxxxx> --- fs/dcache.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) Index: work-2.6/fs/dcache.c =================================================================== --- work-2.6.orig/fs/dcache.c +++ work-2.6/fs/dcache.c @@ -1612,11 +1612,25 @@ resume: this_parent = dentry; goto repeat; } - atomic_dec(&dentry->d_count); + if (!list_empty(&dentry->d_lru)) { + dentry_stat.nr_unused--; + list_del_init(&dentry->d_lru); + } + if (atomic_dec_and_test(&dentry->d_count)) { + list_add(&dentry->d_lru, dentry_unused.prev); + dentry_stat.nr_unused++; + }
We could have dentries on the LRU list with non-zero d_count. If we have a dentry on the LRU list with a count of 1, then the code will remove it from LRU list and then add it back subsequently. I think the condition below should be an else if
} if (this_parent != root) { next = this_parent->d_u.d_child.next; - atomic_dec(&this_parent->d_count); + if (!list_empty(&this_parent->d_lru)) { + dentry_stat.nr_unused--; + list_del_init(&this_parent->d_lru); + } + if (atomic_dec_and_test(&this_parent->d_count)) { + list_add(&this_parent->d_lru, dentry_unused.prev); + dentry_stat.nr_unused++; + }
Ditto
this_parent = this_parent->d_parent; goto resume; }
d_genocide() now almost looks like select_parent(). I think we can share a lot of code between the two. -- Balbir Singh, Linux Technology Center, IBM Software Labs - To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html