aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-21 18:22:44 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-06-29 04:57:36 -0400
commitda53be12bbb4fabbe2e9f6f908de0cf478b5161d (patch)
treea0436fb462a7b16c82e58336e17c55b814f7be6b /fs
parent642b704cd7a29be0b8900971eb525086c1c995b7 (diff)
Don't pass inode to ->d_hash() and ->d_compare()
Instances either don't look at it at all (the majority of cases) or only want it to find the superblock (which can be had as dentry->d_sb). A few cases that want more are actually safe with dentry->d_inode - the only precaution needed is the check that it hadn't been replaced with NULL by rmdir() or by overwriting rename(), which case should be simply treated as cache miss. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r--fs/adfs/dir.c6
-rw-r--r--fs/affs/namei.c26
-rw-r--r--fs/cifs/dir.c9
-rw-r--r--fs/dcache.c27
-rw-r--r--fs/efivarfs/super.c9
-rw-r--r--fs/fat/namei_msdos.c6
-rw-r--r--fs/fat/namei_vfat.c12
-rw-r--r--fs/gfs2/dentry.c3
-rw-r--r--fs/hfs/hfs_fs.h7
-rw-r--r--fs/hfs/string.c6
-rw-r--r--fs/hfsplus/hfsplus_fs.h7
-rw-r--r--fs/hfsplus/unicode.c7
-rw-r--r--fs/hpfs/dentry.c7
-rw-r--r--fs/isofs/inode.c48
-rw-r--r--fs/isofs/namei.c3
-rw-r--r--fs/jfs/namei.c7
-rw-r--r--fs/namei.c7
-rw-r--r--fs/ncpfs/dir.c32
-rw-r--r--fs/proc/proc_sysctl.c7
-rw-r--r--fs/sysv/namei.c3
20 files changed, 95 insertions, 144 deletions
diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c
index ade28bb058e3..0d138c0de293 100644
--- a/fs/adfs/dir.c
+++ b/fs/adfs/dir.c
@@ -191,8 +191,7 @@ const struct file_operations adfs_dir_operations = {
191}; 191};
192 192
193static int 193static int
194adfs_hash(const struct dentry *parent, const struct inode *inode, 194adfs_hash(const struct dentry *parent, struct qstr *qstr)
195 struct qstr *qstr)
196{ 195{
197 const unsigned int name_len = ADFS_SB(parent->d_sb)->s_namelen; 196 const unsigned int name_len = ADFS_SB(parent->d_sb)->s_namelen;
198 const unsigned char *name; 197 const unsigned char *name;
@@ -228,8 +227,7 @@ adfs_hash(const struct dentry *parent, const struct inode *inode,
228 * requirements of the underlying filesystem. 227 * requirements of the underlying filesystem.
229 */ 228 */
230static int 229static int
231adfs_compare(const struct dentry *parent, const struct inode *pinode, 230adfs_compare(const struct dentry *parent, const struct dentry *dentry,
232 const struct dentry *dentry, const struct inode *inode,
233 unsigned int len, const char *str, const struct qstr *name) 231 unsigned int len, const char *str, const struct qstr *name)
234{ 232{
235 int i; 233 int i;
diff --git a/fs/affs/namei.c b/fs/affs/namei.c
index ff65884a7839..c36cbb4537a2 100644
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -13,18 +13,12 @@
13typedef int (*toupper_t)(int); 13typedef int (*toupper_t)(int);
14 14
15static int affs_toupper(int ch); 15static int affs_toupper(int ch);
16static int affs_hash_dentry(const struct dentry *, 16static int affs_hash_dentry(const struct dentry *, struct qstr *);
17 const struct inode *, struct qstr *); 17static int affs_compare_dentry(const struct dentry *parent, const struct dentry *dentry,
18static int affs_compare_dentry(const struct dentry *parent,
19 const struct inode *pinode,
20 const struct dentry *dentry, const struct inode *inode,
21 unsigned int len, const char *str, const struct qstr *name); 18 unsigned int len, const char *str, const struct qstr *name);
22static int affs_intl_toupper(int ch); 19static int affs_intl_toupper(int ch);
23static int affs_intl_hash_dentry(const struct dentry *, 20static int affs_intl_hash_dentry(const struct dentry *, struct qstr *);
24 const struct inode *, struct qstr *); 21static int affs_intl_compare_dentry(const struct dentry *parent, const struct dentry *dentry,
25static int affs_intl_compare_dentry(const struct dentry *parent,
26 const struct inode *pinode,
27 const struct dentry *dentry, const struct inode *inode,
28 unsigned int len, const char *str, const struct qstr *name); 22 unsigned int len, const char *str, const struct qstr *name);
29 23
30const struct dentry_operations affs_dentry_operations = { 24const struct dentry_operations affs_dentry_operations = {
@@ -86,14 +80,12 @@ __affs_hash_dentry(struct qstr *qstr, toupper_t toupper)
86} 80}
87 81
88static int 82static int
89affs_hash_dentry(const struct dentry *dentry, const struct inode *inode, 83affs_hash_dentry(const struct dentry *dentry, struct qstr *qstr)
90 struct qstr *qstr)
91{ 84{
92 return __affs_hash_dentry(qstr, affs_toupper); 85 return __affs_hash_dentry(qstr, affs_toupper);
93} 86}
94static int 87static int
95affs_intl_hash_dentry(const struct dentry *dentry, const struct inode *inode, 88affs_intl_hash_dentry(const struct dentry *dentry, struct qstr *qstr)
96 struct qstr *qstr)
97{ 89{
98 return __affs_hash_dentry(qstr, affs_intl_toupper); 90 return __affs_hash_dentry(qstr, affs_intl_toupper);
99} 91}
@@ -131,15 +123,13 @@ static inline int __affs_compare_dentry(unsigned int len,
131} 123}
132 124
133static int 125static int
134affs_compare_dentry(const struct dentry *parent, const struct inode *pinode, 126affs_compare_dentry(const struct dentry *parent, const struct dentry *dentry,
135 const struct dentry *dentry, const struct inode *inode,
136 unsigned int len, const char *str, const struct qstr *name) 127 unsigned int len, const char *str, const struct qstr *name)
137{ 128{
138 return __affs_compare_dentry(len, str, name, affs_toupper); 129 return __affs_compare_dentry(len, str, name, affs_toupper);
139} 130}
140static int 131static int
141affs_intl_compare_dentry(const struct dentry *parent,const struct inode *pinode, 132affs_intl_compare_dentry(const struct dentry *parent, const struct dentry *dentry,
142 const struct dentry *dentry, const struct inode *inode,
143 unsigned int len, const char *str, const struct qstr *name) 133 unsigned int len, const char *str, const struct qstr *name)
144{ 134{
145 return __affs_compare_dentry(len, str, name, affs_intl_toupper); 135 return __affs_compare_dentry(len, str, name, affs_intl_toupper);
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 5699b5036ed8..5175aebf6737 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -822,8 +822,7 @@ const struct dentry_operations cifs_dentry_ops = {
822/* d_delete: cifs_d_delete, */ /* not needed except for debugging */ 822/* d_delete: cifs_d_delete, */ /* not needed except for debugging */
823}; 823};
824 824
825static int cifs_ci_hash(const struct dentry *dentry, const struct inode *inode, 825static int cifs_ci_hash(const struct dentry *dentry, struct qstr *q)
826 struct qstr *q)
827{ 826{
828 struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls; 827 struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls;
829 unsigned long hash; 828 unsigned long hash;
@@ -838,12 +837,10 @@ static int cifs_ci_hash(const struct dentry *dentry, const struct inode *inode,
838 return 0; 837 return 0;
839} 838}
840 839
841static int cifs_ci_compare(const struct dentry *parent, 840static int cifs_ci_compare(const struct dentry *parent, const struct dentry *dentry,
842 const struct inode *pinode,
843 const struct dentry *dentry, const struct inode *inode,
844 unsigned int len, const char *str, const struct qstr *name) 841 unsigned int len, const char *str, const struct qstr *name)
845{ 842{
846 struct nls_table *codepage = CIFS_SB(pinode->i_sb)->local_nls; 843 struct nls_table *codepage = CIFS_SB(parent->d_sb)->local_nls;
847 844
848 if ((name->len == len) && 845 if ((name->len == len) &&
849 (nls_strnicmp(codepage, name->name, str, len) == 0)) 846 (nls_strnicmp(codepage, name->name, str, len) == 0))
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
1742static noinline enum slow_d_compare slow_dentry_cmp( 1742static 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 */
1794struct dentry *__d_lookup_rcu(const struct dentry *parent, 1789struct 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,
1827seqretry: 1822seqretry:
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 }
diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c
index 141aee31884f..a8766b880c07 100644
--- a/fs/efivarfs/super.c
+++ b/fs/efivarfs/super.c
@@ -45,8 +45,8 @@ static struct super_block *efivarfs_sb;
45 * So we need to perform a case-sensitive match on part 1 and a 45 * So we need to perform a case-sensitive match on part 1 and a
46 * case-insensitive match on part 2. 46 * case-insensitive match on part 2.
47 */ 47 */
48static int efivarfs_d_compare(const struct dentry *parent, const struct inode *pinode, 48static int efivarfs_d_compare(const struct dentry *parent,
49 const struct dentry *dentry, const struct inode *inode, 49 const struct dentry *dentry,
50 unsigned int len, const char *str, 50 unsigned int len, const char *str,
51 const struct qstr *name) 51 const struct qstr *name)
52{ 52{
@@ -63,8 +63,7 @@ static int efivarfs_d_compare(const struct dentry *parent, const struct inode *p
63 return strncasecmp(name->name + guid, str + guid, EFI_VARIABLE_GUID_LEN); 63 return strncasecmp(name->name + guid, str + guid, EFI_VARIABLE_GUID_LEN);
64} 64}
65 65
66static int efivarfs_d_hash(const struct dentry *dentry, 66static int efivarfs_d_hash(const struct dentry *dentry, struct qstr *qstr)
67 const struct inode *inode, struct qstr *qstr)
68{ 67{
69 unsigned long hash = init_name_hash(); 68 unsigned long hash = init_name_hash();
70 const unsigned char *s = qstr->name; 69 const unsigned char *s = qstr->name;
@@ -108,7 +107,7 @@ static struct dentry *efivarfs_alloc_dentry(struct dentry *parent, char *name)
108 q.name = name; 107 q.name = name;
109 q.len = strlen(name); 108 q.len = strlen(name);
110 109
111 err = efivarfs_d_hash(NULL, NULL, &q); 110 err = efivarfs_d_hash(NULL, &q);
112 if (err) 111 if (err)
113 return ERR_PTR(err); 112 return ERR_PTR(err);
114 113
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
index 081b759cff83..a783b0e1272a 100644
--- a/fs/fat/namei_msdos.c
+++ b/fs/fat/namei_msdos.c
@@ -148,8 +148,7 @@ static int msdos_find(struct inode *dir, const unsigned char *name, int len,
148 * that the existing dentry can be used. The msdos fs routines will 148 * that the existing dentry can be used. The msdos fs routines will
149 * return ENOENT or EINVAL as appropriate. 149 * return ENOENT or EINVAL as appropriate.
150 */ 150 */
151static int msdos_hash(const struct dentry *dentry, const struct inode *inode, 151static int msdos_hash(const struct dentry *dentry, struct qstr *qstr)
152 struct qstr *qstr)
153{ 152{
154 struct fat_mount_options *options = &MSDOS_SB(dentry->d_sb)->options; 153 struct fat_mount_options *options = &MSDOS_SB(dentry->d_sb)->options;
155 unsigned char msdos_name[MSDOS_NAME]; 154 unsigned char msdos_name[MSDOS_NAME];
@@ -165,8 +164,7 @@ static int msdos_hash(const struct dentry *dentry, const struct inode *inode,
165 * Compare two msdos names. If either of the names are invalid, 164 * Compare two msdos names. If either of the names are invalid,
166 * we fall back to doing the standard name comparison. 165 * we fall back to doing the standard name comparison.
167 */ 166 */
168static int msdos_cmp(const struct dentry *parent, const struct inode *pinode, 167static int msdos_cmp(const struct dentry *parent, const struct dentry *dentry,
169 const struct dentry *dentry, const struct inode *inode,
170 unsigned int len, const char *str, const struct qstr *name) 168 unsigned int len, const char *str, const struct qstr *name)
171{ 169{
172 struct fat_mount_options *options = &MSDOS_SB(parent->d_sb)->options; 170 struct fat_mount_options *options = &MSDOS_SB(parent->d_sb)->options;
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index 2da952036a3d..6df8d3d885e5 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -107,8 +107,7 @@ static unsigned int vfat_striptail_len(const struct qstr *qstr)
107 * that the existing dentry can be used. The vfat fs routines will 107 * that the existing dentry can be used. The vfat fs routines will
108 * return ENOENT or EINVAL as appropriate. 108 * return ENOENT or EINVAL as appropriate.
109 */ 109 */
110static int vfat_hash(const struct dentry *dentry, const struct inode *inode, 110static int vfat_hash(const struct dentry *dentry, struct qstr *qstr)
111 struct qstr *qstr)
112{ 111{
113 qstr->hash = full_name_hash(qstr->name, vfat_striptail_len(qstr)); 112 qstr->hash = full_name_hash(qstr->name, vfat_striptail_len(qstr));
114 return 0; 113 return 0;
@@ -120,8 +119,7 @@ static int vfat_hash(const struct dentry *dentry, const struct inode *inode,
120 * that the existing dentry can be used. The vfat fs routines will 119 * that the existing dentry can be used. The vfat fs routines will
121 * return ENOENT or EINVAL as appropriate. 120 * return ENOENT or EINVAL as appropriate.
122 */ 121 */
123static int vfat_hashi(const struct dentry *dentry, const struct inode *inode, 122static int vfat_hashi(const struct dentry *dentry, struct qstr *qstr)
124 struct qstr *qstr)
125{ 123{
126 struct nls_table *t = MSDOS_SB(dentry->d_sb)->nls_io; 124 struct nls_table *t = MSDOS_SB(dentry->d_sb)->nls_io;
127 const unsigned char *name; 125 const unsigned char *name;
@@ -142,8 +140,7 @@ static int vfat_hashi(const struct dentry *dentry, const struct inode *inode,
142/* 140/*
143 * Case insensitive compare of two vfat names. 141 * Case insensitive compare of two vfat names.
144 */ 142 */
145static int vfat_cmpi(const struct dentry *parent, const struct inode *pinode, 143static int vfat_cmpi(const struct dentry *parent, const struct dentry *dentry,
146 const struct dentry *dentry, const struct inode *inode,
147 unsigned int len, const char *str, const struct qstr *name) 144 unsigned int len, const char *str, const struct qstr *name)
148{ 145{
149 struct nls_table *t = MSDOS_SB(parent->d_sb)->nls_io; 146 struct nls_table *t = MSDOS_SB(parent->d_sb)->nls_io;
@@ -162,8 +159,7 @@ static int vfat_cmpi(const struct dentry *parent, const struct inode *pinode,
162/* 159/*
163 * Case sensitive compare of two vfat names. 160 * Case sensitive compare of two vfat names.
164 */ 161 */
165static int vfat_cmp(const struct dentry *parent, const struct inode *pinode, 162static int vfat_cmp(const struct dentry *parent, const struct dentry *dentry,
166 const struct dentry *dentry, const struct inode *inode,
167 unsigned int len, const char *str, const struct qstr *name) 163 unsigned int len, const char *str, const struct qstr *name)
168{ 164{
169 unsigned int alen, blen; 165 unsigned int alen, blen;
diff --git a/fs/gfs2/dentry.c b/fs/gfs2/dentry.c
index 4fddb3c22d25..f2448ab2aac5 100644
--- a/fs/gfs2/dentry.c
+++ b/fs/gfs2/dentry.c
@@ -109,8 +109,7 @@ fail:
109 return 0; 109 return 0;
110} 110}
111 111
112static int gfs2_dhash(const struct dentry *dentry, const struct inode *inode, 112static int gfs2_dhash(const struct dentry *dentry, struct qstr *str)
113 struct qstr *str)
114{ 113{
115 str->hash = gfs2_disk_hash(str->name, str->len); 114 str->hash = gfs2_disk_hash(str->name, str->len);
116 return 0; 115 return 0;
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h
index a73b11839a41..0524cda47a6e 100644
--- a/fs/hfs/hfs_fs.h
+++ b/fs/hfs/hfs_fs.h
@@ -229,13 +229,10 @@ extern int hfs_part_find(struct super_block *, sector_t *, sector_t *);
229/* string.c */ 229/* string.c */
230extern const struct dentry_operations hfs_dentry_operations; 230extern const struct dentry_operations hfs_dentry_operations;
231 231
232extern int hfs_hash_dentry(const struct dentry *, const struct inode *, 232extern int hfs_hash_dentry(const struct dentry *, struct qstr *);
233 struct qstr *);
234extern int hfs_strcmp(const unsigned char *, unsigned int, 233extern int hfs_strcmp(const unsigned char *, unsigned int,
235 const unsigned char *, unsigned int); 234 const unsigned char *, unsigned int);
236extern int hfs_compare_dentry(const struct dentry *parent, 235extern int hfs_compare_dentry(const struct dentry *parent, const struct dentry *dentry,
237 const struct inode *pinode,
238 const struct dentry *dentry, const struct inode *inode,
239 unsigned int len, const char *str, const struct qstr *name); 236 unsigned int len, const char *str, const struct qstr *name);
240 237
241/* trans.c */ 238/* trans.c */
diff --git a/fs/hfs/string.c b/fs/hfs/string.c
index 495a976a3cc9..85b610c3909f 100644
--- a/fs/hfs/string.c
+++ b/fs/hfs/string.c
@@ -51,8 +51,7 @@ static unsigned char caseorder[256] = {
51/* 51/*
52 * Hash a string to an integer in a case-independent way 52 * Hash a string to an integer in a case-independent way
53 */ 53 */
54int hfs_hash_dentry(const struct dentry *dentry, const struct inode *inode, 54int hfs_hash_dentry(const struct dentry *dentry, struct qstr *this)
55 struct qstr *this)
56{ 55{
57 const unsigned char *name = this->name; 56 const unsigned char *name = this->name;
58 unsigned int hash, len = this->len; 57 unsigned int hash, len = this->len;
@@ -93,8 +92,7 @@ int hfs_strcmp(const unsigned char *s1, unsigned int len1,
93 * Test for equality of two strings in the HFS filename character ordering. 92 * Test for equality of two strings in the HFS filename character ordering.
94 * return 1 on failure and 0 on success 93 * return 1 on failure and 0 on success
95 */ 94 */
96int hfs_compare_dentry(const struct dentry *parent, const struct inode *pinode, 95int hfs_compare_dentry(const struct dentry *parent, const struct dentry *dentry,
97 const struct dentry *dentry, const struct inode *inode,
98 unsigned int len, const char *str, const struct qstr *name) 96 unsigned int len, const char *str, const struct qstr *name)
99{ 97{
100 const unsigned char *n1, *n2; 98 const unsigned char *n1, *n2;
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index 60b0a3388b26..ede79317cfb8 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -495,11 +495,8 @@ int hfsplus_uni2asc(struct super_block *,
495 const struct hfsplus_unistr *, char *, int *); 495 const struct hfsplus_unistr *, char *, int *);
496int hfsplus_asc2uni(struct super_block *, 496int hfsplus_asc2uni(struct super_block *,
497 struct hfsplus_unistr *, int, const char *, int); 497 struct hfsplus_unistr *, int, const char *, int);
498int hfsplus_hash_dentry(const struct dentry *dentry, 498int hfsplus_hash_dentry(const struct dentry *dentry, struct qstr *str);
499 const struct inode *inode, struct qstr *str); 499int hfsplus_compare_dentry(const struct dentry *parent, const struct dentry *dentry,
500int hfsplus_compare_dentry(const struct dentry *parent,
501 const struct inode *pinode,
502 const struct dentry *dentry, const struct inode *inode,
503 unsigned int len, const char *str, const struct qstr *name); 500 unsigned int len, const char *str, const struct qstr *name);
504 501
505/* wrapper.c */ 502/* wrapper.c */
diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c
index 2c2e47dcfdd8..e8ef121a4d8b 100644
--- a/fs/hfsplus/unicode.c
+++ b/fs/hfsplus/unicode.c
@@ -334,8 +334,7 @@ int hfsplus_asc2uni(struct super_block *sb,
334 * Composed unicode characters are decomposed and case-folding is performed 334 * Composed unicode characters are decomposed and case-folding is performed
335 * if the appropriate bits are (un)set on the superblock. 335 * if the appropriate bits are (un)set on the superblock.
336 */ 336 */
337int hfsplus_hash_dentry(const struct dentry *dentry, const struct inode *inode, 337int hfsplus_hash_dentry(const struct dentry *dentry, struct qstr *str)
338 struct qstr *str)
339{ 338{
340 struct super_block *sb = dentry->d_sb; 339 struct super_block *sb = dentry->d_sb;
341 const char *astr; 340 const char *astr;
@@ -386,9 +385,7 @@ int hfsplus_hash_dentry(const struct dentry *dentry, const struct inode *inode,
386 * Composed unicode characters are decomposed and case-folding is performed 385 * Composed unicode characters are decomposed and case-folding is performed
387 * if the appropriate bits are (un)set on the superblock. 386 * if the appropriate bits are (un)set on the superblock.
388 */ 387 */
389int hfsplus_compare_dentry(const struct dentry *parent, 388int hfsplus_compare_dentry(const struct dentry *parent, const struct dentry *dentry,
390 const struct inode *pinode,
391 const struct dentry *dentry, const struct inode *inode,
392 unsigned int len, const char *str, const struct qstr *name) 389 unsigned int len, const char *str, const struct qstr *name)
393{ 390{
394 struct super_block *sb = parent->d_sb; 391 struct super_block *sb = parent->d_sb;
diff --git a/fs/hpfs/dentry.c b/fs/hpfs/dentry.c
index 05d4816e4e77..fa27980f2229 100644
--- a/fs/hpfs/dentry.c
+++ b/fs/hpfs/dentry.c
@@ -12,8 +12,7 @@
12 * Note: the dentry argument is the parent dentry. 12 * Note: the dentry argument is the parent dentry.
13 */ 13 */
14 14
15static int hpfs_hash_dentry(const struct dentry *dentry, const struct inode *inode, 15static int hpfs_hash_dentry(const struct dentry *dentry, struct qstr *qstr)
16 struct qstr *qstr)
17{ 16{
18 unsigned long hash; 17 unsigned long hash;
19 int i; 18 int i;
@@ -35,9 +34,7 @@ static int hpfs_hash_dentry(const struct dentry *dentry, const struct inode *ino
35 return 0; 34 return 0;
36} 35}
37 36
38static int hpfs_compare_dentry(const struct dentry *parent, 37static int hpfs_compare_dentry(const struct dentry *parent, const struct dentry *dentry,
39 const struct inode *pinode,
40 const struct dentry *dentry, const struct inode *inode,
41 unsigned int len, const char *str, const struct qstr *name) 38 unsigned int len, const char *str, const struct qstr *name)
42{ 39{
43 unsigned al = len; 40 unsigned al = len;
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index d9b8aebdeb22..c348d6d88624 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -28,31 +28,23 @@
28 28
29#define BEQUIET 29#define BEQUIET
30 30
31static int isofs_hashi(const struct dentry *parent, const struct inode *inode, 31static int isofs_hashi(const struct dentry *parent, struct qstr *qstr);
32 struct qstr *qstr); 32static int isofs_hash(const struct dentry *parent, struct qstr *qstr);
33static int isofs_hash(const struct dentry *parent, const struct inode *inode,
34 struct qstr *qstr);
35static int isofs_dentry_cmpi(const struct dentry *parent, 33static int isofs_dentry_cmpi(const struct dentry *parent,
36 const struct inode *pinode, 34 const struct dentry *dentry,
37 const struct dentry *dentry, const struct inode *inode,
38 unsigned int len, const char *str, const struct qstr *name); 35 unsigned int len, const char *str, const struct qstr *name);
39static int isofs_dentry_cmp(const struct dentry *parent, 36static int isofs_dentry_cmp(const struct dentry *parent,
40 const struct inode *pinode, 37 const struct dentry *dentry,
41 const struct dentry *dentry, const struct inode *inode,
42 unsigned int len, const char *str, const struct qstr *name); 38 unsigned int len, const char *str, const struct qstr *name);
43 39
44#ifdef CONFIG_JOLIET 40#ifdef CONFIG_JOLIET
45static int isofs_hashi_ms(const struct dentry *parent, const struct inode *inode, 41static int isofs_hashi_ms(const struct dentry *parent, struct qstr *qstr);
46 struct qstr *qstr); 42static int isofs_hash_ms(const struct dentry *parent, struct qstr *qstr);
47static int isofs_hash_ms(const struct dentry *parent, const struct inode *inode,
48 struct qstr *qstr);
49static int isofs_dentry_cmpi_ms(const struct dentry *parent, 43static int isofs_dentry_cmpi_ms(const struct dentry *parent,
50 const struct inode *pinode, 44 const struct dentry *dentry,
51 const struct dentry *dentry, const struct inode *inode,
52 unsigned int len, const char *str, const struct qstr *name); 45 unsigned int len, const char *str, const struct qstr *name);
53static int isofs_dentry_cmp_ms(const struct dentry *parent, 46static int isofs_dentry_cmp_ms(const struct dentry *parent,
54 const struct inode *pinode, 47 const struct dentry *dentry,
55 const struct dentry *dentry, const struct inode *inode,
56 unsigned int len, const char *str, const struct qstr *name); 48 unsigned int len, const char *str, const struct qstr *name);
57#endif 49#endif
58 50
@@ -265,30 +257,26 @@ static int isofs_dentry_cmp_common(
265} 257}
266 258
267static int 259static int
268isofs_hash(const struct dentry *dentry, const struct inode *inode, 260isofs_hash(const struct dentry *dentry, struct qstr *qstr)
269 struct qstr *qstr)
270{ 261{
271 return isofs_hash_common(dentry, qstr, 0); 262 return isofs_hash_common(dentry, qstr, 0);
272} 263}
273 264
274static int 265static int
275isofs_hashi(const struct dentry *dentry, const struct inode *inode, 266isofs_hashi(const struct dentry *dentry, struct qstr *qstr)
276 struct qstr *qstr)
277{ 267{
278 return isofs_hashi_common(dentry, qstr, 0); 268 return isofs_hashi_common(dentry, qstr, 0);
279} 269}
280 270
281static int 271static int
282isofs_dentry_cmp(const struct dentry *parent, const struct inode *pinode, 272isofs_dentry_cmp(const struct dentry *parent, const struct dentry *dentry,
283 const struct dentry *dentry, const struct inode *inode,
284 unsigned int len, const char *str, const struct qstr *name) 273 unsigned int len, const char *str, const struct qstr *name)
285{ 274{
286 return isofs_dentry_cmp_common(len, str, name, 0, 0); 275 return isofs_dentry_cmp_common(len, str, name, 0, 0);
287} 276}
288 277
289static int 278static int
290isofs_dentry_cmpi(const struct dentry *parent, const struct inode *pinode, 279isofs_dentry_cmpi(const struct dentry *parent, const struct dentry *dentry,
291 const struct dentry *dentry, const struct inode *inode,
292 unsigned int len, const char *str, const struct qstr *name) 280 unsigned int len, const char *str, const struct qstr *name)
293{ 281{
294 return isofs_dentry_cmp_common(len, str, name, 0, 1); 282 return isofs_dentry_cmp_common(len, str, name, 0, 1);
@@ -296,30 +284,26 @@ isofs_dentry_cmpi(const struct dentry *parent, const struct inode *pinode,
296 284
297#ifdef CONFIG_JOLIET 285#ifdef CONFIG_JOLIET
298static int 286static int
299isofs_hash_ms(const struct dentry *dentry, const struct inode *inode, 287isofs_hash_ms(const struct dentry *dentry, struct qstr *qstr)
300 struct qstr *qstr)
301{ 288{
302 return isofs_hash_common(dentry, qstr, 1); 289 return isofs_hash_common(dentry, qstr, 1);
303} 290}
304 291
305static int 292static int
306isofs_hashi_ms(const struct dentry *dentry, const struct inode *inode, 293isofs_hashi_ms(const struct dentry *dentry, struct qstr *qstr)
307 struct qstr *qstr)
308{ 294{
309 return isofs_hashi_common(dentry, qstr, 1); 295 return isofs_hashi_common(dentry, qstr, 1);
310} 296}
311 297
312static int 298static int
313isofs_dentry_cmp_ms(const struct dentry *parent, const struct inode *pinode, 299isofs_dentry_cmp_ms(const struct dentry *parent, const struct dentry *dentry,
314 const struct dentry *dentry, const struct inode *inode,
315 unsigned int len, const char *str, const struct qstr *name) 300 unsigned int len, const char *str, const struct qstr *name)
316{ 301{
317 return isofs_dentry_cmp_common(len, str, name, 1, 0); 302 return isofs_dentry_cmp_common(len, str, name, 1, 0);
318} 303}
319 304
320static int 305static int
321isofs_dentry_cmpi_ms(const struct dentry *parent, const struct inode *pinode, 306isofs_dentry_cmpi_ms(const struct dentry *parent, const struct dentry *dentry,
322 const struct dentry *dentry, const struct inode *inode,
323 unsigned int len, const char *str, const struct qstr *name) 307 unsigned int len, const char *str, const struct qstr *name)
324{ 308{
325 return isofs_dentry_cmp_common(len, str, name, 1, 1); 309 return isofs_dentry_cmp_common(len, str, name, 1, 1);
diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c
index c167028844ed..95295640d9c8 100644
--- a/fs/isofs/namei.c
+++ b/fs/isofs/namei.c
@@ -37,8 +37,7 @@ isofs_cmp(struct dentry *dentry, const char *compare, int dlen)
37 37
38 qstr.name = compare; 38 qstr.name = compare;
39 qstr.len = dlen; 39 qstr.len = dlen;
40 return dentry->d_op->d_compare(NULL, NULL, NULL, NULL, 40 return dentry->d_op->d_compare(NULL, NULL, dentry->d_name.len, dentry->d_name.name, &qstr);
41 dentry->d_name.len, dentry->d_name.name, &qstr);
42} 41}
43 42
44/* 43/*
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 89186b7b9002..8b19027291d6 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -1538,8 +1538,7 @@ const struct file_operations jfs_dir_operations = {
1538 .llseek = generic_file_llseek, 1538 .llseek = generic_file_llseek,
1539}; 1539};
1540 1540
1541static int jfs_ci_hash(const struct dentry *dir, const struct inode *inode, 1541static int jfs_ci_hash(const struct dentry *dir, struct qstr *this)
1542 struct qstr *this)
1543{ 1542{
1544 unsigned long hash; 1543 unsigned long hash;
1545 int i; 1544 int i;
@@ -1552,9 +1551,7 @@ static int jfs_ci_hash(const struct dentry *dir, const struct inode *inode,
1552 return 0; 1551 return 0;
1553} 1552}
1554 1553
1555static int jfs_ci_compare(const struct dentry *parent, 1554static int jfs_ci_compare(const struct dentry *parent, const struct dentry *dentry,
1556 const struct inode *pinode,
1557 const struct dentry *dentry, const struct inode *inode,
1558 unsigned int len, const char *str, const struct qstr *name) 1555 unsigned int len, const char *str, const struct qstr *name)
1559{ 1556{
1560 int i, result = 1; 1557 int i, result = 1;
diff --git a/fs/namei.c b/fs/namei.c
index 66998b06d822..b2beee7a733f 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1352,7 +1352,7 @@ static int lookup_fast(struct nameidata *nd,
1352 */ 1352 */
1353 if (nd->flags & LOOKUP_RCU) { 1353 if (nd->flags & LOOKUP_RCU) {
1354 unsigned seq; 1354 unsigned seq;
1355 dentry = __d_lookup_rcu(parent, &nd->last, &seq, nd->inode); 1355 dentry = __d_lookup_rcu(parent, &nd->last, &seq);
1356 if (!dentry) 1356 if (!dentry)
1357 goto unlazy; 1357 goto unlazy;
1358 1358
@@ -1787,8 +1787,7 @@ static int link_path_walk(const char *name, struct nameidata *nd)
1787 struct dentry *parent = nd->path.dentry; 1787 struct dentry *parent = nd->path.dentry;
1788 nd->flags &= ~LOOKUP_JUMPED; 1788 nd->flags &= ~LOOKUP_JUMPED;
1789 if (unlikely(parent->d_flags & DCACHE_OP_HASH)) { 1789 if (unlikely(parent->d_flags & DCACHE_OP_HASH)) {
1790 err = parent->d_op->d_hash(parent, nd->inode, 1790 err = parent->d_op->d_hash(parent, &this);
1791 &this);
1792 if (err < 0) 1791 if (err < 0)
1793 break; 1792 break;
1794 } 1793 }
@@ -2121,7 +2120,7 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
2121 * to use its own hash.. 2120 * to use its own hash..
2122 */ 2121 */
2123 if (base->d_flags & DCACHE_OP_HASH) { 2122 if (base->d_flags & DCACHE_OP_HASH) {
2124 int err = base->d_op->d_hash(base, base->d_inode, &this); 2123 int err = base->d_op->d_hash(base, &this);
2125 if (err < 0) 2124 if (err < 0)
2126 return ERR_PTR(err); 2125 return ERR_PTR(err);
2127 } 2126 }
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index 3bc105d36f10..3be047474bfc 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -73,10 +73,8 @@ const struct inode_operations ncp_dir_inode_operations =
73 * Dentry operations routines 73 * Dentry operations routines
74 */ 74 */
75static int ncp_lookup_validate(struct dentry *, unsigned int); 75static int ncp_lookup_validate(struct dentry *, unsigned int);
76static int ncp_hash_dentry(const struct dentry *, const struct inode *, 76static int ncp_hash_dentry(const struct dentry *, struct qstr *);
77 struct qstr *); 77static int ncp_compare_dentry(const struct dentry *, const struct dentry *,
78static int ncp_compare_dentry(const struct dentry *, const struct inode *,
79 const struct dentry *, const struct inode *,
80 unsigned int, const char *, const struct qstr *); 78 unsigned int, const char *, const struct qstr *);
81static int ncp_delete_dentry(const struct dentry *); 79static int ncp_delete_dentry(const struct dentry *);
82 80
@@ -119,11 +117,19 @@ static inline int ncp_case_sensitive(const struct inode *i)
119/* 117/*
120 * Note: leave the hash unchanged if the directory 118 * Note: leave the hash unchanged if the directory
121 * is case-sensitive. 119 * is case-sensitive.
120 *
121 * Accessing the parent inode can be racy under RCU pathwalking.
122 * Use ACCESS_ONCE() to make sure we use _one_ particular inode,
123 * the callers will handle races.
122 */ 124 */
123static int 125static int
124ncp_hash_dentry(const struct dentry *dentry, const struct inode *inode, 126ncp_hash_dentry(const struct dentry *dentry, struct qstr *this)
125 struct qstr *this)
126{ 127{
128 struct inode *inode = ACCESS_ONCE(dentry->d_inode);
129
130 if (!inode)
131 return 0;
132
127 if (!ncp_case_sensitive(inode)) { 133 if (!ncp_case_sensitive(inode)) {
128 struct super_block *sb = dentry->d_sb; 134 struct super_block *sb = dentry->d_sb;
129 struct nls_table *t; 135 struct nls_table *t;
@@ -140,14 +146,24 @@ ncp_hash_dentry(const struct dentry *dentry, const struct inode *inode,
140 return 0; 146 return 0;
141} 147}
142 148
149/*
150 * Accessing the parent inode can be racy under RCU pathwalking.
151 * Use ACCESS_ONCE() to make sure we use _one_ particular inode,
152 * the callers will handle races.
153 */
143static int 154static int
144ncp_compare_dentry(const struct dentry *parent, const struct inode *pinode, 155ncp_compare_dentry(const struct dentry *parent, const struct dentry *dentry,
145 const struct dentry *dentry, const struct inode *inode,
146 unsigned int len, const char *str, const struct qstr *name) 156 unsigned int len, const char *str, const struct qstr *name)
147{ 157{
158 struct inode *pinode;
159
148 if (len != name->len) 160 if (len != name->len)
149 return 1; 161 return 1;
150 162
163 pinode = ACCESS_ONCE(parent->d_inode);
164 if (!pinode)
165 return 1;
166
151 if (ncp_case_sensitive(pinode)) 167 if (ncp_case_sensitive(pinode))
152 return strncmp(str, name->name, len); 168 return strncmp(str, name->name, len);
153 169
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index f3a570e7c257..71290463a1d3 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -796,15 +796,16 @@ static int sysctl_is_seen(struct ctl_table_header *p)
796 return res; 796 return res;
797} 797}
798 798
799static int proc_sys_compare(const struct dentry *parent, 799static int proc_sys_compare(const struct dentry *parent, const struct dentry *dentry,
800 const struct inode *pinode,
801 const struct dentry *dentry, const struct inode *inode,
802 unsigned int len, const char *str, const struct qstr *name) 800 unsigned int len, const char *str, const struct qstr *name)
803{ 801{
804 struct ctl_table_header *head; 802 struct ctl_table_header *head;
803 struct inode *inode;
804
805 /* Although proc doesn't have negative dentries, rcu-walk means 805 /* Although proc doesn't have negative dentries, rcu-walk means
806 * that inode here can be NULL */ 806 * that inode here can be NULL */
807 /* AV: can it, indeed? */ 807 /* AV: can it, indeed? */
808 inode = ACCESS_ONCE(dentry->d_inode);
808 if (!inode) 809 if (!inode)
809 return 1; 810 return 1;
810 if (name->len != len) 811 if (name->len != len)
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c
index 1c0d5f264767..731b2bbcaab3 100644
--- a/fs/sysv/namei.c
+++ b/fs/sysv/namei.c
@@ -27,8 +27,7 @@ static int add_nondir(struct dentry *dentry, struct inode *inode)
27 return err; 27 return err;
28} 28}
29 29
30static int sysv_hash(const struct dentry *dentry, const struct inode *inode, 30static int sysv_hash(const struct dentry *dentry, struct qstr *qstr)
31 struct qstr *qstr)
32{ 31{
33 /* Truncate the name in place, avoids having to define a compare 32 /* Truncate the name in place, avoids having to define a compare
34 function. */ 33 function. */