Commit da53be12bbb4fabbe2e9f6f908de0cf478b5161d
Committed by
Al Viro
1 parent
642b704cd7
Exists in
master
and in
20 other branches
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>
Showing 23 changed files with 108 additions and 165 deletions Side-by-side Diff
- Documentation/filesystems/Locking
- Documentation/filesystems/vfs.txt
- fs/adfs/dir.c
- fs/affs/namei.c
- fs/cifs/dir.c
- fs/dcache.c
- fs/efivarfs/super.c
- fs/fat/namei_msdos.c
- fs/fat/namei_vfat.c
- fs/gfs2/dentry.c
- fs/hfs/hfs_fs.h
- fs/hfs/string.c
- fs/hfsplus/hfsplus_fs.h
- fs/hfsplus/unicode.c
- fs/hpfs/dentry.c
- fs/isofs/inode.c
- fs/isofs/namei.c
- fs/jfs/namei.c
- fs/namei.c
- fs/ncpfs/dir.c
- fs/proc/proc_sysctl.c
- fs/sysv/namei.c
- include/linux/dcache.h
Documentation/filesystems/Locking
... | ... | @@ -11,10 +11,8 @@ |
11 | 11 | prototypes: |
12 | 12 | int (*d_revalidate)(struct dentry *, unsigned int); |
13 | 13 | int (*d_weak_revalidate)(struct dentry *, unsigned int); |
14 | - int (*d_hash)(const struct dentry *, const struct inode *, | |
15 | - struct qstr *); | |
16 | - int (*d_compare)(const struct dentry *, const struct inode *, | |
17 | - const struct dentry *, const struct inode *, | |
14 | + int (*d_hash)(const struct dentry *, struct qstr *); | |
15 | + int (*d_compare)(const struct dentry *, const struct dentry *, | |
18 | 16 | unsigned int, const char *, const struct qstr *); |
19 | 17 | int (*d_delete)(struct dentry *); |
20 | 18 | void (*d_release)(struct dentry *); |
Documentation/filesystems/vfs.txt
... | ... | @@ -901,10 +901,8 @@ |
901 | 901 | struct dentry_operations { |
902 | 902 | int (*d_revalidate)(struct dentry *, unsigned int); |
903 | 903 | int (*d_weak_revalidate)(struct dentry *, unsigned int); |
904 | - int (*d_hash)(const struct dentry *, const struct inode *, | |
905 | - struct qstr *); | |
906 | - int (*d_compare)(const struct dentry *, const struct inode *, | |
907 | - const struct dentry *, const struct inode *, | |
904 | + int (*d_hash)(const struct dentry *, struct qstr *); | |
905 | + int (*d_compare)(const struct dentry *, const struct dentry *, | |
908 | 906 | unsigned int, const char *, const struct qstr *); |
909 | 907 | int (*d_delete)(const struct dentry *); |
910 | 908 | void (*d_release)(struct dentry *); |
911 | 909 | |
912 | 910 | |
913 | 911 | |
... | ... | @@ -949,25 +947,24 @@ |
949 | 947 | |
950 | 948 | d_hash: called when the VFS adds a dentry to the hash table. The first |
951 | 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 | 952 | Same locking and synchronisation rules as d_compare regarding |
955 | 953 | what is safe to dereference etc. |
956 | 954 | |
957 | 955 | d_compare: called to compare a dentry name with a given name. The first |
958 | 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 | |
960 | - child dentry. len and name string are properties of the dentry to be | |
961 | - compared. qstr is the name to compare it with. | |
957 | + the child dentry. len and name string are properties of the dentry | |
958 | + to be compared. qstr is the name to compare it with. | |
962 | 959 | |
963 | 960 | Must be constant and idempotent, and should not take locks if |
964 | - possible, and should not or store into the dentry or inodes. | |
965 | - Should not dereference pointers outside the dentry or inodes without | |
961 | + possible, and should not or store into the dentry. | |
962 | + Should not dereference pointers outside the dentry without | |
966 | 963 | lots of care (eg. d_parent, d_inode, d_name should not be used). |
967 | 964 | |
968 | 965 | However, our vfsmount is pinned, and RCU held, so the dentries and |
969 | 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 | 969 | It is a tricky calling convention because it needs to be called under |
973 | 970 | "rcu-walk", ie. without any locks or references on things. |
fs/adfs/dir.c
... | ... | @@ -191,8 +191,7 @@ |
191 | 191 | }; |
192 | 192 | |
193 | 193 | static int |
194 | -adfs_hash(const struct dentry *parent, const struct inode *inode, | |
195 | - struct qstr *qstr) | |
194 | +adfs_hash(const struct dentry *parent, struct qstr *qstr) | |
196 | 195 | { |
197 | 196 | const unsigned int name_len = ADFS_SB(parent->d_sb)->s_namelen; |
198 | 197 | const unsigned char *name; |
... | ... | @@ -228,8 +227,7 @@ |
228 | 227 | * requirements of the underlying filesystem. |
229 | 228 | */ |
230 | 229 | static int |
231 | -adfs_compare(const struct dentry *parent, const struct inode *pinode, | |
232 | - const struct dentry *dentry, const struct inode *inode, | |
230 | +adfs_compare(const struct dentry *parent, const struct dentry *dentry, | |
233 | 231 | unsigned int len, const char *str, const struct qstr *name) |
234 | 232 | { |
235 | 233 | int i; |
fs/affs/namei.c
... | ... | @@ -13,18 +13,12 @@ |
13 | 13 | typedef int (*toupper_t)(int); |
14 | 14 | |
15 | 15 | static int affs_toupper(int ch); |
16 | -static int affs_hash_dentry(const struct dentry *, | |
17 | - const struct inode *, struct qstr *); | |
18 | -static int affs_compare_dentry(const struct dentry *parent, | |
19 | - const struct inode *pinode, | |
20 | - const struct dentry *dentry, const struct inode *inode, | |
16 | +static int affs_hash_dentry(const struct dentry *, struct qstr *); | |
17 | +static int affs_compare_dentry(const struct dentry *parent, const struct dentry *dentry, | |
21 | 18 | unsigned int len, const char *str, const struct qstr *name); |
22 | 19 | static int affs_intl_toupper(int ch); |
23 | -static int affs_intl_hash_dentry(const struct dentry *, | |
24 | - const struct inode *, struct qstr *); | |
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, | |
20 | +static int affs_intl_hash_dentry(const struct dentry *, struct qstr *); | |
21 | +static int affs_intl_compare_dentry(const struct dentry *parent, const struct dentry *dentry, | |
28 | 22 | unsigned int len, const char *str, const struct qstr *name); |
29 | 23 | |
30 | 24 | const struct dentry_operations affs_dentry_operations = { |
31 | 25 | |
... | ... | @@ -86,14 +80,12 @@ |
86 | 80 | } |
87 | 81 | |
88 | 82 | static int |
89 | -affs_hash_dentry(const struct dentry *dentry, const struct inode *inode, | |
90 | - struct qstr *qstr) | |
83 | +affs_hash_dentry(const struct dentry *dentry, struct qstr *qstr) | |
91 | 84 | { |
92 | 85 | return __affs_hash_dentry(qstr, affs_toupper); |
93 | 86 | } |
94 | 87 | static int |
95 | -affs_intl_hash_dentry(const struct dentry *dentry, const struct inode *inode, | |
96 | - struct qstr *qstr) | |
88 | +affs_intl_hash_dentry(const struct dentry *dentry, struct qstr *qstr) | |
97 | 89 | { |
98 | 90 | return __affs_hash_dentry(qstr, affs_intl_toupper); |
99 | 91 | } |
100 | 92 | |
... | ... | @@ -131,15 +123,13 @@ |
131 | 123 | } |
132 | 124 | |
133 | 125 | static int |
134 | -affs_compare_dentry(const struct dentry *parent, const struct inode *pinode, | |
135 | - const struct dentry *dentry, const struct inode *inode, | |
126 | +affs_compare_dentry(const struct dentry *parent, const struct dentry *dentry, | |
136 | 127 | unsigned int len, const char *str, const struct qstr *name) |
137 | 128 | { |
138 | 129 | return __affs_compare_dentry(len, str, name, affs_toupper); |
139 | 130 | } |
140 | 131 | static int |
141 | -affs_intl_compare_dentry(const struct dentry *parent,const struct inode *pinode, | |
142 | - const struct dentry *dentry, const struct inode *inode, | |
132 | +affs_intl_compare_dentry(const struct dentry *parent, const struct dentry *dentry, | |
143 | 133 | unsigned int len, const char *str, const struct qstr *name) |
144 | 134 | { |
145 | 135 | return __affs_compare_dentry(len, str, name, affs_intl_toupper); |
fs/cifs/dir.c
... | ... | @@ -822,8 +822,7 @@ |
822 | 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, | |
826 | - struct qstr *q) | |
825 | +static int cifs_ci_hash(const struct dentry *dentry, struct qstr *q) | |
827 | 826 | { |
828 | 827 | struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls; |
829 | 828 | unsigned long hash; |
830 | 829 | |
... | ... | @@ -838,12 +837,10 @@ |
838 | 837 | return 0; |
839 | 838 | } |
840 | 839 | |
841 | -static int cifs_ci_compare(const struct dentry *parent, | |
842 | - const struct inode *pinode, | |
843 | - const struct dentry *dentry, const struct inode *inode, | |
840 | +static int cifs_ci_compare(const struct dentry *parent, const struct dentry *dentry, | |
844 | 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 | 845 | if ((name->len == len) && |
849 | 846 | (nls_strnicmp(codepage, name->name, str, len) == 0)) |
fs/dcache.c
... | ... | @@ -1723,7 +1723,7 @@ |
1723 | 1723 | * Do the slow-case of the dentry name compare. |
1724 | 1724 | * |
1725 | 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 | 1727 | * filesystem can rely on them, and can use the 'name' and |
1728 | 1728 | * 'len' information without worrying about walking off the |
1729 | 1729 | * end of memory etc. |
1730 | 1730 | |
1731 | 1731 | |
... | ... | @@ -1741,22 +1741,18 @@ |
1741 | 1741 | |
1742 | 1742 | static noinline enum slow_d_compare slow_dentry_cmp( |
1743 | 1743 | const struct dentry *parent, |
1744 | - struct inode *inode, | |
1745 | 1744 | struct dentry *dentry, |
1746 | 1745 | unsigned int seq, |
1747 | 1746 | const struct qstr *name) |
1748 | 1747 | { |
1749 | 1748 | int tlen = dentry->d_name.len; |
1750 | 1749 | const char *tname = dentry->d_name.name; |
1751 | - struct inode *i = dentry->d_inode; | |
1752 | 1750 | |
1753 | 1751 | if (read_seqcount_retry(&dentry->d_seq, seq)) { |
1754 | 1752 | cpu_relax(); |
1755 | 1753 | return D_COMP_SEQRETRY; |
1756 | 1754 | } |
1757 | - if (parent->d_op->d_compare(parent, inode, | |
1758 | - dentry, i, | |
1759 | - tlen, tname, name)) | |
1755 | + if (parent->d_op->d_compare(parent, dentry, tlen, tname, name)) | |
1760 | 1756 | return D_COMP_NOMATCH; |
1761 | 1757 | return D_COMP_OK; |
1762 | 1758 | } |
... | ... | @@ -1766,7 +1762,6 @@ |
1766 | 1762 | * @parent: parent dentry |
1767 | 1763 | * @name: qstr of name we wish to find |
1768 | 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 | 1765 | * Returns: dentry, or NULL |
1771 | 1766 | * |
1772 | 1767 | * __d_lookup_rcu is the dcache lookup function for rcu-walk name |
... | ... | @@ -1793,7 +1788,7 @@ |
1793 | 1788 | */ |
1794 | 1789 | struct dentry *__d_lookup_rcu(const struct dentry *parent, |
1795 | 1790 | const struct qstr *name, |
1796 | - unsigned *seqp, struct inode *inode) | |
1791 | + unsigned *seqp) | |
1797 | 1792 | { |
1798 | 1793 | u64 hashlen = name->hash_len; |
1799 | 1794 | const unsigned char *str = name->name; |
1800 | 1795 | |
... | ... | @@ -1827,11 +1822,10 @@ |
1827 | 1822 | seqretry: |
1828 | 1823 | /* |
1829 | 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 | 1827 | * The caller must perform a seqcount check in order |
1833 | - * to do anything useful with the returned dentry, | |
1834 | - * including using the 'd_inode' pointer. | |
1828 | + * to do anything useful with the returned dentry. | |
1835 | 1829 | * |
1836 | 1830 | * NOTE! We do a "raw" seqcount_begin here. That means that |
1837 | 1831 | * we don't wait for the sequence count to stabilize if it |
1838 | 1832 | |
... | ... | @@ -1845,12 +1839,12 @@ |
1845 | 1839 | continue; |
1846 | 1840 | if (d_unhashed(dentry)) |
1847 | 1841 | continue; |
1848 | - *seqp = seq; | |
1849 | 1842 | |
1850 | 1843 | if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) { |
1851 | 1844 | if (dentry->d_name.hash != hashlen_hash(hashlen)) |
1852 | 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 | 1848 | case D_COMP_OK: |
1855 | 1849 | return dentry; |
1856 | 1850 | case D_COMP_NOMATCH: |
... | ... | @@ -1862,6 +1856,7 @@ |
1862 | 1856 | |
1863 | 1857 | if (dentry->d_name.hash_len != hashlen) |
1864 | 1858 | continue; |
1859 | + *seqp = seq; | |
1865 | 1860 | if (!dentry_cmp(dentry, str, hashlen_len(hashlen))) |
1866 | 1861 | return dentry; |
1867 | 1862 | } |
... | ... | @@ -1959,9 +1954,7 @@ |
1959 | 1954 | if (parent->d_flags & DCACHE_OP_COMPARE) { |
1960 | 1955 | int tlen = dentry->d_name.len; |
1961 | 1956 | const char *tname = dentry->d_name.name; |
1962 | - if (parent->d_op->d_compare(parent, parent->d_inode, | |
1963 | - dentry, dentry->d_inode, | |
1964 | - tlen, tname, name)) | |
1957 | + if (parent->d_op->d_compare(parent, dentry, tlen, tname, name)) | |
1965 | 1958 | goto next; |
1966 | 1959 | } else { |
1967 | 1960 | if (dentry->d_name.len != len) |
... | ... | @@ -1998,7 +1991,7 @@ |
1998 | 1991 | */ |
1999 | 1992 | name->hash = full_name_hash(name->name, name->len); |
2000 | 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 | 1995 | if (unlikely(err < 0)) |
2003 | 1996 | return ERR_PTR(err); |
2004 | 1997 | } |
fs/efivarfs/super.c
... | ... | @@ -45,8 +45,8 @@ |
45 | 45 | * So we need to perform a case-sensitive match on part 1 and a |
46 | 46 | * case-insensitive match on part 2. |
47 | 47 | */ |
48 | -static int efivarfs_d_compare(const struct dentry *parent, const struct inode *pinode, | |
49 | - const struct dentry *dentry, const struct inode *inode, | |
48 | +static int efivarfs_d_compare(const struct dentry *parent, | |
49 | + const struct dentry *dentry, | |
50 | 50 | unsigned int len, const char *str, |
51 | 51 | const struct qstr *name) |
52 | 52 | { |
... | ... | @@ -63,8 +63,7 @@ |
63 | 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, | |
67 | - const struct inode *inode, struct qstr *qstr) | |
66 | +static int efivarfs_d_hash(const struct dentry *dentry, struct qstr *qstr) | |
68 | 67 | { |
69 | 68 | unsigned long hash = init_name_hash(); |
70 | 69 | const unsigned char *s = qstr->name; |
... | ... | @@ -108,7 +107,7 @@ |
108 | 107 | q.name = name; |
109 | 108 | q.len = strlen(name); |
110 | 109 | |
111 | - err = efivarfs_d_hash(NULL, NULL, &q); | |
110 | + err = efivarfs_d_hash(NULL, &q); | |
112 | 111 | if (err) |
113 | 112 | return ERR_PTR(err); |
114 | 113 |
fs/fat/namei_msdos.c
... | ... | @@ -148,8 +148,7 @@ |
148 | 148 | * that the existing dentry can be used. The msdos fs routines will |
149 | 149 | * return ENOENT or EINVAL as appropriate. |
150 | 150 | */ |
151 | -static int msdos_hash(const struct dentry *dentry, const struct inode *inode, | |
152 | - struct qstr *qstr) | |
151 | +static int msdos_hash(const struct dentry *dentry, struct qstr *qstr) | |
153 | 152 | { |
154 | 153 | struct fat_mount_options *options = &MSDOS_SB(dentry->d_sb)->options; |
155 | 154 | unsigned char msdos_name[MSDOS_NAME]; |
... | ... | @@ -165,8 +164,7 @@ |
165 | 164 | * Compare two msdos names. If either of the names are invalid, |
166 | 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, | |
169 | - const struct dentry *dentry, const struct inode *inode, | |
167 | +static int msdos_cmp(const struct dentry *parent, const struct dentry *dentry, | |
170 | 168 | unsigned int len, const char *str, const struct qstr *name) |
171 | 169 | { |
172 | 170 | struct fat_mount_options *options = &MSDOS_SB(parent->d_sb)->options; |
fs/fat/namei_vfat.c
... | ... | @@ -107,8 +107,7 @@ |
107 | 107 | * that the existing dentry can be used. The vfat fs routines will |
108 | 108 | * return ENOENT or EINVAL as appropriate. |
109 | 109 | */ |
110 | -static int vfat_hash(const struct dentry *dentry, const struct inode *inode, | |
111 | - struct qstr *qstr) | |
110 | +static int vfat_hash(const struct dentry *dentry, struct qstr *qstr) | |
112 | 111 | { |
113 | 112 | qstr->hash = full_name_hash(qstr->name, vfat_striptail_len(qstr)); |
114 | 113 | return 0; |
... | ... | @@ -120,8 +119,7 @@ |
120 | 119 | * that the existing dentry can be used. The vfat fs routines will |
121 | 120 | * return ENOENT or EINVAL as appropriate. |
122 | 121 | */ |
123 | -static int vfat_hashi(const struct dentry *dentry, const struct inode *inode, | |
124 | - struct qstr *qstr) | |
122 | +static int vfat_hashi(const struct dentry *dentry, struct qstr *qstr) | |
125 | 123 | { |
126 | 124 | struct nls_table *t = MSDOS_SB(dentry->d_sb)->nls_io; |
127 | 125 | const unsigned char *name; |
... | ... | @@ -142,8 +140,7 @@ |
142 | 140 | /* |
143 | 141 | * Case insensitive compare of two vfat names. |
144 | 142 | */ |
145 | -static int vfat_cmpi(const struct dentry *parent, const struct inode *pinode, | |
146 | - const struct dentry *dentry, const struct inode *inode, | |
143 | +static int vfat_cmpi(const struct dentry *parent, const struct dentry *dentry, | |
147 | 144 | unsigned int len, const char *str, const struct qstr *name) |
148 | 145 | { |
149 | 146 | struct nls_table *t = MSDOS_SB(parent->d_sb)->nls_io; |
... | ... | @@ -162,8 +159,7 @@ |
162 | 159 | /* |
163 | 160 | * Case sensitive compare of two vfat names. |
164 | 161 | */ |
165 | -static int vfat_cmp(const struct dentry *parent, const struct inode *pinode, | |
166 | - const struct dentry *dentry, const struct inode *inode, | |
162 | +static int vfat_cmp(const struct dentry *parent, const struct dentry *dentry, | |
167 | 163 | unsigned int len, const char *str, const struct qstr *name) |
168 | 164 | { |
169 | 165 | unsigned int alen, blen; |
fs/gfs2/dentry.c
... | ... | @@ -109,8 +109,7 @@ |
109 | 109 | return 0; |
110 | 110 | } |
111 | 111 | |
112 | -static int gfs2_dhash(const struct dentry *dentry, const struct inode *inode, | |
113 | - struct qstr *str) | |
112 | +static int gfs2_dhash(const struct dentry *dentry, struct qstr *str) | |
114 | 113 | { |
115 | 114 | str->hash = gfs2_disk_hash(str->name, str->len); |
116 | 115 | return 0; |
fs/hfs/hfs_fs.h
... | ... | @@ -229,13 +229,10 @@ |
229 | 229 | /* string.c */ |
230 | 230 | extern const struct dentry_operations hfs_dentry_operations; |
231 | 231 | |
232 | -extern int hfs_hash_dentry(const struct dentry *, const struct inode *, | |
233 | - struct qstr *); | |
232 | +extern int hfs_hash_dentry(const struct dentry *, struct qstr *); | |
234 | 233 | extern int hfs_strcmp(const unsigned char *, unsigned int, |
235 | 234 | const unsigned char *, unsigned int); |
236 | -extern int hfs_compare_dentry(const struct dentry *parent, | |
237 | - const struct inode *pinode, | |
238 | - const struct dentry *dentry, const struct inode *inode, | |
235 | +extern int hfs_compare_dentry(const struct dentry *parent, const struct dentry *dentry, | |
239 | 236 | unsigned int len, const char *str, const struct qstr *name); |
240 | 237 | |
241 | 238 | /* trans.c */ |
fs/hfs/string.c
... | ... | @@ -51,8 +51,7 @@ |
51 | 51 | /* |
52 | 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, | |
55 | - struct qstr *this) | |
54 | +int hfs_hash_dentry(const struct dentry *dentry, struct qstr *this) | |
56 | 55 | { |
57 | 56 | const unsigned char *name = this->name; |
58 | 57 | unsigned int hash, len = this->len; |
... | ... | @@ -93,8 +92,7 @@ |
93 | 92 | * Test for equality of two strings in the HFS filename character ordering. |
94 | 93 | * return 1 on failure and 0 on success |
95 | 94 | */ |
96 | -int hfs_compare_dentry(const struct dentry *parent, const struct inode *pinode, | |
97 | - const struct dentry *dentry, const struct inode *inode, | |
95 | +int hfs_compare_dentry(const struct dentry *parent, const struct dentry *dentry, | |
98 | 96 | unsigned int len, const char *str, const struct qstr *name) |
99 | 97 | { |
100 | 98 | const unsigned char *n1, *n2; |
fs/hfsplus/hfsplus_fs.h
... | ... | @@ -495,11 +495,8 @@ |
495 | 495 | const struct hfsplus_unistr *, char *, int *); |
496 | 496 | int hfsplus_asc2uni(struct super_block *, |
497 | 497 | struct hfsplus_unistr *, int, const char *, int); |
498 | -int hfsplus_hash_dentry(const struct dentry *dentry, | |
499 | - const struct inode *inode, struct qstr *str); | |
500 | -int hfsplus_compare_dentry(const struct dentry *parent, | |
501 | - const struct inode *pinode, | |
502 | - const struct dentry *dentry, const struct inode *inode, | |
498 | +int hfsplus_hash_dentry(const struct dentry *dentry, struct qstr *str); | |
499 | +int hfsplus_compare_dentry(const struct dentry *parent, const struct dentry *dentry, | |
503 | 500 | unsigned int len, const char *str, const struct qstr *name); |
504 | 501 | |
505 | 502 | /* wrapper.c */ |
fs/hfsplus/unicode.c
... | ... | @@ -334,8 +334,7 @@ |
334 | 334 | * Composed unicode characters are decomposed and case-folding is performed |
335 | 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, | |
338 | - struct qstr *str) | |
337 | +int hfsplus_hash_dentry(const struct dentry *dentry, struct qstr *str) | |
339 | 338 | { |
340 | 339 | struct super_block *sb = dentry->d_sb; |
341 | 340 | const char *astr; |
... | ... | @@ -386,9 +385,7 @@ |
386 | 385 | * Composed unicode characters are decomposed and case-folding is performed |
387 | 386 | * if the appropriate bits are (un)set on the superblock. |
388 | 387 | */ |
389 | -int hfsplus_compare_dentry(const struct dentry *parent, | |
390 | - const struct inode *pinode, | |
391 | - const struct dentry *dentry, const struct inode *inode, | |
388 | +int hfsplus_compare_dentry(const struct dentry *parent, const struct dentry *dentry, | |
392 | 389 | unsigned int len, const char *str, const struct qstr *name) |
393 | 390 | { |
394 | 391 | struct super_block *sb = parent->d_sb; |
fs/hpfs/dentry.c
... | ... | @@ -12,8 +12,7 @@ |
12 | 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, | |
16 | - struct qstr *qstr) | |
15 | +static int hpfs_hash_dentry(const struct dentry *dentry, struct qstr *qstr) | |
17 | 16 | { |
18 | 17 | unsigned long hash; |
19 | 18 | int i; |
... | ... | @@ -35,9 +34,7 @@ |
35 | 34 | return 0; |
36 | 35 | } |
37 | 36 | |
38 | -static int hpfs_compare_dentry(const struct dentry *parent, | |
39 | - const struct inode *pinode, | |
40 | - const struct dentry *dentry, const struct inode *inode, | |
37 | +static int hpfs_compare_dentry(const struct dentry *parent, const struct dentry *dentry, | |
41 | 38 | unsigned int len, const char *str, const struct qstr *name) |
42 | 39 | { |
43 | 40 | unsigned al = len; |
fs/isofs/inode.c
... | ... | @@ -28,31 +28,23 @@ |
28 | 28 | |
29 | 29 | #define BEQUIET |
30 | 30 | |
31 | -static int isofs_hashi(const struct dentry *parent, const struct inode *inode, | |
32 | - struct qstr *qstr); | |
33 | -static int isofs_hash(const struct dentry *parent, const struct inode *inode, | |
34 | - struct qstr *qstr); | |
31 | +static int isofs_hashi(const struct dentry *parent, struct qstr *qstr); | |
32 | +static int isofs_hash(const struct dentry *parent, struct qstr *qstr); | |
35 | 33 | static int isofs_dentry_cmpi(const struct dentry *parent, |
36 | - const struct inode *pinode, | |
37 | - const struct dentry *dentry, const struct inode *inode, | |
34 | + const struct dentry *dentry, | |
38 | 35 | unsigned int len, const char *str, const struct qstr *name); |
39 | 36 | static int isofs_dentry_cmp(const struct dentry *parent, |
40 | - const struct inode *pinode, | |
41 | - const struct dentry *dentry, const struct inode *inode, | |
37 | + const struct dentry *dentry, | |
42 | 38 | unsigned int len, const char *str, const struct qstr *name); |
43 | 39 | |
44 | 40 | #ifdef CONFIG_JOLIET |
45 | -static int isofs_hashi_ms(const struct dentry *parent, const struct inode *inode, | |
46 | - struct qstr *qstr); | |
47 | -static int isofs_hash_ms(const struct dentry *parent, const struct inode *inode, | |
48 | - struct qstr *qstr); | |
41 | +static int isofs_hashi_ms(const struct dentry *parent, struct qstr *qstr); | |
42 | +static int isofs_hash_ms(const struct dentry *parent, struct qstr *qstr); | |
49 | 43 | static int isofs_dentry_cmpi_ms(const struct dentry *parent, |
50 | - const struct inode *pinode, | |
51 | - const struct dentry *dentry, const struct inode *inode, | |
44 | + const struct dentry *dentry, | |
52 | 45 | unsigned int len, const char *str, const struct qstr *name); |
53 | 46 | static int isofs_dentry_cmp_ms(const struct dentry *parent, |
54 | - const struct inode *pinode, | |
55 | - const struct dentry *dentry, const struct inode *inode, | |
47 | + const struct dentry *dentry, | |
56 | 48 | unsigned int len, const char *str, const struct qstr *name); |
57 | 49 | #endif |
58 | 50 | |
59 | 51 | |
60 | 52 | |
61 | 53 | |
... | ... | @@ -265,30 +257,26 @@ |
265 | 257 | } |
266 | 258 | |
267 | 259 | static int |
268 | -isofs_hash(const struct dentry *dentry, const struct inode *inode, | |
269 | - struct qstr *qstr) | |
260 | +isofs_hash(const struct dentry *dentry, struct qstr *qstr) | |
270 | 261 | { |
271 | 262 | return isofs_hash_common(dentry, qstr, 0); |
272 | 263 | } |
273 | 264 | |
274 | 265 | static int |
275 | -isofs_hashi(const struct dentry *dentry, const struct inode *inode, | |
276 | - struct qstr *qstr) | |
266 | +isofs_hashi(const struct dentry *dentry, struct qstr *qstr) | |
277 | 267 | { |
278 | 268 | return isofs_hashi_common(dentry, qstr, 0); |
279 | 269 | } |
280 | 270 | |
281 | 271 | static int |
282 | -isofs_dentry_cmp(const struct dentry *parent, const struct inode *pinode, | |
283 | - const struct dentry *dentry, const struct inode *inode, | |
272 | +isofs_dentry_cmp(const struct dentry *parent, const struct dentry *dentry, | |
284 | 273 | unsigned int len, const char *str, const struct qstr *name) |
285 | 274 | { |
286 | 275 | return isofs_dentry_cmp_common(len, str, name, 0, 0); |
287 | 276 | } |
288 | 277 | |
289 | 278 | static int |
290 | -isofs_dentry_cmpi(const struct dentry *parent, const struct inode *pinode, | |
291 | - const struct dentry *dentry, const struct inode *inode, | |
279 | +isofs_dentry_cmpi(const struct dentry *parent, const struct dentry *dentry, | |
292 | 280 | unsigned int len, const char *str, const struct qstr *name) |
293 | 281 | { |
294 | 282 | return isofs_dentry_cmp_common(len, str, name, 0, 1); |
295 | 283 | |
296 | 284 | |
297 | 285 | |
... | ... | @@ -296,30 +284,26 @@ |
296 | 284 | |
297 | 285 | #ifdef CONFIG_JOLIET |
298 | 286 | static int |
299 | -isofs_hash_ms(const struct dentry *dentry, const struct inode *inode, | |
300 | - struct qstr *qstr) | |
287 | +isofs_hash_ms(const struct dentry *dentry, struct qstr *qstr) | |
301 | 288 | { |
302 | 289 | return isofs_hash_common(dentry, qstr, 1); |
303 | 290 | } |
304 | 291 | |
305 | 292 | static int |
306 | -isofs_hashi_ms(const struct dentry *dentry, const struct inode *inode, | |
307 | - struct qstr *qstr) | |
293 | +isofs_hashi_ms(const struct dentry *dentry, struct qstr *qstr) | |
308 | 294 | { |
309 | 295 | return isofs_hashi_common(dentry, qstr, 1); |
310 | 296 | } |
311 | 297 | |
312 | 298 | static int |
313 | -isofs_dentry_cmp_ms(const struct dentry *parent, const struct inode *pinode, | |
314 | - const struct dentry *dentry, const struct inode *inode, | |
299 | +isofs_dentry_cmp_ms(const struct dentry *parent, const struct dentry *dentry, | |
315 | 300 | unsigned int len, const char *str, const struct qstr *name) |
316 | 301 | { |
317 | 302 | return isofs_dentry_cmp_common(len, str, name, 1, 0); |
318 | 303 | } |
319 | 304 | |
320 | 305 | static int |
321 | -isofs_dentry_cmpi_ms(const struct dentry *parent, const struct inode *pinode, | |
322 | - const struct dentry *dentry, const struct inode *inode, | |
306 | +isofs_dentry_cmpi_ms(const struct dentry *parent, const struct dentry *dentry, | |
323 | 307 | unsigned int len, const char *str, const struct qstr *name) |
324 | 308 | { |
325 | 309 | return isofs_dentry_cmp_common(len, str, name, 1, 1); |
fs/isofs/namei.c
... | ... | @@ -37,8 +37,7 @@ |
37 | 37 | |
38 | 38 | qstr.name = compare; |
39 | 39 | qstr.len = dlen; |
40 | - return dentry->d_op->d_compare(NULL, NULL, NULL, NULL, | |
41 | - dentry->d_name.len, dentry->d_name.name, &qstr); | |
40 | + return dentry->d_op->d_compare(NULL, NULL, dentry->d_name.len, dentry->d_name.name, &qstr); | |
42 | 41 | } |
43 | 42 | |
44 | 43 | /* |
fs/jfs/namei.c
... | ... | @@ -1538,8 +1538,7 @@ |
1538 | 1538 | .llseek = generic_file_llseek, |
1539 | 1539 | }; |
1540 | 1540 | |
1541 | -static int jfs_ci_hash(const struct dentry *dir, const struct inode *inode, | |
1542 | - struct qstr *this) | |
1541 | +static int jfs_ci_hash(const struct dentry *dir, struct qstr *this) | |
1543 | 1542 | { |
1544 | 1543 | unsigned long hash; |
1545 | 1544 | int i; |
... | ... | @@ -1552,9 +1551,7 @@ |
1552 | 1551 | return 0; |
1553 | 1552 | } |
1554 | 1553 | |
1555 | -static int jfs_ci_compare(const struct dentry *parent, | |
1556 | - const struct inode *pinode, | |
1557 | - const struct dentry *dentry, const struct inode *inode, | |
1554 | +static int jfs_ci_compare(const struct dentry *parent, const struct dentry *dentry, | |
1558 | 1555 | unsigned int len, const char *str, const struct qstr *name) |
1559 | 1556 | { |
1560 | 1557 | int i, result = 1; |
fs/namei.c
... | ... | @@ -1352,7 +1352,7 @@ |
1352 | 1352 | */ |
1353 | 1353 | if (nd->flags & LOOKUP_RCU) { |
1354 | 1354 | unsigned seq; |
1355 | - dentry = __d_lookup_rcu(parent, &nd->last, &seq, nd->inode); | |
1355 | + dentry = __d_lookup_rcu(parent, &nd->last, &seq); | |
1356 | 1356 | if (!dentry) |
1357 | 1357 | goto unlazy; |
1358 | 1358 | |
... | ... | @@ -1787,8 +1787,7 @@ |
1787 | 1787 | struct dentry *parent = nd->path.dentry; |
1788 | 1788 | nd->flags &= ~LOOKUP_JUMPED; |
1789 | 1789 | if (unlikely(parent->d_flags & DCACHE_OP_HASH)) { |
1790 | - err = parent->d_op->d_hash(parent, nd->inode, | |
1791 | - &this); | |
1790 | + err = parent->d_op->d_hash(parent, &this); | |
1792 | 1791 | if (err < 0) |
1793 | 1792 | break; |
1794 | 1793 | } |
... | ... | @@ -2121,7 +2120,7 @@ |
2121 | 2120 | * to use its own hash.. |
2122 | 2121 | */ |
2123 | 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 | 2124 | if (err < 0) |
2126 | 2125 | return ERR_PTR(err); |
2127 | 2126 | } |
fs/ncpfs/dir.c
... | ... | @@ -73,10 +73,8 @@ |
73 | 73 | * Dentry operations routines |
74 | 74 | */ |
75 | 75 | static int ncp_lookup_validate(struct dentry *, unsigned int); |
76 | -static int ncp_hash_dentry(const struct dentry *, const struct inode *, | |
77 | - struct qstr *); | |
78 | -static int ncp_compare_dentry(const struct dentry *, const struct inode *, | |
79 | - const struct dentry *, const struct inode *, | |
76 | +static int ncp_hash_dentry(const struct dentry *, struct qstr *); | |
77 | +static int ncp_compare_dentry(const struct dentry *, const struct dentry *, | |
80 | 78 | unsigned int, const char *, const struct qstr *); |
81 | 79 | static int ncp_delete_dentry(const struct dentry *); |
82 | 80 | |
83 | 81 | |
84 | 82 | |
... | ... | @@ -119,11 +117,19 @@ |
119 | 117 | /* |
120 | 118 | * Note: leave the hash unchanged if the directory |
121 | 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 | 125 | static int |
124 | -ncp_hash_dentry(const struct dentry *dentry, const struct inode *inode, | |
125 | - struct qstr *this) | |
126 | +ncp_hash_dentry(const struct dentry *dentry, struct qstr *this) | |
126 | 127 | { |
128 | + struct inode *inode = ACCESS_ONCE(dentry->d_inode); | |
129 | + | |
130 | + if (!inode) | |
131 | + return 0; | |
132 | + | |
127 | 133 | if (!ncp_case_sensitive(inode)) { |
128 | 134 | struct super_block *sb = dentry->d_sb; |
129 | 135 | struct nls_table *t; |
130 | 136 | |
131 | 137 | |
132 | 138 | |
... | ... | @@ -140,12 +146,22 @@ |
140 | 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 | 154 | static int |
144 | -ncp_compare_dentry(const struct dentry *parent, const struct inode *pinode, | |
145 | - const struct dentry *dentry, const struct inode *inode, | |
155 | +ncp_compare_dentry(const struct dentry *parent, const struct dentry *dentry, | |
146 | 156 | unsigned int len, const char *str, const struct qstr *name) |
147 | 157 | { |
158 | + struct inode *pinode; | |
159 | + | |
148 | 160 | if (len != name->len) |
161 | + return 1; | |
162 | + | |
163 | + pinode = ACCESS_ONCE(parent->d_inode); | |
164 | + if (!pinode) | |
149 | 165 | return 1; |
150 | 166 | |
151 | 167 | if (ncp_case_sensitive(pinode)) |
fs/proc/proc_sysctl.c
... | ... | @@ -796,15 +796,16 @@ |
796 | 796 | return res; |
797 | 797 | } |
798 | 798 | |
799 | -static int proc_sys_compare(const struct dentry *parent, | |
800 | - const struct inode *pinode, | |
801 | - const struct dentry *dentry, const struct inode *inode, | |
799 | +static int proc_sys_compare(const struct dentry *parent, const struct dentry *dentry, | |
802 | 800 | unsigned int len, const char *str, const struct qstr *name) |
803 | 801 | { |
804 | 802 | struct ctl_table_header *head; |
803 | + struct inode *inode; | |
804 | + | |
805 | 805 | /* Although proc doesn't have negative dentries, rcu-walk means |
806 | 806 | * that inode here can be NULL */ |
807 | 807 | /* AV: can it, indeed? */ |
808 | + inode = ACCESS_ONCE(dentry->d_inode); | |
808 | 809 | if (!inode) |
809 | 810 | return 1; |
810 | 811 | if (name->len != len) |
fs/sysv/namei.c
... | ... | @@ -27,8 +27,7 @@ |
27 | 27 | return err; |
28 | 28 | } |
29 | 29 | |
30 | -static int sysv_hash(const struct dentry *dentry, const struct inode *inode, | |
31 | - struct qstr *qstr) | |
30 | +static int sysv_hash(const struct dentry *dentry, struct qstr *qstr) | |
32 | 31 | { |
33 | 32 | /* Truncate the name in place, avoids having to define a compare |
34 | 33 | function. */ |
include/linux/dcache.h
... | ... | @@ -146,10 +146,8 @@ |
146 | 146 | struct dentry_operations { |
147 | 147 | int (*d_revalidate)(struct dentry *, unsigned int); |
148 | 148 | int (*d_weak_revalidate)(struct dentry *, unsigned int); |
149 | - int (*d_hash)(const struct dentry *, const struct inode *, | |
150 | - struct qstr *); | |
151 | - int (*d_compare)(const struct dentry *, const struct inode *, | |
152 | - const struct dentry *, const struct inode *, | |
149 | + int (*d_hash)(const struct dentry *, struct qstr *); | |
150 | + int (*d_compare)(const struct dentry *, const struct dentry *, | |
153 | 151 | unsigned int, const char *, const struct qstr *); |
154 | 152 | int (*d_delete)(const struct dentry *); |
155 | 153 | void (*d_release)(struct dentry *); |
... | ... | @@ -302,8 +300,7 @@ |
302 | 300 | extern struct dentry *d_hash_and_lookup(struct dentry *, struct qstr *); |
303 | 301 | extern struct dentry *__d_lookup(const struct dentry *, const struct qstr *); |
304 | 302 | extern struct dentry *__d_lookup_rcu(const struct dentry *parent, |
305 | - const struct qstr *name, | |
306 | - unsigned *seq, struct inode *inode); | |
303 | + const struct qstr *name, unsigned *seq); | |
307 | 304 | |
308 | 305 | /** |
309 | 306 | * __d_rcu_to_refcount - take a refcount on dentry if sequence check is ok |