Commit b1e6a015a580ad145689ad1d6b4aa0e03e6c868b
1 parent
621e155a35
Exists in
master
and in
7 other branches
fs: change d_hash for rcu-walk
Change d_hash so it may be called from lock-free RCU lookups. See similar patch for d_compare for details. For in-tree filesystems, this is just a mechanical change. Signed-off-by: Nick Piggin <npiggin@kernel.dk>
Showing 25 changed files with 94 additions and 51 deletions Side-by-side Diff
- Documentation/filesystems/Locking
- Documentation/filesystems/porting
- Documentation/filesystems/vfs.txt
- drivers/staging/smbfs/cache.c
- drivers/staging/smbfs/dir.c
- fs/adfs/dir.c
- fs/affs/namei.c
- fs/cifs/dir.c
- fs/cifs/readdir.c
- fs/dcache.c
- fs/ecryptfs/inode.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/jfs/namei.c
- fs/namei.c
- fs/ncpfs/dir.c
- fs/sysv/namei.c
- include/linux/dcache.h
Documentation/filesystems/Locking
... | ... | @@ -10,7 +10,8 @@ |
10 | 10 | --------------------------- dentry_operations -------------------------- |
11 | 11 | prototypes: |
12 | 12 | int (*d_revalidate)(struct dentry *, int); |
13 | - int (*d_hash) (struct dentry *, struct qstr *); | |
13 | + int (*d_hash)(const struct dentry *, const struct inode *, | |
14 | + struct qstr *); | |
14 | 15 | int (*d_compare)(const struct dentry *, const struct inode *, |
15 | 16 | const struct dentry *, const struct inode *, |
16 | 17 | unsigned int, const char *, const struct qstr *); |
... | ... | @@ -22,7 +23,7 @@ |
22 | 23 | locking rules: |
23 | 24 | dcache_lock rename_lock ->d_lock may block |
24 | 25 | d_revalidate: no no no yes |
25 | -d_hash no no no yes | |
26 | +d_hash no no no no | |
26 | 27 | d_compare: no yes no no |
27 | 28 | d_delete: yes no yes no |
28 | 29 | d_release: no no no yes |
Documentation/filesystems/porting
... | ... | @@ -333,4 +333,11 @@ |
333 | 333 | .d_compare() calling convention and locking rules are significantly |
334 | 334 | changed. Read updated documentation in Documentation/filesystems/vfs.txt (and |
335 | 335 | look at examples of other filesystems) for guidance. |
336 | + | |
337 | +--- | |
338 | +[mandatory] | |
339 | + | |
340 | + .d_hash() calling convention and locking rules are significantly | |
341 | +changed. Read updated documentation in Documentation/filesystems/vfs.txt (and | |
342 | +look at examples of other filesystems) for guidance. |
Documentation/filesystems/vfs.txt
... | ... | @@ -847,7 +847,8 @@ |
847 | 847 | |
848 | 848 | struct dentry_operations { |
849 | 849 | int (*d_revalidate)(struct dentry *, struct nameidata *); |
850 | - int (*d_hash)(struct dentry *, struct qstr *); | |
850 | + int (*d_hash)(const struct dentry *, const struct inode *, | |
851 | + struct qstr *); | |
851 | 852 | int (*d_compare)(const struct dentry *, const struct inode *, |
852 | 853 | const struct dentry *, const struct inode *, |
853 | 854 | unsigned int, const char *, const struct qstr *); |
... | ... | @@ -864,7 +865,10 @@ |
864 | 865 | |
865 | 866 | d_hash: called when the VFS adds a dentry to the hash table. The first |
866 | 867 | dentry passed to d_hash is the parent directory that the name is |
867 | - to be hashed into. | |
868 | + to be hashed into. The inode is the dentry's inode. | |
869 | + | |
870 | + Same locking and synchronisation rules as d_compare regarding | |
871 | + what is safe to dereference etc. | |
868 | 872 | |
869 | 873 | d_compare: called to compare a dentry name with a given name. The first |
870 | 874 | dentry is the parent of the dentry to be compared, the second is |
drivers/staging/smbfs/cache.c
... | ... | @@ -134,7 +134,7 @@ |
134 | 134 | qname->hash = full_name_hash(qname->name, qname->len); |
135 | 135 | |
136 | 136 | if (dentry->d_op && dentry->d_op->d_hash) |
137 | - if (dentry->d_op->d_hash(dentry, qname) != 0) | |
137 | + if (dentry->d_op->d_hash(dentry, inode, qname) != 0) | |
138 | 138 | goto end_advance; |
139 | 139 | |
140 | 140 | newdent = d_lookup(dentry, qname); |
drivers/staging/smbfs/dir.c
... | ... | @@ -274,7 +274,8 @@ |
274 | 274 | * Dentry operations routines |
275 | 275 | */ |
276 | 276 | static int smb_lookup_validate(struct dentry *, struct nameidata *); |
277 | -static int smb_hash_dentry(struct dentry *, struct qstr *); | |
277 | +static int smb_hash_dentry(const struct dentry *, const struct inode *, | |
278 | + struct qstr *); | |
278 | 279 | static int smb_compare_dentry(const struct dentry *, |
279 | 280 | const struct inode *, |
280 | 281 | const struct dentry *, const struct inode *, |
... | ... | @@ -336,7 +337,8 @@ |
336 | 337 | } |
337 | 338 | |
338 | 339 | static int |
339 | -smb_hash_dentry(struct dentry *dir, struct qstr *this) | |
340 | +smb_hash_dentry(const struct dentry *dir, const struct inode *inode, | |
341 | + struct qstr *this) | |
340 | 342 | { |
341 | 343 | unsigned long hash; |
342 | 344 | int i; |
fs/adfs/dir.c
... | ... | @@ -201,7 +201,8 @@ |
201 | 201 | }; |
202 | 202 | |
203 | 203 | static int |
204 | -adfs_hash(struct dentry *parent, struct qstr *qstr) | |
204 | +adfs_hash(const struct dentry *parent, const struct inode *inode, | |
205 | + struct qstr *qstr) | |
205 | 206 | { |
206 | 207 | const unsigned int name_len = ADFS_SB(parent->d_sb)->s_namelen; |
207 | 208 | const unsigned char *name; |
fs/affs/namei.c
... | ... | @@ -13,13 +13,15 @@ |
13 | 13 | typedef int (*toupper_t)(int); |
14 | 14 | |
15 | 15 | static int affs_toupper(int ch); |
16 | -static int affs_hash_dentry(struct dentry *, struct qstr *); | |
16 | +static int affs_hash_dentry(const struct dentry *, | |
17 | + const struct inode *, struct qstr *); | |
17 | 18 | static int affs_compare_dentry(const struct dentry *parent, |
18 | 19 | const struct inode *pinode, |
19 | 20 | const struct dentry *dentry, const struct inode *inode, |
20 | 21 | unsigned int len, const char *str, const struct qstr *name); |
21 | 22 | static int affs_intl_toupper(int ch); |
22 | -static int affs_intl_hash_dentry(struct dentry *, struct qstr *); | |
23 | +static int affs_intl_hash_dentry(const struct dentry *, | |
24 | + const struct inode *, struct qstr *); | |
23 | 25 | static int affs_intl_compare_dentry(const struct dentry *parent, |
24 | 26 | const struct inode *pinode, |
25 | 27 | const struct dentry *dentry, const struct inode *inode, |
26 | 28 | |
... | ... | @@ -64,13 +66,13 @@ |
64 | 66 | * Note: the dentry argument is the parent dentry. |
65 | 67 | */ |
66 | 68 | static inline int |
67 | -__affs_hash_dentry(struct dentry *dentry, struct qstr *qstr, toupper_t toupper) | |
69 | +__affs_hash_dentry(struct qstr *qstr, toupper_t toupper) | |
68 | 70 | { |
69 | 71 | const u8 *name = qstr->name; |
70 | 72 | unsigned long hash; |
71 | 73 | int i; |
72 | 74 | |
73 | - i = affs_check_name(qstr->name,qstr->len); | |
75 | + i = affs_check_name(qstr->name, qstr->len); | |
74 | 76 | if (i) |
75 | 77 | return i; |
76 | 78 | |
77 | 79 | |
78 | 80 | |
79 | 81 | |
... | ... | @@ -84,14 +86,16 @@ |
84 | 86 | } |
85 | 87 | |
86 | 88 | static int |
87 | -affs_hash_dentry(struct dentry *dentry, struct qstr *qstr) | |
89 | +affs_hash_dentry(const struct dentry *dentry, const struct inode *inode, | |
90 | + struct qstr *qstr) | |
88 | 91 | { |
89 | - return __affs_hash_dentry(dentry, qstr, affs_toupper); | |
92 | + return __affs_hash_dentry(qstr, affs_toupper); | |
90 | 93 | } |
91 | 94 | static int |
92 | -affs_intl_hash_dentry(struct dentry *dentry, struct qstr *qstr) | |
95 | +affs_intl_hash_dentry(const struct dentry *dentry, const struct inode *inode, | |
96 | + struct qstr *qstr) | |
93 | 97 | { |
94 | - return __affs_hash_dentry(dentry, qstr, affs_intl_toupper); | |
98 | + return __affs_hash_dentry(qstr, affs_intl_toupper); | |
95 | 99 | } |
96 | 100 | |
97 | 101 | static inline int __affs_compare_dentry(unsigned int len, |
fs/cifs/dir.c
... | ... | @@ -700,9 +700,10 @@ |
700 | 700 | /* d_delete: cifs_d_delete, */ /* not needed except for debugging */ |
701 | 701 | }; |
702 | 702 | |
703 | -static int cifs_ci_hash(struct dentry *dentry, struct qstr *q) | |
703 | +static int cifs_ci_hash(const struct dentry *dentry, const struct inode *inode, | |
704 | + struct qstr *q) | |
704 | 705 | { |
705 | - struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls; | |
706 | + struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls; | |
706 | 707 | unsigned long hash; |
707 | 708 | int i; |
708 | 709 |
fs/cifs/readdir.c
fs/dcache.c
... | ... | @@ -1478,7 +1478,7 @@ |
1478 | 1478 | */ |
1479 | 1479 | name->hash = full_name_hash(name->name, name->len); |
1480 | 1480 | if (dir->d_op && dir->d_op->d_hash) { |
1481 | - if (dir->d_op->d_hash(dir, name) < 0) | |
1481 | + if (dir->d_op->d_hash(dir, dir->d_inode, name) < 0) | |
1482 | 1482 | goto out; |
1483 | 1483 | } |
1484 | 1484 | dentry = d_lookup(dir, name); |
fs/ecryptfs/inode.c
... | ... | @@ -454,7 +454,7 @@ |
454 | 454 | lower_name.hash = ecryptfs_dentry->d_name.hash; |
455 | 455 | if (lower_dir_dentry->d_op && lower_dir_dentry->d_op->d_hash) { |
456 | 456 | rc = lower_dir_dentry->d_op->d_hash(lower_dir_dentry, |
457 | - &lower_name); | |
457 | + lower_dir_dentry->d_inode, &lower_name); | |
458 | 458 | if (rc < 0) |
459 | 459 | goto out_d_drop; |
460 | 460 | } |
... | ... | @@ -489,7 +489,7 @@ |
489 | 489 | lower_name.hash = full_name_hash(lower_name.name, lower_name.len); |
490 | 490 | if (lower_dir_dentry->d_op && lower_dir_dentry->d_op->d_hash) { |
491 | 491 | rc = lower_dir_dentry->d_op->d_hash(lower_dir_dentry, |
492 | - &lower_name); | |
492 | + lower_dir_dentry->d_inode, &lower_name); | |
493 | 493 | if (rc < 0) |
494 | 494 | goto out_d_drop; |
495 | 495 | } |
fs/fat/namei_msdos.c
... | ... | @@ -148,7 +148,8 @@ |
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(struct dentry *dentry, struct qstr *qstr) | |
151 | +static int msdos_hash(const struct dentry *dentry, const struct inode *inode, | |
152 | + struct qstr *qstr) | |
152 | 153 | { |
153 | 154 | struct fat_mount_options *options = &MSDOS_SB(dentry->d_sb)->options; |
154 | 155 | unsigned char msdos_name[MSDOS_NAME]; |
fs/fat/namei_vfat.c
... | ... | @@ -103,7 +103,8 @@ |
103 | 103 | * that the existing dentry can be used. The vfat fs routines will |
104 | 104 | * return ENOENT or EINVAL as appropriate. |
105 | 105 | */ |
106 | -static int vfat_hash(struct dentry *dentry, struct qstr *qstr) | |
106 | +static int vfat_hash(const struct dentry *dentry, const struct inode *inode, | |
107 | + struct qstr *qstr) | |
107 | 108 | { |
108 | 109 | qstr->hash = full_name_hash(qstr->name, vfat_striptail_len(qstr)); |
109 | 110 | return 0; |
110 | 111 | |
... | ... | @@ -115,9 +116,10 @@ |
115 | 116 | * that the existing dentry can be used. The vfat fs routines will |
116 | 117 | * return ENOENT or EINVAL as appropriate. |
117 | 118 | */ |
118 | -static int vfat_hashi(struct dentry *dentry, struct qstr *qstr) | |
119 | +static int vfat_hashi(const struct dentry *dentry, const struct inode *inode, | |
120 | + struct qstr *qstr) | |
119 | 121 | { |
120 | - struct nls_table *t = MSDOS_SB(dentry->d_inode->i_sb)->nls_io; | |
122 | + struct nls_table *t = MSDOS_SB(dentry->d_sb)->nls_io; | |
121 | 123 | const unsigned char *name; |
122 | 124 | unsigned int len; |
123 | 125 | unsigned long hash; |
fs/gfs2/dentry.c
... | ... | @@ -100,7 +100,8 @@ |
100 | 100 | return 0; |
101 | 101 | } |
102 | 102 | |
103 | -static int gfs2_dhash(struct dentry *dentry, struct qstr *str) | |
103 | +static int gfs2_dhash(const struct dentry *dentry, const struct inode *inode, | |
104 | + struct qstr *str) | |
104 | 105 | { |
105 | 106 | str->hash = gfs2_disk_hash(str->name, str->len); |
106 | 107 | return 0; |
fs/hfs/hfs_fs.h
... | ... | @@ -213,7 +213,8 @@ |
213 | 213 | /* string.c */ |
214 | 214 | extern const struct dentry_operations hfs_dentry_operations; |
215 | 215 | |
216 | -extern int hfs_hash_dentry(struct dentry *, struct qstr *); | |
216 | +extern int hfs_hash_dentry(const struct dentry *, const struct inode *, | |
217 | + struct qstr *); | |
217 | 218 | extern int hfs_strcmp(const unsigned char *, unsigned int, |
218 | 219 | const unsigned char *, unsigned int); |
219 | 220 | extern int hfs_compare_dentry(const struct dentry *parent, |
fs/hfs/string.c
... | ... | @@ -51,7 +51,8 @@ |
51 | 51 | /* |
52 | 52 | * Hash a string to an integer in a case-independent way |
53 | 53 | */ |
54 | -int hfs_hash_dentry(struct dentry *dentry, struct qstr *this) | |
54 | +int hfs_hash_dentry(const struct dentry *dentry, const struct inode *inode, | |
55 | + struct qstr *this) | |
55 | 56 | { |
56 | 57 | const unsigned char *name = this->name; |
57 | 58 | unsigned int hash, len = this->len; |
fs/hfsplus/hfsplus_fs.h
... | ... | @@ -379,7 +379,8 @@ |
379 | 379 | int hfsplus_strcmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *); |
380 | 380 | int hfsplus_uni2asc(struct super_block *, const struct hfsplus_unistr *, char *, int *); |
381 | 381 | int hfsplus_asc2uni(struct super_block *, struct hfsplus_unistr *, const char *, int); |
382 | -int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str); | |
382 | +int hfsplus_hash_dentry(const struct dentry *dentry, const struct inode *inode, | |
383 | + struct qstr *str); | |
383 | 384 | int hfsplus_compare_dentry(const struct dentry *parent, |
384 | 385 | const struct inode *pinode, |
385 | 386 | const struct dentry *dentry, const struct inode *inode, |
fs/hfsplus/unicode.c
... | ... | @@ -320,7 +320,8 @@ |
320 | 320 | * Composed unicode characters are decomposed and case-folding is performed |
321 | 321 | * if the appropriate bits are (un)set on the superblock. |
322 | 322 | */ |
323 | -int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str) | |
323 | +int hfsplus_hash_dentry(const struct dentry *dentry, const struct inode *inode, | |
324 | + struct qstr *str) | |
324 | 325 | { |
325 | 326 | struct super_block *sb = dentry->d_sb; |
326 | 327 | const char *astr; |
fs/hpfs/dentry.c
... | ... | @@ -12,7 +12,8 @@ |
12 | 12 | * Note: the dentry argument is the parent dentry. |
13 | 13 | */ |
14 | 14 | |
15 | -static int hpfs_hash_dentry(struct dentry *dentry, struct qstr *qstr) | |
15 | +static int hpfs_hash_dentry(const struct dentry *dentry, const struct inode *inode, | |
16 | + struct qstr *qstr) | |
16 | 17 | { |
17 | 18 | unsigned long hash; |
18 | 19 | int i; |
fs/isofs/inode.c
... | ... | @@ -26,8 +26,10 @@ |
26 | 26 | |
27 | 27 | #define BEQUIET |
28 | 28 | |
29 | -static int isofs_hashi(struct dentry *parent, struct qstr *qstr); | |
30 | -static int isofs_hash(struct dentry *parent, struct qstr *qstr); | |
29 | +static int isofs_hashi(const struct dentry *parent, const struct inode *inode, | |
30 | + struct qstr *qstr); | |
31 | +static int isofs_hash(const struct dentry *parent, const struct inode *inode, | |
32 | + struct qstr *qstr); | |
31 | 33 | static int isofs_dentry_cmpi(const struct dentry *parent, |
32 | 34 | const struct inode *pinode, |
33 | 35 | const struct dentry *dentry, const struct inode *inode, |
... | ... | @@ -38,8 +40,10 @@ |
38 | 40 | unsigned int len, const char *str, const struct qstr *name); |
39 | 41 | |
40 | 42 | #ifdef CONFIG_JOLIET |
41 | -static int isofs_hashi_ms(struct dentry *parent, struct qstr *qstr); | |
42 | -static int isofs_hash_ms(struct dentry *parent, struct qstr *qstr); | |
43 | +static int isofs_hashi_ms(const struct dentry *parent, const struct inode *inode, | |
44 | + struct qstr *qstr); | |
45 | +static int isofs_hash_ms(const struct dentry *parent, const struct inode *inode, | |
46 | + struct qstr *qstr); | |
43 | 47 | static int isofs_dentry_cmpi_ms(const struct dentry *parent, |
44 | 48 | const struct inode *pinode, |
45 | 49 | const struct dentry *dentry, const struct inode *inode, |
... | ... | @@ -172,7 +176,7 @@ |
172 | 176 | * Compute the hash for the isofs name corresponding to the dentry. |
173 | 177 | */ |
174 | 178 | static int |
175 | -isofs_hash_common(struct dentry *dentry, struct qstr *qstr, int ms) | |
179 | +isofs_hash_common(const struct dentry *dentry, struct qstr *qstr, int ms) | |
176 | 180 | { |
177 | 181 | const char *name; |
178 | 182 | int len; |
... | ... | @@ -193,7 +197,7 @@ |
193 | 197 | * Compute the hash for the isofs name corresponding to the dentry. |
194 | 198 | */ |
195 | 199 | static int |
196 | -isofs_hashi_common(struct dentry *dentry, struct qstr *qstr, int ms) | |
200 | +isofs_hashi_common(const struct dentry *dentry, struct qstr *qstr, int ms) | |
197 | 201 | { |
198 | 202 | const char *name; |
199 | 203 | int len; |
200 | 204 | |
... | ... | @@ -248,13 +252,15 @@ |
248 | 252 | } |
249 | 253 | |
250 | 254 | static int |
251 | -isofs_hash(struct dentry *dentry, struct qstr *qstr) | |
255 | +isofs_hash(const struct dentry *dentry, const struct inode *inode, | |
256 | + struct qstr *qstr) | |
252 | 257 | { |
253 | 258 | return isofs_hash_common(dentry, qstr, 0); |
254 | 259 | } |
255 | 260 | |
256 | 261 | static int |
257 | -isofs_hashi(struct dentry *dentry, struct qstr *qstr) | |
262 | +isofs_hashi(const struct dentry *dentry, const struct inode *inode, | |
263 | + struct qstr *qstr) | |
258 | 264 | { |
259 | 265 | return isofs_hashi_common(dentry, qstr, 0); |
260 | 266 | } |
261 | 267 | |
... | ... | @@ -277,13 +283,15 @@ |
277 | 283 | |
278 | 284 | #ifdef CONFIG_JOLIET |
279 | 285 | static int |
280 | -isofs_hash_ms(struct dentry *dentry, struct qstr *qstr) | |
286 | +isofs_hash_ms(const struct dentry *dentry, const struct inode *inode, | |
287 | + struct qstr *qstr) | |
281 | 288 | { |
282 | 289 | return isofs_hash_common(dentry, qstr, 1); |
283 | 290 | } |
284 | 291 | |
285 | 292 | static int |
286 | -isofs_hashi_ms(struct dentry *dentry, struct qstr *qstr) | |
293 | +isofs_hashi_ms(const struct dentry *dentry, const struct inode *inode, | |
294 | + struct qstr *qstr) | |
287 | 295 | { |
288 | 296 | return isofs_hashi_common(dentry, qstr, 1); |
289 | 297 | } |
fs/jfs/namei.c
... | ... | @@ -1574,7 +1574,8 @@ |
1574 | 1574 | .llseek = generic_file_llseek, |
1575 | 1575 | }; |
1576 | 1576 | |
1577 | -static int jfs_ci_hash(struct dentry *dir, struct qstr *this) | |
1577 | +static int jfs_ci_hash(const struct dentry *dir, const struct inode *inode, | |
1578 | + struct qstr *this) | |
1578 | 1579 | { |
1579 | 1580 | unsigned long hash; |
1580 | 1581 | int i; |
fs/namei.c
... | ... | @@ -731,7 +731,8 @@ |
731 | 731 | * to use its own hash.. |
732 | 732 | */ |
733 | 733 | if (nd->path.dentry->d_op && nd->path.dentry->d_op->d_hash) { |
734 | - int err = nd->path.dentry->d_op->d_hash(nd->path.dentry, name); | |
734 | + int err = nd->path.dentry->d_op->d_hash(nd->path.dentry, | |
735 | + nd->path.dentry->d_inode, name); | |
735 | 736 | if (err < 0) |
736 | 737 | return err; |
737 | 738 | } |
... | ... | @@ -1134,7 +1135,7 @@ |
1134 | 1135 | * to use its own hash.. |
1135 | 1136 | */ |
1136 | 1137 | if (base->d_op && base->d_op->d_hash) { |
1137 | - err = base->d_op->d_hash(base, name); | |
1138 | + err = base->d_op->d_hash(base, inode, name); | |
1138 | 1139 | dentry = ERR_PTR(err); |
1139 | 1140 | if (err < 0) |
1140 | 1141 | goto out; |
fs/ncpfs/dir.c
... | ... | @@ -74,7 +74,8 @@ |
74 | 74 | * Dentry operations routines |
75 | 75 | */ |
76 | 76 | static int ncp_lookup_validate(struct dentry *, struct nameidata *); |
77 | -static int ncp_hash_dentry(struct dentry *, struct qstr *); | |
77 | +static int ncp_hash_dentry(const struct dentry *, const struct inode *, | |
78 | + struct qstr *); | |
78 | 79 | static int ncp_compare_dentry(const struct dentry *, const struct inode *, |
79 | 80 | const struct dentry *, const struct inode *, |
80 | 81 | unsigned int, const char *, const struct qstr *); |
81 | 82 | |
... | ... | @@ -129,9 +130,10 @@ |
129 | 130 | * is case-sensitive. |
130 | 131 | */ |
131 | 132 | static int |
132 | -ncp_hash_dentry(struct dentry *dentry, struct qstr *this) | |
133 | +ncp_hash_dentry(const struct dentry *dentry, const struct inode *inode, | |
134 | + struct qstr *this) | |
133 | 135 | { |
134 | - if (!ncp_case_sensitive(dentry->d_inode)) { | |
136 | + if (!ncp_case_sensitive(inode)) { | |
135 | 137 | struct super_block *sb = dentry->d_sb; |
136 | 138 | struct nls_table *t; |
137 | 139 | unsigned long hash; |
... | ... | @@ -597,7 +599,7 @@ |
597 | 599 | qname.hash = full_name_hash(qname.name, qname.len); |
598 | 600 | |
599 | 601 | if (dentry->d_op && dentry->d_op->d_hash) |
600 | - if (dentry->d_op->d_hash(dentry, &qname) != 0) | |
602 | + if (dentry->d_op->d_hash(dentry, dentry->d_inode, &qname) != 0) | |
601 | 603 | goto end_advance; |
602 | 604 | |
603 | 605 | newdent = d_lookup(dentry, &qname); |
fs/sysv/namei.c
... | ... | @@ -27,7 +27,8 @@ |
27 | 27 | return err; |
28 | 28 | } |
29 | 29 | |
30 | -static int sysv_hash(struct dentry *dentry, struct qstr *qstr) | |
30 | +static int sysv_hash(const struct dentry *dentry, const struct inode *inode, | |
31 | + struct qstr *qstr) | |
31 | 32 | { |
32 | 33 | /* Truncate the name in place, avoids having to define a compare |
33 | 34 | function. */ |
include/linux/dcache.h
... | ... | @@ -133,7 +133,8 @@ |
133 | 133 | |
134 | 134 | struct dentry_operations { |
135 | 135 | int (*d_revalidate)(struct dentry *, struct nameidata *); |
136 | - int (*d_hash)(struct dentry *, struct qstr *); | |
136 | + int (*d_hash)(const struct dentry *, const struct inode *, | |
137 | + struct qstr *); | |
137 | 138 | int (*d_compare)(const struct dentry *, const struct inode *, |
138 | 139 | const struct dentry *, const struct inode *, |
139 | 140 | unsigned int, const char *, const struct qstr *); |