diff options
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 6e4ea6d87774..d3902139b533 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -344,6 +344,24 @@ void d_drop(struct dentry *dentry) | |||
344 | EXPORT_SYMBOL(d_drop); | 344 | EXPORT_SYMBOL(d_drop); |
345 | 345 | ||
346 | /* | 346 | /* |
347 | * d_clear_need_lookup - drop a dentry from cache and clear the need lookup flag | ||
348 | * @dentry: dentry to drop | ||
349 | * | ||
350 | * This is called when we do a lookup on a placeholder dentry that needed to be | ||
351 | * looked up. The dentry should have been hashed in order for it to be found by | ||
352 | * the lookup code, but now needs to be unhashed while we do the actual lookup | ||
353 | * and clear the DCACHE_NEED_LOOKUP flag. | ||
354 | */ | ||
355 | void d_clear_need_lookup(struct dentry *dentry) | ||
356 | { | ||
357 | spin_lock(&dentry->d_lock); | ||
358 | __d_drop(dentry); | ||
359 | dentry->d_flags &= ~DCACHE_NEED_LOOKUP; | ||
360 | spin_unlock(&dentry->d_lock); | ||
361 | } | ||
362 | EXPORT_SYMBOL(d_clear_need_lookup); | ||
363 | |||
364 | /* | ||
347 | * Finish off a dentry we've decided to kill. | 365 | * Finish off a dentry we've decided to kill. |
348 | * dentry->d_lock must be held, returns with it unlocked. | 366 | * dentry->d_lock must be held, returns with it unlocked. |
349 | * If ref is non-zero, then decrement the refcount too. | 367 | * If ref is non-zero, then decrement the refcount too. |
@@ -432,8 +450,13 @@ repeat: | |||
432 | if (d_unhashed(dentry)) | 450 | if (d_unhashed(dentry)) |
433 | goto kill_it; | 451 | goto kill_it; |
434 | 452 | ||
435 | /* Otherwise leave it cached and ensure it's on the LRU */ | 453 | /* |
436 | dentry->d_flags |= DCACHE_REFERENCED; | 454 | * If this dentry needs lookup, don't set the referenced flag so that it |
455 | * is more likely to be cleaned up by the dcache shrinker in case of | ||
456 | * memory pressure. | ||
457 | */ | ||
458 | if (!d_need_lookup(dentry)) | ||
459 | dentry->d_flags |= DCACHE_REFERENCED; | ||
437 | dentry_lru_add(dentry); | 460 | dentry_lru_add(dentry); |
438 | 461 | ||
439 | dentry->d_count--; | 462 | dentry->d_count--; |
@@ -1708,6 +1731,13 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode, | |||
1708 | } | 1731 | } |
1709 | 1732 | ||
1710 | /* | 1733 | /* |
1734 | * We are going to instantiate this dentry, unhash it and clear the | ||
1735 | * lookup flag so we can do that. | ||
1736 | */ | ||
1737 | if (unlikely(d_need_lookup(found))) | ||
1738 | d_clear_need_lookup(found); | ||
1739 | |||
1740 | /* | ||
1711 | * Negative dentry: instantiate it unless the inode is a directory and | 1741 | * Negative dentry: instantiate it unless the inode is a directory and |
1712 | * already has a dentry. | 1742 | * already has a dentry. |
1713 | */ | 1743 | */ |