diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-21 18:22:44 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-06-29 04:57:36 -0400 |
commit | da53be12bbb4fabbe2e9f6f908de0cf478b5161d (patch) | |
tree | a0436fb462a7b16c82e58336e17c55b814f7be6b | |
parent | 642b704cd7a29be0b8900971eb525086c1c995b7 (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>
-rw-r--r-- | Documentation/filesystems/Locking | 6 | ||||
-rw-r--r-- | Documentation/filesystems/vfs.txt | 19 | ||||
-rw-r--r-- | fs/adfs/dir.c | 6 | ||||
-rw-r--r-- | fs/affs/namei.c | 26 | ||||
-rw-r--r-- | fs/cifs/dir.c | 9 | ||||
-rw-r--r-- | fs/dcache.c | 27 | ||||
-rw-r--r-- | fs/efivarfs/super.c | 9 | ||||
-rw-r--r-- | fs/fat/namei_msdos.c | 6 | ||||
-rw-r--r-- | fs/fat/namei_vfat.c | 12 | ||||
-rw-r--r-- | fs/gfs2/dentry.c | 3 | ||||
-rw-r--r-- | fs/hfs/hfs_fs.h | 7 | ||||
-rw-r--r-- | fs/hfs/string.c | 6 | ||||
-rw-r--r-- | fs/hfsplus/hfsplus_fs.h | 7 | ||||
-rw-r--r-- | fs/hfsplus/unicode.c | 7 | ||||
-rw-r--r-- | fs/hpfs/dentry.c | 7 | ||||
-rw-r--r-- | fs/isofs/inode.c | 48 | ||||
-rw-r--r-- | fs/isofs/namei.c | 3 | ||||
-rw-r--r-- | fs/jfs/namei.c | 7 | ||||
-rw-r--r-- | fs/namei.c | 7 | ||||
-rw-r--r-- | fs/ncpfs/dir.c | 32 | ||||
-rw-r--r-- | fs/proc/proc_sysctl.c | 7 | ||||
-rw-r--r-- | fs/sysv/namei.c | 3 | ||||
-rw-r--r-- | include/linux/dcache.h | 9 |
23 files changed, 108 insertions, 165 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index bdd82b2339d9..f94a362f408e 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
@@ -11,10 +11,8 @@ be able to use diff(1). | |||
11 | prototypes: | 11 | prototypes: |
12 | int (*d_revalidate)(struct dentry *, unsigned int); | 12 | int (*d_revalidate)(struct dentry *, unsigned int); |
13 | int (*d_weak_revalidate)(struct dentry *, unsigned int); | 13 | int (*d_weak_revalidate)(struct dentry *, unsigned int); |
14 | int (*d_hash)(const struct dentry *, const struct inode *, | 14 | int (*d_hash)(const struct dentry *, struct qstr *); |
15 | struct qstr *); | 15 | int (*d_compare)(const struct dentry *, const struct dentry *, |
16 | int (*d_compare)(const struct dentry *, const struct inode *, | ||
17 | const struct dentry *, const struct inode *, | ||
18 | unsigned int, const char *, const struct qstr *); | 16 | unsigned int, const char *, const struct qstr *); |
19 | int (*d_delete)(struct dentry *); | 17 | int (*d_delete)(struct dentry *); |
20 | void (*d_release)(struct dentry *); | 18 | void (*d_release)(struct dentry *); |
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 4a35f6614a66..51ba44e3fc40 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt | |||
@@ -901,10 +901,8 @@ defined: | |||
901 | struct dentry_operations { | 901 | struct dentry_operations { |
902 | int (*d_revalidate)(struct dentry *, unsigned int); | 902 | int (*d_revalidate)(struct dentry *, unsigned int); |
903 | int (*d_weak_revalidate)(struct dentry *, unsigned int); | 903 | int (*d_weak_revalidate)(struct dentry *, unsigned int); |
904 | int (*d_hash)(const struct dentry *, const struct inode *, | 904 | int (*d_hash)(const struct dentry *, struct qstr *); |
905 | struct qstr *); | 905 | int (*d_compare)(const struct dentry *, const struct dentry *, |
906 | int (*d_compare)(const struct dentry *, const struct inode *, | ||
907 | const struct dentry *, const struct inode *, | ||
908 | unsigned int, const char *, const struct qstr *); | 906 | unsigned int, const char *, const struct qstr *); |
909 | int (*d_delete)(const struct dentry *); | 907 | int (*d_delete)(const struct dentry *); |
910 | void (*d_release)(struct dentry *); | 908 | void (*d_release)(struct dentry *); |
@@ -949,25 +947,24 @@ struct dentry_operations { | |||
949 | 947 | ||
950 | d_hash: called when the VFS adds a dentry to the hash table. The first | 948 | d_hash: called when the VFS adds a dentry to the hash table. The first |
951 | dentry passed to d_hash is the parent directory that the name is | 949 | dentry passed to d_hash is the parent directory that the name is |
952 | to be hashed into. The inode is the dentry's inode. | 950 | to be hashed into. |
953 | 951 | ||
954 | Same locking and synchronisation rules as d_compare regarding | 952 | Same locking and synchronisation rules as d_compare regarding |
955 | what is safe to dereference etc. | 953 | what is safe to dereference etc. |
956 | 954 | ||
957 | d_compare: called to compare a dentry name with a given name. The first | 955 | d_compare: called to compare a dentry name with a given name. The first |
958 | dentry is the parent of the dentry to be compared, the second is | 956 | dentry is the parent of the dentry to be compared, the second is |
959 | the parent's inode, then the dentry and inode (may be NULL) of the | 957 | the child dentry. len and name string are properties of the dentry |
960 | child dentry. len and name string are properties of the dentry to be | 958 | to be compared. qstr is the name to compare it with. |
961 | compared. qstr is the name to compare it with. | ||
962 | 959 | ||
963 | Must be constant and idempotent, and should not take locks if | 960 | Must be constant and idempotent, and should not take locks if |
964 | possible, and should not or store into the dentry or inodes. | 961 | possible, and should not or store into the dentry. |
965 | Should not dereference pointers outside the dentry or inodes without | 962 | Should not dereference pointers outside the dentry without |
966 | lots of care (eg. d_parent, d_inode, d_name should not be used). | 963 | lots of care (eg. d_parent, d_inode, d_name should not be used). |
967 | 964 | ||
968 | However, our vfsmount is pinned, and RCU held, so the dentries and | 965 | However, our vfsmount is pinned, and RCU held, so the dentries and |
969 | inodes won't disappear, neither will our sb or filesystem module. | 966 | inodes won't disappear, neither will our sb or filesystem module. |
970 | ->i_sb and ->d_sb may be used. | 967 | ->d_sb may be used. |
971 | 968 | ||
972 | It is a tricky calling convention because it needs to be called under | 969 | It is a tricky calling convention because it needs to be called under |
973 | "rcu-walk", ie. without any locks or references on things. | 970 | "rcu-walk", ie. without any locks or references on things. |
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 | ||
193 | static int | 193 | static int |
194 | adfs_hash(const struct dentry *parent, const struct inode *inode, | 194 | adfs_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 | */ |
230 | static int | 229 | static int |
231 | adfs_compare(const struct dentry *parent, const struct inode *pinode, | 230 | adfs_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 @@ | |||
13 | typedef int (*toupper_t)(int); | 13 | typedef int (*toupper_t)(int); |
14 | 14 | ||
15 | static int affs_toupper(int ch); | 15 | static int affs_toupper(int ch); |
16 | static int affs_hash_dentry(const struct dentry *, | 16 | static int affs_hash_dentry(const struct dentry *, struct qstr *); |
17 | const struct inode *, struct qstr *); | 17 | static int affs_compare_dentry(const struct dentry *parent, const struct dentry *dentry, |
18 | static 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); |
22 | static int affs_intl_toupper(int ch); | 19 | static int affs_intl_toupper(int ch); |
23 | static int affs_intl_hash_dentry(const struct dentry *, | 20 | static int affs_intl_hash_dentry(const struct dentry *, struct qstr *); |
24 | const struct inode *, struct qstr *); | 21 | static int affs_intl_compare_dentry(const struct dentry *parent, const struct dentry *dentry, |
25 | static 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 | ||
30 | const struct dentry_operations affs_dentry_operations = { | 24 | const struct dentry_operations affs_dentry_operations = { |
@@ -86,14 +80,12 @@ __affs_hash_dentry(struct qstr *qstr, toupper_t toupper) | |||
86 | } | 80 | } |
87 | 81 | ||
88 | static int | 82 | static int |
89 | affs_hash_dentry(const struct dentry *dentry, const struct inode *inode, | 83 | affs_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 | } |
94 | static int | 87 | static int |
95 | affs_intl_hash_dentry(const struct dentry *dentry, const struct inode *inode, | 88 | affs_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 | ||
133 | static int | 125 | static int |
134 | affs_compare_dentry(const struct dentry *parent, const struct inode *pinode, | 126 | affs_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 | } |
140 | static int | 131 | static int |
141 | affs_intl_compare_dentry(const struct dentry *parent,const struct inode *pinode, | 132 | affs_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 | ||
825 | static int cifs_ci_hash(const struct dentry *dentry, const struct inode *inode, | 825 | static 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 | ||
841 | static int cifs_ci_compare(const struct dentry *parent, | 840 | static 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 | ||
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 | } |
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 | */ |
48 | static int efivarfs_d_compare(const struct dentry *parent, const struct inode *pinode, | 48 | static 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 | ||
66 | static int efivarfs_d_hash(const struct dentry *dentry, | 66 | static 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 | */ |
151 | static int msdos_hash(const struct dentry *dentry, const struct inode *inode, | 151 | static 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 | */ |
168 | static int msdos_cmp(const struct dentry *parent, const struct inode *pinode, | 167 | static 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 | */ |
110 | static int vfat_hash(const struct dentry *dentry, const struct inode *inode, | 110 | static 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 | */ |
123 | static int vfat_hashi(const struct dentry *dentry, const struct inode *inode, | 122 | static 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 | */ |
145 | static int vfat_cmpi(const struct dentry *parent, const struct inode *pinode, | 143 | static 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 | */ |
165 | static int vfat_cmp(const struct dentry *parent, const struct inode *pinode, | 162 | static 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 | ||
112 | static int gfs2_dhash(const struct dentry *dentry, const struct inode *inode, | 112 | static 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 */ |
230 | extern const struct dentry_operations hfs_dentry_operations; | 230 | extern const struct dentry_operations hfs_dentry_operations; |
231 | 231 | ||
232 | extern int hfs_hash_dentry(const struct dentry *, const struct inode *, | 232 | extern int hfs_hash_dentry(const struct dentry *, struct qstr *); |
233 | struct qstr *); | ||
234 | extern int hfs_strcmp(const unsigned char *, unsigned int, | 233 | extern int hfs_strcmp(const unsigned char *, unsigned int, |
235 | const unsigned char *, unsigned int); | 234 | const unsigned char *, unsigned int); |
236 | extern int hfs_compare_dentry(const struct dentry *parent, | 235 | extern 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 | */ |
54 | int hfs_hash_dentry(const struct dentry *dentry, const struct inode *inode, | 54 | int 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 | */ |
96 | int hfs_compare_dentry(const struct dentry *parent, const struct inode *pinode, | 95 | int 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 *); |
496 | int hfsplus_asc2uni(struct super_block *, | 496 | int hfsplus_asc2uni(struct super_block *, |
497 | struct hfsplus_unistr *, int, const char *, int); | 497 | struct hfsplus_unistr *, int, const char *, int); |
498 | int hfsplus_hash_dentry(const struct dentry *dentry, | 498 | int hfsplus_hash_dentry(const struct dentry *dentry, struct qstr *str); |
499 | const struct inode *inode, struct qstr *str); | 499 | int hfsplus_compare_dentry(const struct dentry *parent, const struct dentry *dentry, |
500 | int 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 | */ |
337 | int hfsplus_hash_dentry(const struct dentry *dentry, const struct inode *inode, | 337 | int 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 | */ |
389 | int hfsplus_compare_dentry(const struct dentry *parent, | 388 | int 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 | ||
15 | static int hpfs_hash_dentry(const struct dentry *dentry, const struct inode *inode, | 15 | static 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 | ||
38 | static int hpfs_compare_dentry(const struct dentry *parent, | 37 | static 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 | ||
31 | static int isofs_hashi(const struct dentry *parent, const struct inode *inode, | 31 | static int isofs_hashi(const struct dentry *parent, struct qstr *qstr); |
32 | struct qstr *qstr); | 32 | static int isofs_hash(const struct dentry *parent, struct qstr *qstr); |
33 | static int isofs_hash(const struct dentry *parent, const struct inode *inode, | ||
34 | struct qstr *qstr); | ||
35 | static int isofs_dentry_cmpi(const struct dentry *parent, | 33 | static 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); |
39 | static int isofs_dentry_cmp(const struct dentry *parent, | 36 | static 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 |
45 | static int isofs_hashi_ms(const struct dentry *parent, const struct inode *inode, | 41 | static int isofs_hashi_ms(const struct dentry *parent, struct qstr *qstr); |
46 | struct qstr *qstr); | 42 | static int isofs_hash_ms(const struct dentry *parent, struct qstr *qstr); |
47 | static int isofs_hash_ms(const struct dentry *parent, const struct inode *inode, | ||
48 | struct qstr *qstr); | ||
49 | static int isofs_dentry_cmpi_ms(const struct dentry *parent, | 43 | static 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); |
53 | static int isofs_dentry_cmp_ms(const struct dentry *parent, | 46 | static 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 | ||
267 | static int | 259 | static int |
268 | isofs_hash(const struct dentry *dentry, const struct inode *inode, | 260 | isofs_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 | ||
274 | static int | 265 | static int |
275 | isofs_hashi(const struct dentry *dentry, const struct inode *inode, | 266 | isofs_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 | ||
281 | static int | 271 | static int |
282 | isofs_dentry_cmp(const struct dentry *parent, const struct inode *pinode, | 272 | isofs_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 | ||
289 | static int | 278 | static int |
290 | isofs_dentry_cmpi(const struct dentry *parent, const struct inode *pinode, | 279 | isofs_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 |
298 | static int | 286 | static int |
299 | isofs_hash_ms(const struct dentry *dentry, const struct inode *inode, | 287 | isofs_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 | ||
305 | static int | 292 | static int |
306 | isofs_hashi_ms(const struct dentry *dentry, const struct inode *inode, | 293 | isofs_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 | ||
312 | static int | 298 | static int |
313 | isofs_dentry_cmp_ms(const struct dentry *parent, const struct inode *pinode, | 299 | isofs_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 | ||
320 | static int | 305 | static int |
321 | isofs_dentry_cmpi_ms(const struct dentry *parent, const struct inode *pinode, | 306 | isofs_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 | ||
1541 | static int jfs_ci_hash(const struct dentry *dir, const struct inode *inode, | 1541 | static 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 | ||
1555 | static int jfs_ci_compare(const struct dentry *parent, | 1554 | static 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 | */ |
75 | static int ncp_lookup_validate(struct dentry *, unsigned int); | 75 | static int ncp_lookup_validate(struct dentry *, unsigned int); |
76 | static int ncp_hash_dentry(const struct dentry *, const struct inode *, | 76 | static int ncp_hash_dentry(const struct dentry *, struct qstr *); |
77 | struct qstr *); | 77 | static int ncp_compare_dentry(const struct dentry *, const struct dentry *, |
78 | static 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 *); |
81 | static int ncp_delete_dentry(const struct dentry *); | 79 | static 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 | */ |
123 | static int | 125 | static int |
124 | ncp_hash_dentry(const struct dentry *dentry, const struct inode *inode, | 126 | ncp_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 | */ | ||
143 | static int | 154 | static int |
144 | ncp_compare_dentry(const struct dentry *parent, const struct inode *pinode, | 155 | ncp_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 | ||
799 | static int proc_sys_compare(const struct dentry *parent, | 799 | static 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 | ||
30 | static int sysv_hash(const struct dentry *dentry, const struct inode *inode, | 30 | static 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. */ |
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 86da7595ba31..f42dbe145479 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h | |||
@@ -146,10 +146,8 @@ enum dentry_d_lock_class | |||
146 | struct dentry_operations { | 146 | struct dentry_operations { |
147 | int (*d_revalidate)(struct dentry *, unsigned int); | 147 | int (*d_revalidate)(struct dentry *, unsigned int); |
148 | int (*d_weak_revalidate)(struct dentry *, unsigned int); | 148 | int (*d_weak_revalidate)(struct dentry *, unsigned int); |
149 | int (*d_hash)(const struct dentry *, const struct inode *, | 149 | int (*d_hash)(const struct dentry *, struct qstr *); |
150 | struct qstr *); | 150 | int (*d_compare)(const struct dentry *, const struct dentry *, |
151 | int (*d_compare)(const struct dentry *, const struct inode *, | ||
152 | const struct dentry *, const struct inode *, | ||
153 | unsigned int, const char *, const struct qstr *); | 151 | unsigned int, const char *, const struct qstr *); |
154 | int (*d_delete)(const struct dentry *); | 152 | int (*d_delete)(const struct dentry *); |
155 | void (*d_release)(struct dentry *); | 153 | void (*d_release)(struct dentry *); |
@@ -302,8 +300,7 @@ extern struct dentry *d_lookup(const struct dentry *, const struct qstr *); | |||
302 | extern struct dentry *d_hash_and_lookup(struct dentry *, struct qstr *); | 300 | extern struct dentry *d_hash_and_lookup(struct dentry *, struct qstr *); |
303 | extern struct dentry *__d_lookup(const struct dentry *, const struct qstr *); | 301 | extern struct dentry *__d_lookup(const struct dentry *, const struct qstr *); |
304 | extern struct dentry *__d_lookup_rcu(const struct dentry *parent, | 302 | extern struct dentry *__d_lookup_rcu(const struct dentry *parent, |
305 | const struct qstr *name, | 303 | const struct qstr *name, unsigned *seq); |
306 | unsigned *seq, struct inode *inode); | ||
307 | 304 | ||
308 | /** | 305 | /** |
309 | * __d_rcu_to_refcount - take a refcount on dentry if sequence check is ok | 306 | * __d_rcu_to_refcount - take a refcount on dentry if sequence check is ok |