diff options
Diffstat (limited to 'fs/dcache.c')
| -rw-r--r-- | fs/dcache.c | 15 | 
1 files changed, 11 insertions, 4 deletions
| diff --git a/fs/dcache.c b/fs/dcache.c index 3c6d3113a25..616fedff011 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -243,6 +243,7 @@ static void dentry_lru_add(struct dentry *dentry)  static void __dentry_lru_del(struct dentry *dentry)  {  	list_del_init(&dentry->d_lru); +	dentry->d_flags &= ~DCACHE_SHRINK_LIST;  	dentry->d_sb->s_nr_dentry_unused--;  	dentry_stat.nr_unused--;  } @@ -806,6 +807,7 @@ relock:  			spin_unlock(&dentry->d_lock);  		} else {  			list_move_tail(&dentry->d_lru, &tmp); +			dentry->d_flags |= DCACHE_SHRINK_LIST;  			spin_unlock(&dentry->d_lock);  			if (!--count)  				break; @@ -1097,14 +1099,19 @@ resume:  		/*  		 * move only zero ref count dentries to the dispose list. +		 * +		 * Those which are presently on the shrink list, being processed +		 * by shrink_dentry_list(), shouldn't be moved.  Otherwise the +		 * loop in shrink_dcache_parent() might not make any progress +		 * and loop forever.  		 */ -		if (!dentry->d_count) { +		if (dentry->d_count) { +			dentry_lru_del(dentry); +		} else if (!(dentry->d_flags & DCACHE_SHRINK_LIST)) {  			dentry_lru_move_list(dentry, dispose); +			dentry->d_flags |= DCACHE_SHRINK_LIST;  			found++; -		} else { -			dentry_lru_del(dentry);  		} -  		/*  		 * We can return to the caller if we have found some (this  		 * ensures forward progress). We'll be coming back to find | 
