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 |
