diff options
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 27 |
1 files changed, 10 insertions, 17 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index b692c7e097c5..3199fe6863a8 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -1723,7 +1723,7 @@ EXPORT_SYMBOL(d_add_ci); | |||
1723 | * Do the slow-case of the dentry name compare. | 1723 | * Do the slow-case of the dentry name compare. |
1724 | * | 1724 | * |
1725 | * Unlike the dentry_cmp() function, we need to atomically | 1725 | * Unlike the dentry_cmp() function, we need to atomically |
1726 | * load the name, length and inode information, so that the | 1726 | * load the name and length information, so that the |
1727 | * filesystem can rely on them, and can use the 'name' and | 1727 | * filesystem can rely on them, and can use the 'name' and |
1728 | * 'len' information without worrying about walking off the | 1728 | * 'len' information without worrying about walking off the |
1729 | * end of memory etc. | 1729 | * end of memory etc. |
@@ -1741,22 +1741,18 @@ enum slow_d_compare { | |||
1741 | 1741 | ||
1742 | static noinline enum slow_d_compare slow_dentry_cmp( | 1742 | static noinline enum slow_d_compare slow_dentry_cmp( |
1743 | const struct dentry *parent, | 1743 | const struct dentry *parent, |
1744 | struct inode *inode, | ||
1745 | struct dentry *dentry, | 1744 | struct dentry *dentry, |
1746 | unsigned int seq, | 1745 | unsigned int seq, |
1747 | const struct qstr *name) | 1746 | const struct qstr *name) |
1748 | { | 1747 | { |
1749 | int tlen = dentry->d_name.len; | 1748 | int tlen = dentry->d_name.len; |
1750 | const char *tname = dentry->d_name.name; | 1749 | const char *tname = dentry->d_name.name; |
1751 | struct inode *i = dentry->d_inode; | ||
1752 | 1750 | ||
1753 | if (read_seqcount_retry(&dentry->d_seq, seq)) { | 1751 | if (read_seqcount_retry(&dentry->d_seq, seq)) { |
1754 | cpu_relax(); | 1752 | cpu_relax(); |
1755 | return D_COMP_SEQRETRY; | 1753 | return D_COMP_SEQRETRY; |
1756 | } | 1754 | } |
1757 | if (parent->d_op->d_compare(parent, inode, | 1755 | if (parent->d_op->d_compare(parent, dentry, tlen, tname, name)) |
1758 | dentry, i, | ||
1759 | tlen, tname, name)) | ||
1760 | return D_COMP_NOMATCH; | 1756 | return D_COMP_NOMATCH; |
1761 | return D_COMP_OK; | 1757 | return D_COMP_OK; |
1762 | } | 1758 | } |
@@ -1766,7 +1762,6 @@ static noinline enum slow_d_compare slow_dentry_cmp( | |||
1766 | * @parent: parent dentry | 1762 | * @parent: parent dentry |
1767 | * @name: qstr of name we wish to find | 1763 | * @name: qstr of name we wish to find |
1768 | * @seqp: returns d_seq value at the point where the dentry was found | 1764 | * @seqp: returns d_seq value at the point where the dentry was found |
1769 | * @inode: returns dentry->d_inode when the inode was found valid. | ||
1770 | * Returns: dentry, or NULL | 1765 | * Returns: dentry, or NULL |
1771 | * | 1766 | * |
1772 | * __d_lookup_rcu is the dcache lookup function for rcu-walk name | 1767 | * __d_lookup_rcu is the dcache lookup function for rcu-walk name |
@@ -1793,7 +1788,7 @@ static noinline enum slow_d_compare slow_dentry_cmp( | |||
1793 | */ | 1788 | */ |
1794 | struct dentry *__d_lookup_rcu(const struct dentry *parent, | 1789 | struct dentry *__d_lookup_rcu(const struct dentry *parent, |
1795 | const struct qstr *name, | 1790 | const struct qstr *name, |
1796 | unsigned *seqp, struct inode *inode) | 1791 | unsigned *seqp) |
1797 | { | 1792 | { |
1798 | u64 hashlen = name->hash_len; | 1793 | u64 hashlen = name->hash_len; |
1799 | const unsigned char *str = name->name; | 1794 | const unsigned char *str = name->name; |
@@ -1827,11 +1822,10 @@ struct dentry *__d_lookup_rcu(const struct dentry *parent, | |||
1827 | seqretry: | 1822 | seqretry: |
1828 | /* | 1823 | /* |
1829 | * The dentry sequence count protects us from concurrent | 1824 | * The dentry sequence count protects us from concurrent |
1830 | * renames, and thus protects inode, parent and name fields. | 1825 | * renames, and thus protects parent and name fields. |
1831 | * | 1826 | * |
1832 | * The caller must perform a seqcount check in order | 1827 | * The caller must perform a seqcount check in order |
1833 | * to do anything useful with the returned dentry, | 1828 | * to do anything useful with the returned dentry. |
1834 | * including using the 'd_inode' pointer. | ||
1835 | * | 1829 | * |
1836 | * NOTE! We do a "raw" seqcount_begin here. That means that | 1830 | * NOTE! We do a "raw" seqcount_begin here. That means that |
1837 | * we don't wait for the sequence count to stabilize if it | 1831 | * we don't wait for the sequence count to stabilize if it |
@@ -1845,12 +1839,12 @@ seqretry: | |||
1845 | continue; | 1839 | continue; |
1846 | if (d_unhashed(dentry)) | 1840 | if (d_unhashed(dentry)) |
1847 | continue; | 1841 | continue; |
1848 | *seqp = seq; | ||
1849 | 1842 | ||
1850 | if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) { | 1843 | if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) { |
1851 | if (dentry->d_name.hash != hashlen_hash(hashlen)) | 1844 | if (dentry->d_name.hash != hashlen_hash(hashlen)) |
1852 | continue; | 1845 | continue; |
1853 | switch (slow_dentry_cmp(parent, inode, dentry, seq, name)) { | 1846 | *seqp = seq; |
1847 | switch (slow_dentry_cmp(parent, dentry, seq, name)) { | ||
1854 | case D_COMP_OK: | 1848 | case D_COMP_OK: |
1855 | return dentry; | 1849 | return dentry; |
1856 | case D_COMP_NOMATCH: | 1850 | case D_COMP_NOMATCH: |
@@ -1862,6 +1856,7 @@ seqretry: | |||
1862 | 1856 | ||
1863 | if (dentry->d_name.hash_len != hashlen) | 1857 | if (dentry->d_name.hash_len != hashlen) |
1864 | continue; | 1858 | continue; |
1859 | *seqp = seq; | ||
1865 | if (!dentry_cmp(dentry, str, hashlen_len(hashlen))) | 1860 | if (!dentry_cmp(dentry, str, hashlen_len(hashlen))) |
1866 | return dentry; | 1861 | return dentry; |
1867 | } | 1862 | } |
@@ -1959,9 +1954,7 @@ struct dentry *__d_lookup(const struct dentry *parent, const struct qstr *name) | |||
1959 | if (parent->d_flags & DCACHE_OP_COMPARE) { | 1954 | if (parent->d_flags & DCACHE_OP_COMPARE) { |
1960 | int tlen = dentry->d_name.len; | 1955 | int tlen = dentry->d_name.len; |
1961 | const char *tname = dentry->d_name.name; | 1956 | const char *tname = dentry->d_name.name; |
1962 | if (parent->d_op->d_compare(parent, parent->d_inode, | 1957 | if (parent->d_op->d_compare(parent, dentry, tlen, tname, name)) |
1963 | dentry, dentry->d_inode, | ||
1964 | tlen, tname, name)) | ||
1965 | goto next; | 1958 | goto next; |
1966 | } else { | 1959 | } else { |
1967 | if (dentry->d_name.len != len) | 1960 | if (dentry->d_name.len != len) |
@@ -1998,7 +1991,7 @@ struct dentry *d_hash_and_lookup(struct dentry *dir, struct qstr *name) | |||
1998 | */ | 1991 | */ |
1999 | name->hash = full_name_hash(name->name, name->len); | 1992 | name->hash = full_name_hash(name->name, name->len); |
2000 | if (dir->d_flags & DCACHE_OP_HASH) { | 1993 | if (dir->d_flags & DCACHE_OP_HASH) { |
2001 | int err = dir->d_op->d_hash(dir, dir->d_inode, name); | 1994 | int err = dir->d_op->d_hash(dir, name); |
2002 | if (unlikely(err < 0)) | 1995 | if (unlikely(err < 0)) |
2003 | return ERR_PTR(err); | 1996 | return ERR_PTR(err); |
2004 | } | 1997 | } |