diff options
author | Nick Piggin <npiggin@kernel.dk> | 2011-01-07 01:49:28 -0500 |
---|---|---|
committer | Nick Piggin <npiggin@kernel.dk> | 2011-01-07 01:50:20 -0500 |
commit | b1e6a015a580ad145689ad1d6b4aa0e03e6c868b (patch) | |
tree | 57a10ef164e4d2f798d9b832dbeaf973aca2ab83 | |
parent | 621e155a3591962420eacdd39f6f0aa29ceb221e (diff) |
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>
-rw-r--r-- | Documentation/filesystems/Locking | 5 | ||||
-rw-r--r-- | Documentation/filesystems/porting | 7 | ||||
-rw-r--r-- | Documentation/filesystems/vfs.txt | 8 | ||||
-rw-r--r-- | drivers/staging/smbfs/cache.c | 2 | ||||
-rw-r--r-- | drivers/staging/smbfs/dir.c | 6 | ||||
-rw-r--r-- | fs/adfs/dir.c | 3 | ||||
-rw-r--r-- | fs/affs/namei.c | 20 | ||||
-rw-r--r-- | fs/cifs/dir.c | 5 | ||||
-rw-r--r-- | fs/cifs/readdir.c | 2 | ||||
-rw-r--r-- | fs/dcache.c | 2 | ||||
-rw-r--r-- | fs/ecryptfs/inode.c | 4 | ||||
-rw-r--r-- | fs/fat/namei_msdos.c | 3 | ||||
-rw-r--r-- | fs/fat/namei_vfat.c | 8 | ||||
-rw-r--r-- | fs/gfs2/dentry.c | 3 | ||||
-rw-r--r-- | fs/hfs/hfs_fs.h | 3 | ||||
-rw-r--r-- | fs/hfs/string.c | 3 | ||||
-rw-r--r-- | fs/hfsplus/hfsplus_fs.h | 3 | ||||
-rw-r--r-- | fs/hfsplus/unicode.c | 3 | ||||
-rw-r--r-- | fs/hpfs/dentry.c | 3 | ||||
-rw-r--r-- | fs/isofs/inode.c | 28 | ||||
-rw-r--r-- | fs/jfs/namei.c | 3 | ||||
-rw-r--r-- | fs/namei.c | 5 | ||||
-rw-r--r-- | fs/ncpfs/dir.c | 10 | ||||
-rw-r--r-- | fs/sysv/namei.c | 3 | ||||
-rw-r--r-- | include/linux/dcache.h | 3 |
25 files changed, 94 insertions, 51 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 9a76f8d8bf95..a15ee207b449 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
@@ -10,7 +10,8 @@ be able to use diff(1). | |||
10 | --------------------------- dentry_operations -------------------------- | 10 | --------------------------- dentry_operations -------------------------- |
11 | prototypes: | 11 | prototypes: |
12 | int (*d_revalidate)(struct dentry *, int); | 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 | int (*d_compare)(const struct dentry *, const struct inode *, | 15 | int (*d_compare)(const struct dentry *, const struct inode *, |
15 | const struct dentry *, const struct inode *, | 16 | const struct dentry *, const struct inode *, |
16 | unsigned int, const char *, const struct qstr *); | 17 | unsigned int, const char *, const struct qstr *); |
@@ -22,7 +23,7 @@ prototypes: | |||
22 | locking rules: | 23 | locking rules: |
23 | dcache_lock rename_lock ->d_lock may block | 24 | dcache_lock rename_lock ->d_lock may block |
24 | d_revalidate: no no no yes | 25 | d_revalidate: no no no yes |
25 | d_hash no no no yes | 26 | d_hash no no no no |
26 | d_compare: no yes no no | 27 | d_compare: no yes no no |
27 | d_delete: yes no yes no | 28 | d_delete: yes no yes no |
28 | d_release: no no no yes | 29 | d_release: no no no yes |
diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index d44511e20828..9fd31940a8ef 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting | |||
@@ -333,3 +333,10 @@ unreferenced dentries, and is now only called when the dentry refcount goes to | |||
333 | .d_compare() calling convention and locking rules are significantly | 333 | .d_compare() calling convention and locking rules are significantly |
334 | changed. Read updated documentation in Documentation/filesystems/vfs.txt (and | 334 | changed. Read updated documentation in Documentation/filesystems/vfs.txt (and |
335 | look at examples of other filesystems) for guidance. | 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. | ||
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 250681b8c7cc..69b10ff5ec81 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt | |||
@@ -847,7 +847,8 @@ defined: | |||
847 | 847 | ||
848 | struct dentry_operations { | 848 | struct dentry_operations { |
849 | int (*d_revalidate)(struct dentry *, struct nameidata *); | 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 | int (*d_compare)(const struct dentry *, const struct inode *, | 852 | int (*d_compare)(const struct dentry *, const struct inode *, |
852 | const struct dentry *, const struct inode *, | 853 | const struct dentry *, const struct inode *, |
853 | unsigned int, const char *, const struct qstr *); | 854 | unsigned int, const char *, const struct qstr *); |
@@ -864,7 +865,10 @@ struct dentry_operations { | |||
864 | 865 | ||
865 | d_hash: called when the VFS adds a dentry to the hash table. The first | 866 | d_hash: called when the VFS adds a dentry to the hash table. The first |
866 | dentry passed to d_hash is the parent directory that the name is | 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 | d_compare: called to compare a dentry name with a given name. The first | 873 | d_compare: called to compare a dentry name with a given name. The first |
870 | dentry is the parent of the dentry to be compared, the second is | 874 | dentry is the parent of the dentry to be compared, the second is |
diff --git a/drivers/staging/smbfs/cache.c b/drivers/staging/smbfs/cache.c index dbd2e1df3ba9..0beded260b00 100644 --- a/drivers/staging/smbfs/cache.c +++ b/drivers/staging/smbfs/cache.c | |||
@@ -134,7 +134,7 @@ smb_fill_cache(struct file *filp, void *dirent, filldir_t filldir, | |||
134 | qname->hash = full_name_hash(qname->name, qname->len); | 134 | qname->hash = full_name_hash(qname->name, qname->len); |
135 | 135 | ||
136 | if (dentry->d_op && dentry->d_op->d_hash) | 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 | goto end_advance; | 138 | goto end_advance; |
139 | 139 | ||
140 | newdent = d_lookup(dentry, qname); | 140 | newdent = d_lookup(dentry, qname); |
diff --git a/drivers/staging/smbfs/dir.c b/drivers/staging/smbfs/dir.c index bd63229f43f2..5f79799d5d4a 100644 --- a/drivers/staging/smbfs/dir.c +++ b/drivers/staging/smbfs/dir.c | |||
@@ -274,7 +274,8 @@ smb_dir_open(struct inode *dir, struct file *file) | |||
274 | * Dentry operations routines | 274 | * Dentry operations routines |
275 | */ | 275 | */ |
276 | static int smb_lookup_validate(struct dentry *, struct nameidata *); | 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 | static int smb_compare_dentry(const struct dentry *, | 279 | static int smb_compare_dentry(const struct dentry *, |
279 | const struct inode *, | 280 | const struct inode *, |
280 | const struct dentry *, const struct inode *, | 281 | const struct dentry *, const struct inode *, |
@@ -336,7 +337,8 @@ smb_lookup_validate(struct dentry * dentry, struct nameidata *nd) | |||
336 | } | 337 | } |
337 | 338 | ||
338 | static int | 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 | unsigned long hash; | 343 | unsigned long hash; |
342 | int i; | 344 | int i; |
diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c index c8ed66162bd4..a11e5e102716 100644 --- a/fs/adfs/dir.c +++ b/fs/adfs/dir.c | |||
@@ -201,7 +201,8 @@ const struct file_operations adfs_dir_operations = { | |||
201 | }; | 201 | }; |
202 | 202 | ||
203 | static int | 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 | const unsigned int name_len = ADFS_SB(parent->d_sb)->s_namelen; | 207 | const unsigned int name_len = ADFS_SB(parent->d_sb)->s_namelen; |
207 | const unsigned char *name; | 208 | const unsigned char *name; |
diff --git a/fs/affs/namei.c b/fs/affs/namei.c index 547d5deb0d42..5aca08c21100 100644 --- a/fs/affs/namei.c +++ b/fs/affs/namei.c | |||
@@ -13,13 +13,15 @@ | |||
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(struct dentry *, struct qstr *); | 16 | static int affs_hash_dentry(const struct dentry *, |
17 | const struct inode *, struct qstr *); | ||
17 | static int affs_compare_dentry(const struct dentry *parent, | 18 | static int affs_compare_dentry(const struct dentry *parent, |
18 | const struct inode *pinode, | 19 | const struct inode *pinode, |
19 | const struct dentry *dentry, const struct inode *inode, | 20 | const struct dentry *dentry, const struct inode *inode, |
20 | unsigned int len, const char *str, const struct qstr *name); | 21 | unsigned int len, const char *str, const struct qstr *name); |
21 | static int affs_intl_toupper(int ch); | 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 | static int affs_intl_compare_dentry(const struct dentry *parent, | 25 | static int affs_intl_compare_dentry(const struct dentry *parent, |
24 | const struct inode *pinode, | 26 | const struct inode *pinode, |
25 | const struct dentry *dentry, const struct inode *inode, | 27 | const struct dentry *dentry, const struct inode *inode, |
@@ -64,13 +66,13 @@ affs_get_toupper(struct super_block *sb) | |||
64 | * Note: the dentry argument is the parent dentry. | 66 | * Note: the dentry argument is the parent dentry. |
65 | */ | 67 | */ |
66 | static inline int | 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 | const u8 *name = qstr->name; | 71 | const u8 *name = qstr->name; |
70 | unsigned long hash; | 72 | unsigned long hash; |
71 | int i; | 73 | int i; |
72 | 74 | ||
73 | i = affs_check_name(qstr->name,qstr->len); | 75 | i = affs_check_name(qstr->name, qstr->len); |
74 | if (i) | 76 | if (i) |
75 | return i; | 77 | return i; |
76 | 78 | ||
@@ -84,14 +86,16 @@ __affs_hash_dentry(struct dentry *dentry, struct qstr *qstr, toupper_t toupper) | |||
84 | } | 86 | } |
85 | 87 | ||
86 | static int | 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 | static int | 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 | static inline int __affs_compare_dentry(unsigned int len, | 101 | static inline int __affs_compare_dentry(unsigned int len, |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index c60133f0d8e4..88bfe686ac00 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -700,9 +700,10 @@ const struct dentry_operations cifs_dentry_ops = { | |||
700 | /* d_delete: cifs_d_delete, */ /* not needed except for debugging */ | 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 | unsigned long hash; | 707 | unsigned long hash; |
707 | int i; | 708 | int i; |
708 | 709 | ||
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index a73eb9f4bdaf..ee463aeca0b0 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -79,7 +79,7 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name, | |||
79 | cFYI(1, "For %s", name->name); | 79 | cFYI(1, "For %s", name->name); |
80 | 80 | ||
81 | if (parent->d_op && parent->d_op->d_hash) | 81 | if (parent->d_op && parent->d_op->d_hash) |
82 | parent->d_op->d_hash(parent, name); | 82 | parent->d_op->d_hash(parent, parent->d_inode, name); |
83 | else | 83 | else |
84 | name->hash = full_name_hash(name->name, name->len); | 84 | name->hash = full_name_hash(name->name, name->len); |
85 | 85 | ||
diff --git a/fs/dcache.c b/fs/dcache.c index 7075555fbb04..6f59f375ed9d 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -1478,7 +1478,7 @@ struct dentry *d_hash_and_lookup(struct dentry *dir, struct qstr *name) | |||
1478 | */ | 1478 | */ |
1479 | name->hash = full_name_hash(name->name, name->len); | 1479 | name->hash = full_name_hash(name->name, name->len); |
1480 | if (dir->d_op && dir->d_op->d_hash) { | 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 | goto out; | 1482 | goto out; |
1483 | } | 1483 | } |
1484 | dentry = d_lookup(dir, name); | 1484 | dentry = d_lookup(dir, name); |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 9d1a22d62765..a1ed7a7cb173 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -454,7 +454,7 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
454 | lower_name.hash = ecryptfs_dentry->d_name.hash; | 454 | lower_name.hash = ecryptfs_dentry->d_name.hash; |
455 | if (lower_dir_dentry->d_op && lower_dir_dentry->d_op->d_hash) { | 455 | if (lower_dir_dentry->d_op && lower_dir_dentry->d_op->d_hash) { |
456 | rc = lower_dir_dentry->d_op->d_hash(lower_dir_dentry, | 456 | rc = lower_dir_dentry->d_op->d_hash(lower_dir_dentry, |
457 | &lower_name); | 457 | lower_dir_dentry->d_inode, &lower_name); |
458 | if (rc < 0) | 458 | if (rc < 0) |
459 | goto out_d_drop; | 459 | goto out_d_drop; |
460 | } | 460 | } |
@@ -489,7 +489,7 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, | |||
489 | lower_name.hash = full_name_hash(lower_name.name, lower_name.len); | 489 | lower_name.hash = full_name_hash(lower_name.name, lower_name.len); |
490 | if (lower_dir_dentry->d_op && lower_dir_dentry->d_op->d_hash) { | 490 | if (lower_dir_dentry->d_op && lower_dir_dentry->d_op->d_hash) { |
491 | rc = lower_dir_dentry->d_op->d_hash(lower_dir_dentry, | 491 | rc = lower_dir_dentry->d_op->d_hash(lower_dir_dentry, |
492 | &lower_name); | 492 | lower_dir_dentry->d_inode, &lower_name); |
493 | if (rc < 0) | 493 | if (rc < 0) |
494 | goto out_d_drop; | 494 | goto out_d_drop; |
495 | } | 495 | } |
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index 99d3c7ac973c..3b3e072d8982 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c | |||
@@ -148,7 +148,8 @@ 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(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 | struct fat_mount_options *options = &MSDOS_SB(dentry->d_sb)->options; | 154 | struct fat_mount_options *options = &MSDOS_SB(dentry->d_sb)->options; |
154 | unsigned char msdos_name[MSDOS_NAME]; | 155 | unsigned char msdos_name[MSDOS_NAME]; |
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index 95e00ab84c3f..4fc06278db48 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c | |||
@@ -103,7 +103,8 @@ static unsigned int vfat_striptail_len(const struct qstr *qstr) | |||
103 | * that the existing dentry can be used. The vfat fs routines will | 103 | * that the existing dentry can be used. The vfat fs routines will |
104 | * return ENOENT or EINVAL as appropriate. | 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 | qstr->hash = full_name_hash(qstr->name, vfat_striptail_len(qstr)); | 109 | qstr->hash = full_name_hash(qstr->name, vfat_striptail_len(qstr)); |
109 | return 0; | 110 | return 0; |
@@ -115,9 +116,10 @@ static int vfat_hash(struct dentry *dentry, struct qstr *qstr) | |||
115 | * that the existing dentry can be used. The vfat fs routines will | 116 | * that the existing dentry can be used. The vfat fs routines will |
116 | * return ENOENT or EINVAL as appropriate. | 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 | const unsigned char *name; | 123 | const unsigned char *name; |
122 | unsigned int len; | 124 | unsigned int len; |
123 | unsigned long hash; | 125 | unsigned long hash; |
diff --git a/fs/gfs2/dentry.c b/fs/gfs2/dentry.c index e80fea2f65ff..50497f65763b 100644 --- a/fs/gfs2/dentry.c +++ b/fs/gfs2/dentry.c | |||
@@ -100,7 +100,8 @@ fail: | |||
100 | return 0; | 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 | str->hash = gfs2_disk_hash(str->name, str->len); | 106 | str->hash = gfs2_disk_hash(str->name, str->len); |
106 | return 0; | 107 | return 0; |
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h index 8cd876f0e961..ad97c2d58287 100644 --- a/fs/hfs/hfs_fs.h +++ b/fs/hfs/hfs_fs.h | |||
@@ -213,7 +213,8 @@ extern int hfs_part_find(struct super_block *, sector_t *, sector_t *); | |||
213 | /* string.c */ | 213 | /* string.c */ |
214 | extern const struct dentry_operations hfs_dentry_operations; | 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 | extern int hfs_strcmp(const unsigned char *, unsigned int, | 218 | extern int hfs_strcmp(const unsigned char *, unsigned int, |
218 | const unsigned char *, unsigned int); | 219 | const unsigned char *, unsigned int); |
219 | extern int hfs_compare_dentry(const struct dentry *parent, | 220 | extern int hfs_compare_dentry(const struct dentry *parent, |
diff --git a/fs/hfs/string.c b/fs/hfs/string.c index aaf90d0d6940..495a976a3cc9 100644 --- a/fs/hfs/string.c +++ b/fs/hfs/string.c | |||
@@ -51,7 +51,8 @@ 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(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 | const unsigned char *name = this->name; | 57 | const unsigned char *name = this->name; |
57 | unsigned int hash, len = this->len; | 58 | unsigned int hash, len = this->len; |
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 7aa96eefe483..a5308f491e3e 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h | |||
@@ -379,7 +379,8 @@ int hfsplus_strcasecmp(const struct hfsplus_unistr *, const struct hfsplus_unist | |||
379 | int hfsplus_strcmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *); | 379 | int hfsplus_strcmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *); |
380 | int hfsplus_uni2asc(struct super_block *, const struct hfsplus_unistr *, char *, int *); | 380 | int hfsplus_uni2asc(struct super_block *, const struct hfsplus_unistr *, char *, int *); |
381 | int hfsplus_asc2uni(struct super_block *, struct hfsplus_unistr *, const char *, int); | 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 | int hfsplus_compare_dentry(const struct dentry *parent, | 384 | int hfsplus_compare_dentry(const struct dentry *parent, |
384 | const struct inode *pinode, | 385 | const struct inode *pinode, |
385 | const struct dentry *dentry, const struct inode *inode, | 386 | const struct dentry *dentry, const struct inode *inode, |
diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c index b178c997efa8..d800aa0f2c80 100644 --- a/fs/hfsplus/unicode.c +++ b/fs/hfsplus/unicode.c | |||
@@ -320,7 +320,8 @@ int hfsplus_asc2uni(struct super_block *sb, struct hfsplus_unistr *ustr, | |||
320 | * Composed unicode characters are decomposed and case-folding is performed | 320 | * Composed unicode characters are decomposed and case-folding is performed |
321 | * if the appropriate bits are (un)set on the superblock. | 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 | struct super_block *sb = dentry->d_sb; | 326 | struct super_block *sb = dentry->d_sb; |
326 | const char *astr; | 327 | const char *astr; |
diff --git a/fs/hpfs/dentry.c b/fs/hpfs/dentry.c index dd9b1e74a734..35526df1fd32 100644 --- a/fs/hpfs/dentry.c +++ b/fs/hpfs/dentry.c | |||
@@ -12,7 +12,8 @@ | |||
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(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 | unsigned long hash; | 18 | unsigned long hash; |
18 | int i; | 19 | int i; |
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 7b0fbc61af81..d204ee4235fd 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
@@ -26,8 +26,10 @@ | |||
26 | 26 | ||
27 | #define BEQUIET | 27 | #define BEQUIET |
28 | 28 | ||
29 | static int isofs_hashi(struct dentry *parent, struct qstr *qstr); | 29 | static int isofs_hashi(const struct dentry *parent, const struct inode *inode, |
30 | static int isofs_hash(struct dentry *parent, struct qstr *qstr); | 30 | struct qstr *qstr); |
31 | static int isofs_hash(const struct dentry *parent, const struct inode *inode, | ||
32 | struct qstr *qstr); | ||
31 | static int isofs_dentry_cmpi(const struct dentry *parent, | 33 | static int isofs_dentry_cmpi(const struct dentry *parent, |
32 | const struct inode *pinode, | 34 | const struct inode *pinode, |
33 | const struct dentry *dentry, const struct inode *inode, | 35 | const struct dentry *dentry, const struct inode *inode, |
@@ -38,8 +40,10 @@ static int isofs_dentry_cmp(const struct dentry *parent, | |||
38 | unsigned int len, const char *str, const struct qstr *name); | 40 | unsigned int len, const char *str, const struct qstr *name); |
39 | 41 | ||
40 | #ifdef CONFIG_JOLIET | 42 | #ifdef CONFIG_JOLIET |
41 | static int isofs_hashi_ms(struct dentry *parent, struct qstr *qstr); | 43 | static int isofs_hashi_ms(const struct dentry *parent, const struct inode *inode, |
42 | static int isofs_hash_ms(struct dentry *parent, struct qstr *qstr); | 44 | struct qstr *qstr); |
45 | static int isofs_hash_ms(const struct dentry *parent, const struct inode *inode, | ||
46 | struct qstr *qstr); | ||
43 | static int isofs_dentry_cmpi_ms(const struct dentry *parent, | 47 | static int isofs_dentry_cmpi_ms(const struct dentry *parent, |
44 | const struct inode *pinode, | 48 | const struct inode *pinode, |
45 | const struct dentry *dentry, const struct inode *inode, | 49 | const struct dentry *dentry, const struct inode *inode, |
@@ -172,7 +176,7 @@ struct iso9660_options{ | |||
172 | * Compute the hash for the isofs name corresponding to the dentry. | 176 | * Compute the hash for the isofs name corresponding to the dentry. |
173 | */ | 177 | */ |
174 | static int | 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 | const char *name; | 181 | const char *name; |
178 | int len; | 182 | int len; |
@@ -193,7 +197,7 @@ isofs_hash_common(struct dentry *dentry, struct qstr *qstr, int ms) | |||
193 | * Compute the hash for the isofs name corresponding to the dentry. | 197 | * Compute the hash for the isofs name corresponding to the dentry. |
194 | */ | 198 | */ |
195 | static int | 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 | const char *name; | 202 | const char *name; |
199 | int len; | 203 | int len; |
@@ -248,13 +252,15 @@ static int isofs_dentry_cmp_common( | |||
248 | } | 252 | } |
249 | 253 | ||
250 | static int | 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 | return isofs_hash_common(dentry, qstr, 0); | 258 | return isofs_hash_common(dentry, qstr, 0); |
254 | } | 259 | } |
255 | 260 | ||
256 | static int | 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 | return isofs_hashi_common(dentry, qstr, 0); | 265 | return isofs_hashi_common(dentry, qstr, 0); |
260 | } | 266 | } |
@@ -277,13 +283,15 @@ isofs_dentry_cmpi(const struct dentry *parent, const struct inode *pinode, | |||
277 | 283 | ||
278 | #ifdef CONFIG_JOLIET | 284 | #ifdef CONFIG_JOLIET |
279 | static int | 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 | return isofs_hash_common(dentry, qstr, 1); | 289 | return isofs_hash_common(dentry, qstr, 1); |
283 | } | 290 | } |
284 | 291 | ||
285 | static int | 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 | return isofs_hashi_common(dentry, qstr, 1); | 296 | return isofs_hashi_common(dentry, qstr, 1); |
289 | } | 297 | } |
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 92129016cd79..57f90dad8919 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c | |||
@@ -1574,7 +1574,8 @@ const struct file_operations jfs_dir_operations = { | |||
1574 | .llseek = generic_file_llseek, | 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 | unsigned long hash; | 1580 | unsigned long hash; |
1580 | int i; | 1581 | int i; |
diff --git a/fs/namei.c b/fs/namei.c index 4ff7ca530533..f3b5ca404659 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -731,7 +731,8 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, | |||
731 | * to use its own hash.. | 731 | * to use its own hash.. |
732 | */ | 732 | */ |
733 | if (nd->path.dentry->d_op && nd->path.dentry->d_op->d_hash) { | 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 | if (err < 0) | 736 | if (err < 0) |
736 | return err; | 737 | return err; |
737 | } | 738 | } |
@@ -1134,7 +1135,7 @@ static struct dentry *__lookup_hash(struct qstr *name, | |||
1134 | * to use its own hash.. | 1135 | * to use its own hash.. |
1135 | */ | 1136 | */ |
1136 | if (base->d_op && base->d_op->d_hash) { | 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 | dentry = ERR_PTR(err); | 1139 | dentry = ERR_PTR(err); |
1139 | if (err < 0) | 1140 | if (err < 0) |
1140 | goto out; | 1141 | goto out; |
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index 3bcc68aed416..bbbf7922f422 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c | |||
@@ -74,7 +74,8 @@ const struct inode_operations ncp_dir_inode_operations = | |||
74 | * Dentry operations routines | 74 | * Dentry operations routines |
75 | */ | 75 | */ |
76 | static int ncp_lookup_validate(struct dentry *, struct nameidata *); | 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 | static int ncp_compare_dentry(const struct dentry *, const struct inode *, | 79 | static int ncp_compare_dentry(const struct dentry *, const struct inode *, |
79 | const struct dentry *, const struct inode *, | 80 | const struct dentry *, const struct inode *, |
80 | unsigned int, const char *, const struct qstr *); | 81 | unsigned int, const char *, const struct qstr *); |
@@ -129,9 +130,10 @@ static inline int ncp_case_sensitive(const struct inode *i) | |||
129 | * is case-sensitive. | 130 | * is case-sensitive. |
130 | */ | 131 | */ |
131 | static int | 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 | struct super_block *sb = dentry->d_sb; | 137 | struct super_block *sb = dentry->d_sb; |
136 | struct nls_table *t; | 138 | struct nls_table *t; |
137 | unsigned long hash; | 139 | unsigned long hash; |
@@ -597,7 +599,7 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir, | |||
597 | qname.hash = full_name_hash(qname.name, qname.len); | 599 | qname.hash = full_name_hash(qname.name, qname.len); |
598 | 600 | ||
599 | if (dentry->d_op && dentry->d_op->d_hash) | 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 | goto end_advance; | 603 | goto end_advance; |
602 | 604 | ||
603 | newdent = d_lookup(dentry, &qname); | 605 | newdent = d_lookup(dentry, &qname); |
diff --git a/fs/sysv/namei.c b/fs/sysv/namei.c index 11e7f7d11cd0..7507aeb4c90e 100644 --- a/fs/sysv/namei.c +++ b/fs/sysv/namei.c | |||
@@ -27,7 +27,8 @@ 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(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 | /* Truncate the name in place, avoids having to define a compare | 33 | /* Truncate the name in place, avoids having to define a compare |
33 | function. */ | 34 | function. */ |
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 75a072bf2a34..1149e706f04d 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h | |||
@@ -133,7 +133,8 @@ enum dentry_d_lock_class | |||
133 | 133 | ||
134 | struct dentry_operations { | 134 | struct dentry_operations { |
135 | int (*d_revalidate)(struct dentry *, struct nameidata *); | 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 | int (*d_compare)(const struct dentry *, const struct inode *, | 138 | int (*d_compare)(const struct dentry *, const struct inode *, |
138 | const struct dentry *, const struct inode *, | 139 | const struct dentry *, const struct inode *, |
139 | unsigned int, const char *, const struct qstr *); | 140 | unsigned int, const char *, const struct qstr *); |