aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dcache.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dcache.c')
-rw-r--r--fs/dcache.c178
1 files changed, 128 insertions, 50 deletions
diff --git a/fs/dcache.c b/fs/dcache.c
index 2bac4ba1d1d3..d68631f18df1 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -43,7 +43,7 @@ static __cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock);
43 43
44EXPORT_SYMBOL(dcache_lock); 44EXPORT_SYMBOL(dcache_lock);
45 45
46static kmem_cache_t *dentry_cache __read_mostly; 46static struct kmem_cache *dentry_cache __read_mostly;
47 47
48#define DNAME_INLINE_LEN (sizeof(struct dentry)-offsetof(struct dentry,d_iname)) 48#define DNAME_INLINE_LEN (sizeof(struct dentry)-offsetof(struct dentry,d_iname))
49 49
@@ -68,15 +68,19 @@ struct dentry_stat_t dentry_stat = {
68 .age_limit = 45, 68 .age_limit = 45,
69}; 69};
70 70
71static void d_callback(struct rcu_head *head) 71static void __d_free(struct dentry *dentry)
72{ 72{
73 struct dentry * dentry = container_of(head, struct dentry, d_u.d_rcu);
74
75 if (dname_external(dentry)) 73 if (dname_external(dentry))
76 kfree(dentry->d_name.name); 74 kfree(dentry->d_name.name);
77 kmem_cache_free(dentry_cache, dentry); 75 kmem_cache_free(dentry_cache, dentry);
78} 76}
79 77
78static void d_callback(struct rcu_head *head)
79{
80 struct dentry * dentry = container_of(head, struct dentry, d_u.d_rcu);
81 __d_free(dentry);
82}
83
80/* 84/*
81 * no dcache_lock, please. The caller must decrement dentry_stat.nr_dentry 85 * no dcache_lock, please. The caller must decrement dentry_stat.nr_dentry
82 * inside dcache_lock. 86 * inside dcache_lock.
@@ -85,7 +89,11 @@ static void d_free(struct dentry *dentry)
85{ 89{
86 if (dentry->d_op && dentry->d_op->d_release) 90 if (dentry->d_op && dentry->d_op->d_release)
87 dentry->d_op->d_release(dentry); 91 dentry->d_op->d_release(dentry);
88 call_rcu(&dentry->d_u.d_rcu, d_callback); 92 /* if dentry was never inserted into hash, immediate free is OK */
93 if (dentry->d_hash.pprev == NULL)
94 __d_free(dentry);
95 else
96 call_rcu(&dentry->d_u.d_rcu, d_callback);
89} 97}
90 98
91/* 99/*
@@ -478,11 +486,12 @@ static void prune_dcache(int count, struct super_block *sb)
478 up_read(s_umount); 486 up_read(s_umount);
479 } 487 }
480 spin_unlock(&dentry->d_lock); 488 spin_unlock(&dentry->d_lock);
481 /* Cannot remove the first dentry, and it isn't appropriate 489 /*
482 * to move it to the head of the list, so give up, and try 490 * Insert dentry at the head of the list as inserting at the
483 * later 491 * tail leads to a cycle.
484 */ 492 */
485 break; 493 list_add(&dentry->d_lru, &dentry_unused);
494 dentry_stat.nr_unused++;
486 } 495 }
487 spin_unlock(&dcache_lock); 496 spin_unlock(&dcache_lock);
488} 497}
@@ -556,6 +565,7 @@ repeat:
556static void shrink_dcache_for_umount_subtree(struct dentry *dentry) 565static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
557{ 566{
558 struct dentry *parent; 567 struct dentry *parent;
568 unsigned detached = 0;
559 569
560 BUG_ON(!IS_ROOT(dentry)); 570 BUG_ON(!IS_ROOT(dentry));
561 571
@@ -620,7 +630,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
620 atomic_dec(&parent->d_count); 630 atomic_dec(&parent->d_count);
621 631
622 list_del(&dentry->d_u.d_child); 632 list_del(&dentry->d_u.d_child);
623 dentry_stat.nr_dentry--; /* For d_free, below */ 633 detached++;
624 634
625 inode = dentry->d_inode; 635 inode = dentry->d_inode;
626 if (inode) { 636 if (inode) {
@@ -638,7 +648,7 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
638 * otherwise we ascend to the parent and move to the 648 * otherwise we ascend to the parent and move to the
639 * next sibling if there is one */ 649 * next sibling if there is one */
640 if (!parent) 650 if (!parent)
641 return; 651 goto out;
642 652
643 dentry = parent; 653 dentry = parent;
644 654
@@ -647,6 +657,11 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry)
647 dentry = list_entry(dentry->d_subdirs.next, 657 dentry = list_entry(dentry->d_subdirs.next,
648 struct dentry, d_u.d_child); 658 struct dentry, d_u.d_child);
649 } 659 }
660out:
661 /* several dentries were freed, need to correct nr_dentry */
662 spin_lock(&dcache_lock);
663 dentry_stat.nr_dentry -= detached;
664 spin_unlock(&dcache_lock);
650} 665}
651 666
652/* 667/*
@@ -1469,23 +1484,21 @@ static void switch_names(struct dentry *dentry, struct dentry *target)
1469 * deleted it. 1484 * deleted it.
1470 */ 1485 */
1471 1486
1472/** 1487/*
1473 * d_move - move a dentry 1488 * d_move_locked - move a dentry
1474 * @dentry: entry to move 1489 * @dentry: entry to move
1475 * @target: new dentry 1490 * @target: new dentry
1476 * 1491 *
1477 * Update the dcache to reflect the move of a file name. Negative 1492 * Update the dcache to reflect the move of a file name. Negative
1478 * dcache entries should not be moved in this way. 1493 * dcache entries should not be moved in this way.
1479 */ 1494 */
1480 1495static void d_move_locked(struct dentry * dentry, struct dentry * target)
1481void d_move(struct dentry * dentry, struct dentry * target)
1482{ 1496{
1483 struct hlist_head *list; 1497 struct hlist_head *list;
1484 1498
1485 if (!dentry->d_inode) 1499 if (!dentry->d_inode)
1486 printk(KERN_WARNING "VFS: moving negative dcache entry\n"); 1500 printk(KERN_WARNING "VFS: moving negative dcache entry\n");
1487 1501
1488 spin_lock(&dcache_lock);
1489 write_seqlock(&rename_lock); 1502 write_seqlock(&rename_lock);
1490 /* 1503 /*
1491 * XXXX: do we really need to take target->d_lock? 1504 * XXXX: do we really need to take target->d_lock?
@@ -1536,7 +1549,81 @@ already_unhashed:
1536 fsnotify_d_move(dentry); 1549 fsnotify_d_move(dentry);
1537 spin_unlock(&dentry->d_lock); 1550 spin_unlock(&dentry->d_lock);
1538 write_sequnlock(&rename_lock); 1551 write_sequnlock(&rename_lock);
1552}
1553
1554/**
1555 * d_move - move a dentry
1556 * @dentry: entry to move
1557 * @target: new dentry
1558 *
1559 * Update the dcache to reflect the move of a file name. Negative
1560 * dcache entries should not be moved in this way.
1561 */
1562
1563void d_move(struct dentry * dentry, struct dentry * target)
1564{
1565 spin_lock(&dcache_lock);
1566 d_move_locked(dentry, target);
1567 spin_unlock(&dcache_lock);
1568}
1569
1570/*
1571 * Helper that returns 1 if p1 is a parent of p2, else 0
1572 */
1573static int d_isparent(struct dentry *p1, struct dentry *p2)
1574{
1575 struct dentry *p;
1576
1577 for (p = p2; p->d_parent != p; p = p->d_parent) {
1578 if (p->d_parent == p1)
1579 return 1;
1580 }
1581 return 0;
1582}
1583
1584/*
1585 * This helper attempts to cope with remotely renamed directories
1586 *
1587 * It assumes that the caller is already holding
1588 * dentry->d_parent->d_inode->i_mutex and the dcache_lock
1589 *
1590 * Note: If ever the locking in lock_rename() changes, then please
1591 * remember to update this too...
1592 *
1593 * On return, dcache_lock will have been unlocked.
1594 */
1595static struct dentry *__d_unalias(struct dentry *dentry, struct dentry *alias)
1596{
1597 struct mutex *m1 = NULL, *m2 = NULL;
1598 struct dentry *ret;
1599
1600 /* If alias and dentry share a parent, then no extra locks required */
1601 if (alias->d_parent == dentry->d_parent)
1602 goto out_unalias;
1603
1604 /* Check for loops */
1605 ret = ERR_PTR(-ELOOP);
1606 if (d_isparent(alias, dentry))
1607 goto out_err;
1608
1609 /* See lock_rename() */
1610 ret = ERR_PTR(-EBUSY);
1611 if (!mutex_trylock(&dentry->d_sb->s_vfs_rename_mutex))
1612 goto out_err;
1613 m1 = &dentry->d_sb->s_vfs_rename_mutex;
1614 if (!mutex_trylock(&alias->d_parent->d_inode->i_mutex))
1615 goto out_err;
1616 m2 = &alias->d_parent->d_inode->i_mutex;
1617out_unalias:
1618 d_move_locked(alias, dentry);
1619 ret = alias;
1620out_err:
1539 spin_unlock(&dcache_lock); 1621 spin_unlock(&dcache_lock);
1622 if (m2)
1623 mutex_unlock(m2);
1624 if (m1)
1625 mutex_unlock(m1);
1626 return ret;
1540} 1627}
1541 1628
1542/* 1629/*
@@ -1581,7 +1668,7 @@ static void __d_materialise_dentry(struct dentry *dentry, struct dentry *anon)
1581 */ 1668 */
1582struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode) 1669struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
1583{ 1670{
1584 struct dentry *alias, *actual; 1671 struct dentry *actual;
1585 1672
1586 BUG_ON(!d_unhashed(dentry)); 1673 BUG_ON(!d_unhashed(dentry));
1587 1674
@@ -1593,26 +1680,27 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode)
1593 goto found_lock; 1680 goto found_lock;
1594 } 1681 }
1595 1682
1596 /* See if a disconnected directory already exists as an anonymous root 1683 if (S_ISDIR(inode->i_mode)) {
1597 * that we should splice into the tree instead */ 1684 struct dentry *alias;
1598 if (S_ISDIR(inode->i_mode) && (alias = __d_find_alias(inode, 1))) { 1685
1599 spin_lock(&alias->d_lock); 1686 /* Does an aliased dentry already exist? */
1600 1687 alias = __d_find_alias(inode, 0);
1601 /* Is this a mountpoint that we could splice into our tree? */ 1688 if (alias) {
1602 if (IS_ROOT(alias)) 1689 actual = alias;
1603 goto connect_mountpoint; 1690 /* Is this an anonymous mountpoint that we could splice
1604 1691 * into our tree? */
1605 if (alias->d_name.len == dentry->d_name.len && 1692 if (IS_ROOT(alias)) {
1606 alias->d_parent == dentry->d_parent && 1693 spin_lock(&alias->d_lock);
1607 memcmp(alias->d_name.name, 1694 __d_materialise_dentry(dentry, alias);
1608 dentry->d_name.name, 1695 __d_drop(alias);
1609 dentry->d_name.len) == 0) 1696 goto found;
1610 goto replace_with_alias; 1697 }
1611 1698 /* Nope, but we must(!) avoid directory aliasing */
1612 spin_unlock(&alias->d_lock); 1699 actual = __d_unalias(dentry, alias);
1613 1700 if (IS_ERR(actual))
1614 /* Doh! Seem to be aliasing directories for some reason... */ 1701 dput(alias);
1615 dput(alias); 1702 goto out_nolock;
1703 }
1616 } 1704 }
1617 1705
1618 /* Add a unique reference */ 1706 /* Add a unique reference */
@@ -1628,7 +1716,7 @@ found:
1628 _d_rehash(actual); 1716 _d_rehash(actual);
1629 spin_unlock(&actual->d_lock); 1717 spin_unlock(&actual->d_lock);
1630 spin_unlock(&dcache_lock); 1718 spin_unlock(&dcache_lock);
1631 1719out_nolock:
1632 if (actual == dentry) { 1720 if (actual == dentry) {
1633 security_d_instantiate(dentry, inode); 1721 security_d_instantiate(dentry, inode);
1634 return NULL; 1722 return NULL;
@@ -1637,16 +1725,6 @@ found:
1637 iput(inode); 1725 iput(inode);
1638 return actual; 1726 return actual;
1639 1727
1640 /* Convert the anonymous/root alias into an ordinary dentry */
1641connect_mountpoint:
1642 __d_materialise_dentry(dentry, alias);
1643
1644 /* Replace the candidate dentry with the alias in the tree */
1645replace_with_alias:
1646 __d_drop(alias);
1647 actual = alias;
1648 goto found;
1649
1650shouldnt_be_hashed: 1728shouldnt_be_hashed:
1651 spin_unlock(&dcache_lock); 1729 spin_unlock(&dcache_lock);
1652 BUG(); 1730 BUG();
@@ -2002,10 +2080,10 @@ static void __init dcache_init(unsigned long mempages)
2002} 2080}
2003 2081
2004/* SLAB cache for __getname() consumers */ 2082/* SLAB cache for __getname() consumers */
2005kmem_cache_t *names_cachep __read_mostly; 2083struct kmem_cache *names_cachep __read_mostly;
2006 2084
2007/* SLAB cache for file structures */ 2085/* SLAB cache for file structures */
2008kmem_cache_t *filp_cachep __read_mostly; 2086struct kmem_cache *filp_cachep __read_mostly;
2009 2087
2010EXPORT_SYMBOL(d_genocide); 2088EXPORT_SYMBOL(d_genocide);
2011 2089