aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
authorNick Piggin <npiggin@kernel.dk>2011-01-07 01:49:43 -0500
committerNick Piggin <npiggin@kernel.dk>2011-01-07 01:50:24 -0500
commitdc0474be3e27463d4d4a2793f82366eed906f223 (patch)
tree41f75e638442cb343bacdcfbabb17ffc3bd5b4ce /fs/dcache.c
parent357f8e658bba8a085c4a5d4331e30894be8096b8 (diff)
fs: dcache rationalise dget variants
dget_locked was a shortcut to avoid the lazy lru manipulation when we already held dcache_lock (lru manipulation was relatively cheap at that point). However, how that the lru lock is an innermost one, we never hold it at any caller, so the lock cost can now be avoided. We already have well working lazy dcache LRU, so it should be fine to defer LRU manipulations to scan time. Signed-off-by: Nick Piggin <npiggin@kernel.dk>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c36
1 files changed, 11 insertions, 25 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 01f016799fd4..b4d2e28eef5b 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -429,32 +429,17 @@ int d_invalidate(struct dentry * dentry)
429EXPORT_SYMBOL(d_invalidate); 429EXPORT_SYMBOL(d_invalidate);
430 430
431/* This must be called with d_lock held */ 431/* This must be called with d_lock held */
432static inline struct dentry * __dget_locked_dlock(struct dentry *dentry) 432static inline void __dget_dlock(struct dentry *dentry)
433{ 433{
434 dentry->d_count++; 434 dentry->d_count++;
435 dentry_lru_del(dentry);
436 return dentry;
437} 435}
438 436
439/* This must be called with d_lock held */ 437static inline void __dget(struct dentry *dentry)
440static inline struct dentry * __dget_locked(struct dentry *dentry)
441{ 438{
442 spin_lock(&dentry->d_lock); 439 spin_lock(&dentry->d_lock);
443 __dget_locked_dlock(dentry); 440 __dget_dlock(dentry);
444 spin_unlock(&dentry->d_lock); 441 spin_unlock(&dentry->d_lock);
445 return dentry;
446}
447
448struct dentry * dget_locked_dlock(struct dentry *dentry)
449{
450 return __dget_locked_dlock(dentry);
451}
452
453struct dentry * dget_locked(struct dentry *dentry)
454{
455 return __dget_locked(dentry);
456} 442}
457EXPORT_SYMBOL(dget_locked);
458 443
459struct dentry *dget_parent(struct dentry *dentry) 444struct dentry *dget_parent(struct dentry *dentry)
460{ 445{
@@ -512,7 +497,7 @@ again:
512 (alias->d_flags & DCACHE_DISCONNECTED)) { 497 (alias->d_flags & DCACHE_DISCONNECTED)) {
513 discon_alias = alias; 498 discon_alias = alias;
514 } else if (!want_discon) { 499 } else if (!want_discon) {
515 __dget_locked_dlock(alias); 500 __dget_dlock(alias);
516 spin_unlock(&alias->d_lock); 501 spin_unlock(&alias->d_lock);
517 return alias; 502 return alias;
518 } 503 }
@@ -525,7 +510,7 @@ again:
525 if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) { 510 if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) {
526 if (IS_ROOT(alias) && 511 if (IS_ROOT(alias) &&
527 (alias->d_flags & DCACHE_DISCONNECTED)) { 512 (alias->d_flags & DCACHE_DISCONNECTED)) {
528 __dget_locked_dlock(alias); 513 __dget_dlock(alias);
529 spin_unlock(&alias->d_lock); 514 spin_unlock(&alias->d_lock);
530 return alias; 515 return alias;
531 } 516 }
@@ -561,7 +546,7 @@ restart:
561 list_for_each_entry(dentry, &inode->i_dentry, d_alias) { 546 list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
562 spin_lock(&dentry->d_lock); 547 spin_lock(&dentry->d_lock);
563 if (!dentry->d_count) { 548 if (!dentry->d_count) {
564 __dget_locked_dlock(dentry); 549 __dget_dlock(dentry);
565 __d_drop(dentry); 550 __d_drop(dentry);
566 spin_unlock(&dentry->d_lock); 551 spin_unlock(&dentry->d_lock);
567 spin_unlock(&dcache_inode_lock); 552 spin_unlock(&dcache_inode_lock);
@@ -1257,7 +1242,8 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
1257 * don't need child lock because it is not subject 1242 * don't need child lock because it is not subject
1258 * to concurrency here 1243 * to concurrency here
1259 */ 1244 */
1260 dentry->d_parent = dget_dlock(parent); 1245 __dget_dlock(parent);
1246 dentry->d_parent = parent;
1261 dentry->d_sb = parent->d_sb; 1247 dentry->d_sb = parent->d_sb;
1262 list_add(&dentry->d_u.d_child, &parent->d_subdirs); 1248 list_add(&dentry->d_u.d_child, &parent->d_subdirs);
1263 spin_unlock(&parent->d_lock); 1249 spin_unlock(&parent->d_lock);
@@ -1360,7 +1346,7 @@ static struct dentry *__d_instantiate_unique(struct dentry *entry,
1360 continue; 1346 continue;
1361 if (memcmp(qstr->name, name, len)) 1347 if (memcmp(qstr->name, name, len))
1362 continue; 1348 continue;
1363 dget_locked(alias); 1349 __dget(alias);
1364 return alias; 1350 return alias;
1365 } 1351 }
1366 1352
@@ -1613,7 +1599,7 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode,
1613 * reference to it, move it in place and use it. 1599 * reference to it, move it in place and use it.
1614 */ 1600 */
1615 new = list_entry(inode->i_dentry.next, struct dentry, d_alias); 1601 new = list_entry(inode->i_dentry.next, struct dentry, d_alias);
1616 dget_locked(new); 1602 __dget(new);
1617 spin_unlock(&dcache_inode_lock); 1603 spin_unlock(&dcache_inode_lock);
1618 security_d_instantiate(found, inode); 1604 security_d_instantiate(found, inode);
1619 d_move(new, found); 1605 d_move(new, found);
@@ -1789,7 +1775,7 @@ int d_validate(struct dentry *dentry, struct dentry *dparent)
1789 list_for_each_entry(child, &dparent->d_subdirs, d_u.d_child) { 1775 list_for_each_entry(child, &dparent->d_subdirs, d_u.d_child) {
1790 if (dentry == child) { 1776 if (dentry == child) {
1791 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); 1777 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
1792 __dget_locked_dlock(dentry); 1778 __dget_dlock(dentry);
1793 spin_unlock(&dentry->d_lock); 1779 spin_unlock(&dentry->d_lock);
1794 spin_unlock(&dparent->d_lock); 1780 spin_unlock(&dparent->d_lock);
1795 return 1; 1781 return 1;