aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Piggin <npiggin@kernel.dk>2011-01-07 01:49:27 -0500
committerNick Piggin <npiggin@kernel.dk>2011-01-07 01:50:19 -0500
commit621e155a3591962420eacdd39f6f0aa29ceb221e (patch)
tree387a9fb396f1bf24514b712c294182e36ba51076
parentfb2d5b86aff355a27ebfc132d3c99f4a940cc3fe (diff)
fs: change d_compare for rcu-walk
Change d_compare so it may be called from lock-free RCU lookups. This does put significant restrictions on what may be done from the callback, however there don't seem to have been any problems with in-tree fses. If some strange use case pops up that _really_ cannot cope with the rcu-walk rules, we can just add new rcu-unaware callbacks, which would cause name lookup to drop out of rcu-walk mode. For in-tree filesystems, this is just a mechanical change. Signed-off-by: Nick Piggin <npiggin@kernel.dk>
-rw-r--r--Documentation/filesystems/Locking4
-rw-r--r--Documentation/filesystems/porting7
-rw-r--r--Documentation/filesystems/vfs.txt26
-rw-r--r--drivers/staging/smbfs/dir.c16
-rw-r--r--fs/adfs/dir.c8
-rw-r--r--fs/affs/namei.c46
-rw-r--r--fs/cifs/dir.c12
-rw-r--r--fs/dcache.c4
-rw-r--r--fs/fat/namei_msdos.c14
-rw-r--r--fs/fat/namei_vfat.c33
-rw-r--r--fs/hfs/hfs_fs.h5
-rw-r--r--fs/hfs/string.c14
-rw-r--r--fs/hfsplus/hfsplus_fs.h5
-rw-r--r--fs/hfsplus/unicode.c15
-rw-r--r--fs/hpfs/dentry.c22
-rw-r--r--fs/isofs/inode.c92
-rw-r--r--fs/isofs/namei.c3
-rw-r--r--fs/jfs/namei.c11
-rw-r--r--fs/ncpfs/dir.c25
-rw-r--r--fs/ncpfs/ncplib_kernel.h8
-rw-r--r--fs/proc/proc_sysctl.c13
-rw-r--r--include/linux/dcache.h12
-rw-r--r--include/linux/ncp_fs.h4
23 files changed, 242 insertions, 157 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 33fa3e5d38fd..9a76f8d8bf95 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -11,7 +11,9 @@ be able to use diff(1).
11prototypes: 11prototypes:
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) (struct dentry *, struct qstr *);
14 int (*d_compare) (struct dentry *, struct qstr *, struct qstr *); 14 int (*d_compare)(const struct dentry *, const struct inode *,
15 const struct dentry *, const struct inode *,
16 unsigned int, const char *, const struct qstr *);
15 int (*d_delete)(struct dentry *); 17 int (*d_delete)(struct dentry *);
16 void (*d_release)(struct dentry *); 18 void (*d_release)(struct dentry *);
17 void (*d_iput)(struct dentry *, struct inode *); 19 void (*d_iput)(struct dentry *, struct inode *);
diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting
index 9e71c9ad3108..d44511e20828 100644
--- a/Documentation/filesystems/porting
+++ b/Documentation/filesystems/porting
@@ -326,3 +326,10 @@ to it.
326unreferenced dentries, and is now only called when the dentry refcount goes to 326unreferenced dentries, and is now only called when the dentry refcount goes to
3270. Even on 0 refcount transition, it must be able to tolerate being called 0, 3270. Even on 0 refcount transition, it must be able to tolerate being called 0,
3281, or more times (eg. constant, idempotent). 3281, or more times (eg. constant, idempotent).
329
330---
331[mandatory]
332
333 .d_compare() calling convention and locking rules are significantly
334changed. Read updated documentation in Documentation/filesystems/vfs.txt (and
335look at examples of other filesystems) for guidance.
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index 95c0a93f056c..250681b8c7cc 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -848,7 +848,9 @@ defined:
848struct dentry_operations { 848struct 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)(struct dentry *, struct qstr *);
851 int (*d_compare)(struct dentry *, struct qstr *, struct qstr *); 851 int (*d_compare)(const struct dentry *, const struct inode *,
852 const struct dentry *, const struct inode *,
853 unsigned int, const char *, const struct qstr *);
852 int (*d_delete)(const struct dentry *); 854 int (*d_delete)(const struct dentry *);
853 void (*d_release)(struct dentry *); 855 void (*d_release)(struct dentry *);
854 void (*d_iput)(struct dentry *, struct inode *); 856 void (*d_iput)(struct dentry *, struct inode *);
@@ -860,9 +862,27 @@ struct dentry_operations {
860 dcache. Most filesystems leave this as NULL, because all their 862 dcache. Most filesystems leave this as NULL, because all their
861 dentries in the dcache are valid 863 dentries in the dcache are valid
862 864
863 d_hash: called when the VFS adds a dentry to the hash table 865 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 to be hashed into.
864 868
865 d_compare: called when a dentry should be compared with another 869 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
871 the parent's inode, then the dentry and inode (may be NULL) of the
872 child dentry. len and name string are properties of the dentry to be
873 compared. qstr is the name to compare it with.
874
875 Must be constant and idempotent, and should not take locks if
876 possible, and should not or store into the dentry or inodes.
877 Should not dereference pointers outside the dentry or inodes without
878 lots of care (eg. d_parent, d_inode, d_name should not be used).
879
880 However, our vfsmount is pinned, and RCU held, so the dentries and
881 inodes won't disappear, neither will our sb or filesystem module.
882 ->i_sb and ->d_sb may be used.
883
884 It is a tricky calling convention because it needs to be called under
885 "rcu-walk", ie. without any locks or references on things.
866 886
867 d_delete: called when the last reference to a dentry is dropped and the 887 d_delete: called when the last reference to a dentry is dropped and the
868 dcache is deciding whether or not to cache it. Return 1 to delete 888 dcache is deciding whether or not to cache it. Return 1 to delete
diff --git a/drivers/staging/smbfs/dir.c b/drivers/staging/smbfs/dir.c
index 2270d4822c2f..bd63229f43f2 100644
--- a/drivers/staging/smbfs/dir.c
+++ b/drivers/staging/smbfs/dir.c
@@ -275,7 +275,10 @@ smb_dir_open(struct inode *dir, struct file *file)
275 */ 275 */
276static int smb_lookup_validate(struct dentry *, struct nameidata *); 276static int smb_lookup_validate(struct dentry *, struct nameidata *);
277static int smb_hash_dentry(struct dentry *, struct qstr *); 277static int smb_hash_dentry(struct dentry *, struct qstr *);
278static int smb_compare_dentry(struct dentry *, struct qstr *, struct qstr *); 278static int smb_compare_dentry(const struct dentry *,
279 const struct inode *,
280 const struct dentry *, const struct inode *,
281 unsigned int, const char *, const struct qstr *);
279static int smb_delete_dentry(const struct dentry *); 282static int smb_delete_dentry(const struct dentry *);
280 283
281static const struct dentry_operations smbfs_dentry_operations = 284static const struct dentry_operations smbfs_dentry_operations =
@@ -347,14 +350,17 @@ smb_hash_dentry(struct dentry *dir, struct qstr *this)
347} 350}
348 351
349static int 352static int
350smb_compare_dentry(struct dentry *dir, struct qstr *a, struct qstr *b) 353smb_compare_dentry(const struct dentry *parent,
354 const struct inode *pinode,
355 const struct dentry *dentry, const struct inode *inode,
356 unsigned int len, const char *str, const struct qstr *name)
351{ 357{
352 int i, result = 1; 358 int i, result = 1;
353 359
354 if (a->len != b->len) 360 if (len != name->len)
355 goto out; 361 goto out;
356 for (i=0; i < a->len; i++) { 362 for (i=0; i < len; i++) {
357 if (tolower(a->name[i]) != tolower(b->name[i])) 363 if (tolower(str[i]) != tolower(name->name[i]))
358 goto out; 364 goto out;
359 } 365 }
360 result = 0; 366 result = 0;
diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c
index f4287e4de744..c8ed66162bd4 100644
--- a/fs/adfs/dir.c
+++ b/fs/adfs/dir.c
@@ -237,17 +237,19 @@ adfs_hash(struct dentry *parent, struct qstr *qstr)
237 * requirements of the underlying filesystem. 237 * requirements of the underlying filesystem.
238 */ 238 */
239static int 239static int
240adfs_compare(struct dentry *parent, struct qstr *entry, struct qstr *name) 240adfs_compare(const struct dentry *parent, const struct inode *pinode,
241 const struct dentry *dentry, const struct inode *inode,
242 unsigned int len, const char *str, const struct qstr *name)
241{ 243{
242 int i; 244 int i;
243 245
244 if (entry->len != name->len) 246 if (len != name->len)
245 return 1; 247 return 1;
246 248
247 for (i = 0; i < name->len; i++) { 249 for (i = 0; i < name->len; i++) {
248 char a, b; 250 char a, b;
249 251
250 a = entry->name[i]; 252 a = str[i];
251 b = name->name[i]; 253 b = name->name[i];
252 254
253 if (a >= 'A' && a <= 'Z') 255 if (a >= 'A' && a <= 'Z')
diff --git a/fs/affs/namei.c b/fs/affs/namei.c
index 914d1c0bc07a..547d5deb0d42 100644
--- a/fs/affs/namei.c
+++ b/fs/affs/namei.c
@@ -14,10 +14,16 @@ typedef int (*toupper_t)(int);
14 14
15static int affs_toupper(int ch); 15static int affs_toupper(int ch);
16static int affs_hash_dentry(struct dentry *, struct qstr *); 16static int affs_hash_dentry(struct dentry *, struct qstr *);
17static int affs_compare_dentry(struct dentry *, struct qstr *, struct qstr *); 17static int affs_compare_dentry(const struct dentry *parent,
18 const struct inode *pinode,
19 const struct dentry *dentry, const struct inode *inode,
20 unsigned int len, const char *str, const struct qstr *name);
18static int affs_intl_toupper(int ch); 21static int affs_intl_toupper(int ch);
19static int affs_intl_hash_dentry(struct dentry *, struct qstr *); 22static int affs_intl_hash_dentry(struct dentry *, struct qstr *);
20static int affs_intl_compare_dentry(struct dentry *, struct qstr *, struct qstr *); 23static int affs_intl_compare_dentry(const struct dentry *parent,
24 const struct inode *pinode,
25 const struct dentry *dentry, const struct inode *inode,
26 unsigned int len, const char *str, const struct qstr *name);
21 27
22const struct dentry_operations affs_dentry_operations = { 28const struct dentry_operations affs_dentry_operations = {
23 .d_hash = affs_hash_dentry, 29 .d_hash = affs_hash_dentry,
@@ -88,29 +94,29 @@ affs_intl_hash_dentry(struct dentry *dentry, struct qstr *qstr)
88 return __affs_hash_dentry(dentry, qstr, affs_intl_toupper); 94 return __affs_hash_dentry(dentry, qstr, affs_intl_toupper);
89} 95}
90 96
91static inline int 97static inline int __affs_compare_dentry(unsigned int len,
92__affs_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b, toupper_t toupper) 98 const char *str, const struct qstr *name, toupper_t toupper)
93{ 99{
94 const u8 *aname = a->name; 100 const u8 *aname = str;
95 const u8 *bname = b->name; 101 const u8 *bname = name->name;
96 int len;
97 102
98 /* 'a' is the qstr of an already existing dentry, so the name 103 /*
99 * must be valid. 'b' must be validated first. 104 * 'str' is the name of an already existing dentry, so the name
105 * must be valid. 'name' must be validated first.
100 */ 106 */
101 107
102 if (affs_check_name(b->name,b->len)) 108 if (affs_check_name(name->name, name->len))
103 return 1; 109 return 1;
104 110
105 /* If the names are longer than the allowed 30 chars, 111 /*
112 * If the names are longer than the allowed 30 chars,
106 * the excess is ignored, so their length may differ. 113 * the excess is ignored, so their length may differ.
107 */ 114 */
108 len = a->len;
109 if (len >= 30) { 115 if (len >= 30) {
110 if (b->len < 30) 116 if (name->len < 30)
111 return 1; 117 return 1;
112 len = 30; 118 len = 30;
113 } else if (len != b->len) 119 } else if (len != name->len)
114 return 1; 120 return 1;
115 121
116 for (; len > 0; len--) 122 for (; len > 0; len--)
@@ -121,14 +127,18 @@ __affs_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b, tou
121} 127}
122 128
123static int 129static int
124affs_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b) 130affs_compare_dentry(const struct dentry *parent, const struct inode *pinode,
131 const struct dentry *dentry, const struct inode *inode,
132 unsigned int len, const char *str, const struct qstr *name)
125{ 133{
126 return __affs_compare_dentry(dentry, a, b, affs_toupper); 134 return __affs_compare_dentry(len, str, name, affs_toupper);
127} 135}
128static int 136static int
129affs_intl_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b) 137affs_intl_compare_dentry(const struct dentry *parent,const struct inode *pinode,
138 const struct dentry *dentry, const struct inode *inode,
139 unsigned int len, const char *str, const struct qstr *name)
130{ 140{
131 return __affs_compare_dentry(dentry, a, b, affs_intl_toupper); 141 return __affs_compare_dentry(len, str, name, affs_intl_toupper);
132} 142}
133 143
134/* 144/*
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 521d841b1fd1..c60133f0d8e4 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -715,13 +715,15 @@ static int cifs_ci_hash(struct dentry *dentry, struct qstr *q)
715 return 0; 715 return 0;
716} 716}
717 717
718static int cifs_ci_compare(struct dentry *dentry, struct qstr *a, 718static int cifs_ci_compare(const struct dentry *parent,
719 struct qstr *b) 719 const struct inode *pinode,
720 const struct dentry *dentry, const struct inode *inode,
721 unsigned int len, const char *str, const struct qstr *name)
720{ 722{
721 struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls; 723 struct nls_table *codepage = CIFS_SB(pinode->i_sb)->local_nls;
722 724
723 if ((a->len == b->len) && 725 if ((name->len == len) &&
724 (nls_strnicmp(codepage, a->name, b->name, a->len) == 0)) 726 (nls_strnicmp(codepage, name->name, str, len) == 0))
725 return 0; 727 return 0;
726 return 1; 728 return 1;
727} 729}
diff --git a/fs/dcache.c b/fs/dcache.c
index 814e5f491e9c..7075555fbb04 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1437,7 +1437,9 @@ struct dentry * __d_lookup(struct dentry * parent, struct qstr * name)
1437 */ 1437 */
1438 qstr = &dentry->d_name; 1438 qstr = &dentry->d_name;
1439 if (parent->d_op && parent->d_op->d_compare) { 1439 if (parent->d_op && parent->d_op->d_compare) {
1440 if (parent->d_op->d_compare(parent, qstr, name)) 1440 if (parent->d_op->d_compare(parent, parent->d_inode,
1441 dentry, dentry->d_inode,
1442 qstr->len, qstr->name, name))
1441 goto next; 1443 goto next;
1442 } else { 1444 } else {
1443 if (qstr->len != len) 1445 if (qstr->len != len)
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c
index 3345aabd1dd7..99d3c7ac973c 100644
--- a/fs/fat/namei_msdos.c
+++ b/fs/fat/namei_msdos.c
@@ -164,16 +164,18 @@ static int msdos_hash(struct dentry *dentry, struct qstr *qstr)
164 * Compare two msdos names. If either of the names are invalid, 164 * Compare two msdos names. If either of the names are invalid,
165 * we fall back to doing the standard name comparison. 165 * we fall back to doing the standard name comparison.
166 */ 166 */
167static int msdos_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b) 167static int msdos_cmp(const struct dentry *parent, const struct inode *pinode,
168 const struct dentry *dentry, const struct inode *inode,
169 unsigned int len, const char *str, const struct qstr *name)
168{ 170{
169 struct fat_mount_options *options = &MSDOS_SB(dentry->d_sb)->options; 171 struct fat_mount_options *options = &MSDOS_SB(parent->d_sb)->options;
170 unsigned char a_msdos_name[MSDOS_NAME], b_msdos_name[MSDOS_NAME]; 172 unsigned char a_msdos_name[MSDOS_NAME], b_msdos_name[MSDOS_NAME];
171 int error; 173 int error;
172 174
173 error = msdos_format_name(a->name, a->len, a_msdos_name, options); 175 error = msdos_format_name(name->name, name->len, a_msdos_name, options);
174 if (error) 176 if (error)
175 goto old_compare; 177 goto old_compare;
176 error = msdos_format_name(b->name, b->len, b_msdos_name, options); 178 error = msdos_format_name(str, len, b_msdos_name, options);
177 if (error) 179 if (error)
178 goto old_compare; 180 goto old_compare;
179 error = memcmp(a_msdos_name, b_msdos_name, MSDOS_NAME); 181 error = memcmp(a_msdos_name, b_msdos_name, MSDOS_NAME);
@@ -182,8 +184,8 @@ out:
182 184
183old_compare: 185old_compare:
184 error = 1; 186 error = 1;
185 if (a->len == b->len) 187 if (name->len == len)
186 error = memcmp(a->name, b->name, a->len); 188 error = memcmp(name->name, str, len);
187 goto out; 189 goto out;
188} 190}
189 191
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c
index b936703b8924..95e00ab84c3f 100644
--- a/fs/fat/namei_vfat.c
+++ b/fs/fat/namei_vfat.c
@@ -85,15 +85,18 @@ static int vfat_revalidate_ci(struct dentry *dentry, struct nameidata *nd)
85} 85}
86 86
87/* returns the length of a struct qstr, ignoring trailing dots */ 87/* returns the length of a struct qstr, ignoring trailing dots */
88static unsigned int vfat_striptail_len(struct qstr *qstr) 88static unsigned int __vfat_striptail_len(unsigned int len, const char *name)
89{ 89{
90 unsigned int len = qstr->len; 90 while (len && name[len - 1] == '.')
91
92 while (len && qstr->name[len - 1] == '.')
93 len--; 91 len--;
94 return len; 92 return len;
95} 93}
96 94
95static unsigned int vfat_striptail_len(const struct qstr *qstr)
96{
97 return __vfat_striptail_len(qstr->len, qstr->name);
98}
99
97/* 100/*
98 * Compute the hash for the vfat name corresponding to the dentry. 101 * Compute the hash for the vfat name corresponding to the dentry.
99 * Note: if the name is invalid, we leave the hash code unchanged so 102 * Note: if the name is invalid, we leave the hash code unchanged so
@@ -133,16 +136,18 @@ static int vfat_hashi(struct dentry *dentry, struct qstr *qstr)
133/* 136/*
134 * Case insensitive compare of two vfat names. 137 * Case insensitive compare of two vfat names.
135 */ 138 */
136static int vfat_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b) 139static int vfat_cmpi(const struct dentry *parent, const struct inode *pinode,
140 const struct dentry *dentry, const struct inode *inode,
141 unsigned int len, const char *str, const struct qstr *name)
137{ 142{
138 struct nls_table *t = MSDOS_SB(dentry->d_inode->i_sb)->nls_io; 143 struct nls_table *t = MSDOS_SB(parent->d_sb)->nls_io;
139 unsigned int alen, blen; 144 unsigned int alen, blen;
140 145
141 /* A filename cannot end in '.' or we treat it like it has none */ 146 /* A filename cannot end in '.' or we treat it like it has none */
142 alen = vfat_striptail_len(a); 147 alen = vfat_striptail_len(name);
143 blen = vfat_striptail_len(b); 148 blen = __vfat_striptail_len(len, str);
144 if (alen == blen) { 149 if (alen == blen) {
145 if (nls_strnicmp(t, a->name, b->name, alen) == 0) 150 if (nls_strnicmp(t, name->name, str, alen) == 0)
146 return 0; 151 return 0;
147 } 152 }
148 return 1; 153 return 1;
@@ -151,15 +156,17 @@ static int vfat_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b)
151/* 156/*
152 * Case sensitive compare of two vfat names. 157 * Case sensitive compare of two vfat names.
153 */ 158 */
154static int vfat_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b) 159static int vfat_cmp(const struct dentry *parent, const struct inode *pinode,
160 const struct dentry *dentry, const struct inode *inode,
161 unsigned int len, const char *str, const struct qstr *name)
155{ 162{
156 unsigned int alen, blen; 163 unsigned int alen, blen;
157 164
158 /* A filename cannot end in '.' or we treat it like it has none */ 165 /* A filename cannot end in '.' or we treat it like it has none */
159 alen = vfat_striptail_len(a); 166 alen = vfat_striptail_len(name);
160 blen = vfat_striptail_len(b); 167 blen = __vfat_striptail_len(len, str);
161 if (alen == blen) { 168 if (alen == blen) {
162 if (strncmp(a->name, b->name, alen) == 0) 169 if (strncmp(name->name, str, alen) == 0)
163 return 0; 170 return 0;
164 } 171 }
165 return 1; 172 return 1;
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h
index c8cffb81e849..8cd876f0e961 100644
--- a/fs/hfs/hfs_fs.h
+++ b/fs/hfs/hfs_fs.h
@@ -216,7 +216,10 @@ extern const struct dentry_operations hfs_dentry_operations;
216extern int hfs_hash_dentry(struct dentry *, struct qstr *); 216extern int hfs_hash_dentry(struct dentry *, struct qstr *);
217extern int hfs_strcmp(const unsigned char *, unsigned int, 217extern int hfs_strcmp(const unsigned char *, unsigned int,
218 const unsigned char *, unsigned int); 218 const unsigned char *, unsigned int);
219extern int hfs_compare_dentry(struct dentry *, struct qstr *, struct qstr *); 219extern int hfs_compare_dentry(const struct dentry *parent,
220 const struct inode *pinode,
221 const struct dentry *dentry, const struct inode *inode,
222 unsigned int len, const char *str, const struct qstr *name);
220 223
221/* trans.c */ 224/* trans.c */
222extern void hfs_asc2mac(struct super_block *, struct hfs_name *, struct qstr *); 225extern void hfs_asc2mac(struct super_block *, struct hfs_name *, struct qstr *);
diff --git a/fs/hfs/string.c b/fs/hfs/string.c
index 927a5af79428..aaf90d0d6940 100644
--- a/fs/hfs/string.c
+++ b/fs/hfs/string.c
@@ -92,21 +92,21 @@ int hfs_strcmp(const unsigned char *s1, unsigned int len1,
92 * Test for equality of two strings in the HFS filename character ordering. 92 * Test for equality of two strings in the HFS filename character ordering.
93 * return 1 on failure and 0 on success 93 * return 1 on failure and 0 on success
94 */ 94 */
95int hfs_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *s2) 95int hfs_compare_dentry(const struct dentry *parent, const struct inode *pinode,
96 const struct dentry *dentry, const struct inode *inode,
97 unsigned int len, const char *str, const struct qstr *name)
96{ 98{
97 const unsigned char *n1, *n2; 99 const unsigned char *n1, *n2;
98 int len;
99 100
100 len = s1->len;
101 if (len >= HFS_NAMELEN) { 101 if (len >= HFS_NAMELEN) {
102 if (s2->len < HFS_NAMELEN) 102 if (name->len < HFS_NAMELEN)
103 return 1; 103 return 1;
104 len = HFS_NAMELEN; 104 len = HFS_NAMELEN;
105 } else if (len != s2->len) 105 } else if (len != name->len)
106 return 1; 106 return 1;
107 107
108 n1 = s1->name; 108 n1 = str;
109 n2 = s2->name; 109 n2 = name->name;
110 while (len--) { 110 while (len--) {
111 if (caseorder[*n1++] != caseorder[*n2++]) 111 if (caseorder[*n1++] != caseorder[*n2++])
112 return 1; 112 return 1;
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index cb3653efb57a..7aa96eefe483 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -380,7 +380,10 @@ int hfsplus_strcmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *)
380int hfsplus_uni2asc(struct super_block *, const struct hfsplus_unistr *, char *, int *); 380int hfsplus_uni2asc(struct super_block *, const struct hfsplus_unistr *, char *, int *);
381int hfsplus_asc2uni(struct super_block *, struct hfsplus_unistr *, const char *, int); 381int hfsplus_asc2uni(struct super_block *, struct hfsplus_unistr *, const char *, int);
382int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str); 382int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str);
383int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *s2); 383int hfsplus_compare_dentry(const struct dentry *parent,
384 const struct inode *pinode,
385 const struct dentry *dentry, const struct inode *inode,
386 unsigned int len, const char *str, const struct qstr *name);
384 387
385/* wrapper.c */ 388/* wrapper.c */
386int hfsplus_read_wrapper(struct super_block *); 389int hfsplus_read_wrapper(struct super_block *);
diff --git a/fs/hfsplus/unicode.c b/fs/hfsplus/unicode.c
index b66d67de882c..b178c997efa8 100644
--- a/fs/hfsplus/unicode.c
+++ b/fs/hfsplus/unicode.c
@@ -363,9 +363,12 @@ int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str)
363 * Composed unicode characters are decomposed and case-folding is performed 363 * Composed unicode characters are decomposed and case-folding is performed
364 * if the appropriate bits are (un)set on the superblock. 364 * if the appropriate bits are (un)set on the superblock.
365 */ 365 */
366int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *s2) 366int hfsplus_compare_dentry(const struct dentry *parent,
367 const struct inode *pinode,
368 const struct dentry *dentry, const struct inode *inode,
369 unsigned int len, const char *str, const struct qstr *name)
367{ 370{
368 struct super_block *sb = dentry->d_sb; 371 struct super_block *sb = parent->d_sb;
369 int casefold, decompose, size; 372 int casefold, decompose, size;
370 int dsize1, dsize2, len1, len2; 373 int dsize1, dsize2, len1, len2;
371 const u16 *dstr1, *dstr2; 374 const u16 *dstr1, *dstr2;
@@ -375,10 +378,10 @@ int hfsplus_compare_dentry(struct dentry *dentry, struct qstr *s1, struct qstr *
375 378
376 casefold = test_bit(HFSPLUS_SB_CASEFOLD, &HFSPLUS_SB(sb)->flags); 379 casefold = test_bit(HFSPLUS_SB_CASEFOLD, &HFSPLUS_SB(sb)->flags);
377 decompose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags); 380 decompose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags);
378 astr1 = s1->name; 381 astr1 = str;
379 len1 = s1->len; 382 len1 = len;
380 astr2 = s2->name; 383 astr2 = name->name;
381 len2 = s2->len; 384 len2 = name->len;
382 dsize1 = dsize2 = 0; 385 dsize1 = dsize2 = 0;
383 dstr1 = dstr2 = NULL; 386 dstr1 = dstr2 = NULL;
384 387
diff --git a/fs/hpfs/dentry.c b/fs/hpfs/dentry.c
index 67d9d36b3d5f..dd9b1e74a734 100644
--- a/fs/hpfs/dentry.c
+++ b/fs/hpfs/dentry.c
@@ -34,19 +34,25 @@ static int hpfs_hash_dentry(struct dentry *dentry, struct qstr *qstr)
34 return 0; 34 return 0;
35} 35}
36 36
37static int hpfs_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b) 37static int hpfs_compare_dentry(const struct dentry *parent,
38 const struct inode *pinode,
39 const struct dentry *dentry, const struct inode *inode,
40 unsigned int len, const char *str, const struct qstr *name)
38{ 41{
39 unsigned al=a->len; 42 unsigned al = len;
40 unsigned bl=b->len; 43 unsigned bl = name->len;
41 hpfs_adjust_length(a->name, &al); 44
45 hpfs_adjust_length(str, &al);
42 /*hpfs_adjust_length(b->name, &bl);*/ 46 /*hpfs_adjust_length(b->name, &bl);*/
43 /* 'a' is the qstr of an already existing dentry, so the name 47
44 * must be valid. 'b' must be validated first. 48 /*
49 * 'str' is the nane of an already existing dentry, so the name
50 * must be valid. 'name' must be validated first.
45 */ 51 */
46 52
47 if (hpfs_chk_name(b->name, &bl)) 53 if (hpfs_chk_name(name->name, &bl))
48 return 1; 54 return 1;
49 if (hpfs_compare_names(dentry->d_sb, a->name, al, b->name, bl, 0)) 55 if (hpfs_compare_names(parent->d_sb, str, al, name->name, bl, 0))
50 return 1; 56 return 1;
51 return 0; 57 return 0;
52} 58}
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index bfdeb82a53be..7b0fbc61af81 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -28,14 +28,26 @@
28 28
29static int isofs_hashi(struct dentry *parent, struct qstr *qstr); 29static int isofs_hashi(struct dentry *parent, struct qstr *qstr);
30static int isofs_hash(struct dentry *parent, struct qstr *qstr); 30static int isofs_hash(struct dentry *parent, struct qstr *qstr);
31static int isofs_dentry_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b); 31static int isofs_dentry_cmpi(const struct dentry *parent,
32static int isofs_dentry_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b); 32 const struct inode *pinode,
33 const struct dentry *dentry, const struct inode *inode,
34 unsigned int len, const char *str, const struct qstr *name);
35static int isofs_dentry_cmp(const struct dentry *parent,
36 const struct inode *pinode,
37 const struct dentry *dentry, const struct inode *inode,
38 unsigned int len, const char *str, const struct qstr *name);
33 39
34#ifdef CONFIG_JOLIET 40#ifdef CONFIG_JOLIET
35static int isofs_hashi_ms(struct dentry *parent, struct qstr *qstr); 41static int isofs_hashi_ms(struct dentry *parent, struct qstr *qstr);
36static int isofs_hash_ms(struct dentry *parent, struct qstr *qstr); 42static int isofs_hash_ms(struct dentry *parent, struct qstr *qstr);
37static int isofs_dentry_cmpi_ms(struct dentry *dentry, struct qstr *a, struct qstr *b); 43static int isofs_dentry_cmpi_ms(const struct dentry *parent,
38static int isofs_dentry_cmp_ms(struct dentry *dentry, struct qstr *a, struct qstr *b); 44 const struct inode *pinode,
45 const struct dentry *dentry, const struct inode *inode,
46 unsigned int len, const char *str, const struct qstr *name);
47static int isofs_dentry_cmp_ms(const struct dentry *parent,
48 const struct inode *pinode,
49 const struct dentry *dentry, const struct inode *inode,
50 unsigned int len, const char *str, const struct qstr *name);
39#endif 51#endif
40 52
41static void isofs_put_super(struct super_block *sb) 53static void isofs_put_super(struct super_block *sb)
@@ -206,49 +218,31 @@ isofs_hashi_common(struct dentry *dentry, struct qstr *qstr, int ms)
206} 218}
207 219
208/* 220/*
209 * Case insensitive compare of two isofs names. 221 * Compare of two isofs names.
210 */ 222 */
211static int isofs_dentry_cmpi_common(struct dentry *dentry, struct qstr *a, 223static int isofs_dentry_cmp_common(
212 struct qstr *b, int ms) 224 unsigned int len, const char *str,
225 const struct qstr *name, int ms, int ci)
213{ 226{
214 int alen, blen; 227 int alen, blen;
215 228
216 /* A filename cannot end in '.' or we treat it like it has none */ 229 /* A filename cannot end in '.' or we treat it like it has none */
217 alen = a->len; 230 alen = name->len;
218 blen = b->len; 231 blen = len;
219 if (ms) { 232 if (ms) {
220 while (alen && a->name[alen-1] == '.') 233 while (alen && name->name[alen-1] == '.')
221 alen--; 234 alen--;
222 while (blen && b->name[blen-1] == '.') 235 while (blen && str[blen-1] == '.')
223 blen--; 236 blen--;
224 } 237 }
225 if (alen == blen) { 238 if (alen == blen) {
226 if (strnicmp(a->name, b->name, alen) == 0) 239 if (ci) {
227 return 0; 240 if (strnicmp(name->name, str, alen) == 0)
228 } 241 return 0;
229 return 1; 242 } else {
230} 243 if (strncmp(name->name, str, alen) == 0)
231 244 return 0;
232/* 245 }
233 * Case sensitive compare of two isofs names.
234 */
235static int isofs_dentry_cmp_common(struct dentry *dentry, struct qstr *a,
236 struct qstr *b, int ms)
237{
238 int alen, blen;
239
240 /* A filename cannot end in '.' or we treat it like it has none */
241 alen = a->len;
242 blen = b->len;
243 if (ms) {
244 while (alen && a->name[alen-1] == '.')
245 alen--;
246 while (blen && b->name[blen-1] == '.')
247 blen--;
248 }
249 if (alen == blen) {
250 if (strncmp(a->name, b->name, alen) == 0)
251 return 0;
252 } 246 }
253 return 1; 247 return 1;
254} 248}
@@ -266,15 +260,19 @@ isofs_hashi(struct dentry *dentry, struct qstr *qstr)
266} 260}
267 261
268static int 262static int
269isofs_dentry_cmp(struct dentry *dentry,struct qstr *a,struct qstr *b) 263isofs_dentry_cmp(const struct dentry *parent, const struct inode *pinode,
264 const struct dentry *dentry, const struct inode *inode,
265 unsigned int len, const char *str, const struct qstr *name)
270{ 266{
271 return isofs_dentry_cmp_common(dentry, a, b, 0); 267 return isofs_dentry_cmp_common(len, str, name, 0, 0);
272} 268}
273 269
274static int 270static int
275isofs_dentry_cmpi(struct dentry *dentry,struct qstr *a,struct qstr *b) 271isofs_dentry_cmpi(const struct dentry *parent, const struct inode *pinode,
272 const struct dentry *dentry, const struct inode *inode,
273 unsigned int len, const char *str, const struct qstr *name)
276{ 274{
277 return isofs_dentry_cmpi_common(dentry, a, b, 0); 275 return isofs_dentry_cmp_common(len, str, name, 0, 1);
278} 276}
279 277
280#ifdef CONFIG_JOLIET 278#ifdef CONFIG_JOLIET
@@ -291,15 +289,19 @@ isofs_hashi_ms(struct dentry *dentry, struct qstr *qstr)
291} 289}
292 290
293static int 291static int
294isofs_dentry_cmp_ms(struct dentry *dentry,struct qstr *a,struct qstr *b) 292isofs_dentry_cmp_ms(const struct dentry *parent, const struct inode *pinode,
293 const struct dentry *dentry, const struct inode *inode,
294 unsigned int len, const char *str, const struct qstr *name)
295{ 295{
296 return isofs_dentry_cmp_common(dentry, a, b, 1); 296 return isofs_dentry_cmp_common(len, str, name, 1, 0);
297} 297}
298 298
299static int 299static int
300isofs_dentry_cmpi_ms(struct dentry *dentry,struct qstr *a,struct qstr *b) 300isofs_dentry_cmpi_ms(const struct dentry *parent, const struct inode *pinode,
301 const struct dentry *dentry, const struct inode *inode,
302 unsigned int len, const char *str, const struct qstr *name)
301{ 303{
302 return isofs_dentry_cmpi_common(dentry, a, b, 1); 304 return isofs_dentry_cmp_common(len, str, name, 1, 1);
303} 305}
304#endif 306#endif
305 307
diff --git a/fs/isofs/namei.c b/fs/isofs/namei.c
index 0d23abfd4280..715f7d318046 100644
--- a/fs/isofs/namei.c
+++ b/fs/isofs/namei.c
@@ -37,7 +37,8 @@ isofs_cmp(struct dentry *dentry, const char *compare, int dlen)
37 37
38 qstr.name = compare; 38 qstr.name = compare;
39 qstr.len = dlen; 39 qstr.len = dlen;
40 return dentry->d_op->d_compare(dentry, &dentry->d_name, &qstr); 40 return dentry->d_op->d_compare(NULL, NULL, NULL, NULL,
41 dentry->d_name.len, dentry->d_name.name, &qstr);
41} 42}
42 43
43/* 44/*
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 2da1546161fa..92129016cd79 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -1587,14 +1587,17 @@ static int jfs_ci_hash(struct dentry *dir, struct qstr *this)
1587 return 0; 1587 return 0;
1588} 1588}
1589 1589
1590static int jfs_ci_compare(struct dentry *dir, struct qstr *a, struct qstr *b) 1590static int jfs_ci_compare(const struct dentry *parent,
1591 const struct inode *pinode,
1592 const struct dentry *dentry, const struct inode *inode,
1593 unsigned int len, const char *str, const struct qstr *name)
1591{ 1594{
1592 int i, result = 1; 1595 int i, result = 1;
1593 1596
1594 if (a->len != b->len) 1597 if (len != name->len)
1595 goto out; 1598 goto out;
1596 for (i=0; i < a->len; i++) { 1599 for (i=0; i < len; i++) {
1597 if (tolower(a->name[i]) != tolower(b->name[i])) 1600 if (tolower(str[i]) != tolower(name->name[i]))
1598 goto out; 1601 goto out;
1599 } 1602 }
1600 result = 0; 1603 result = 0;
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index e80ea4e37c48..3bcc68aed416 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -75,7 +75,9 @@ const struct inode_operations ncp_dir_inode_operations =
75 */ 75 */
76static int ncp_lookup_validate(struct dentry *, struct nameidata *); 76static int ncp_lookup_validate(struct dentry *, struct nameidata *);
77static int ncp_hash_dentry(struct dentry *, struct qstr *); 77static int ncp_hash_dentry(struct dentry *, struct qstr *);
78static int ncp_compare_dentry (struct dentry *, struct qstr *, struct qstr *); 78static int ncp_compare_dentry(const struct dentry *, const struct inode *,
79 const struct dentry *, const struct inode *,
80 unsigned int, const char *, const struct qstr *);
79static int ncp_delete_dentry(const struct dentry *); 81static int ncp_delete_dentry(const struct dentry *);
80 82
81static const struct dentry_operations ncp_dentry_operations = 83static const struct dentry_operations ncp_dentry_operations =
@@ -113,10 +115,10 @@ static inline int ncp_preserve_entry_case(struct inode *i, __u32 nscreator)
113 115
114#define ncp_preserve_case(i) (ncp_namespace(i) != NW_NS_DOS) 116#define ncp_preserve_case(i) (ncp_namespace(i) != NW_NS_DOS)
115 117
116static inline int ncp_case_sensitive(struct dentry *dentry) 118static inline int ncp_case_sensitive(const struct inode *i)
117{ 119{
118#ifdef CONFIG_NCPFS_NFS_NS 120#ifdef CONFIG_NCPFS_NFS_NS
119 return ncp_namespace(dentry->d_inode) == NW_NS_NFS; 121 return ncp_namespace(i) == NW_NS_NFS;
120#else 122#else
121 return 0; 123 return 0;
122#endif /* CONFIG_NCPFS_NFS_NS */ 124#endif /* CONFIG_NCPFS_NFS_NS */
@@ -129,12 +131,13 @@ static inline int ncp_case_sensitive(struct dentry *dentry)
129static int 131static int
130ncp_hash_dentry(struct dentry *dentry, struct qstr *this) 132ncp_hash_dentry(struct dentry *dentry, struct qstr *this)
131{ 133{
132 if (!ncp_case_sensitive(dentry)) { 134 if (!ncp_case_sensitive(dentry->d_inode)) {
135 struct super_block *sb = dentry->d_sb;
133 struct nls_table *t; 136 struct nls_table *t;
134 unsigned long hash; 137 unsigned long hash;
135 int i; 138 int i;
136 139
137 t = NCP_IO_TABLE(dentry); 140 t = NCP_IO_TABLE(sb);
138 hash = init_name_hash(); 141 hash = init_name_hash();
139 for (i=0; i<this->len ; i++) 142 for (i=0; i<this->len ; i++)
140 hash = partial_name_hash(ncp_tolower(t, this->name[i]), 143 hash = partial_name_hash(ncp_tolower(t, this->name[i]),
@@ -145,15 +148,17 @@ ncp_hash_dentry(struct dentry *dentry, struct qstr *this)
145} 148}
146 149
147static int 150static int
148ncp_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b) 151ncp_compare_dentry(const struct dentry *parent, const struct inode *pinode,
152 const struct dentry *dentry, const struct inode *inode,
153 unsigned int len, const char *str, const struct qstr *name)
149{ 154{
150 if (a->len != b->len) 155 if (len != name->len)
151 return 1; 156 return 1;
152 157
153 if (ncp_case_sensitive(dentry)) 158 if (ncp_case_sensitive(pinode))
154 return strncmp(a->name, b->name, a->len); 159 return strncmp(str, name->name, len);
155 160
156 return ncp_strnicmp(NCP_IO_TABLE(dentry), a->name, b->name, a->len); 161 return ncp_strnicmp(NCP_IO_TABLE(pinode->i_sb), str, name->name, len);
157} 162}
158 163
159/* 164/*
diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h
index 3c57eca634ce..244d1b73fda7 100644
--- a/fs/ncpfs/ncplib_kernel.h
+++ b/fs/ncpfs/ncplib_kernel.h
@@ -135,7 +135,7 @@ int ncp__vol2io(struct ncp_server *, unsigned char *, unsigned int *,
135 const unsigned char *, unsigned int, int); 135 const unsigned char *, unsigned int, int);
136 136
137#define NCP_ESC ':' 137#define NCP_ESC ':'
138#define NCP_IO_TABLE(dentry) (NCP_SERVER((dentry)->d_inode)->nls_io) 138#define NCP_IO_TABLE(sb) (NCP_SBP(sb)->nls_io)
139#define ncp_tolower(t, c) nls_tolower(t, c) 139#define ncp_tolower(t, c) nls_tolower(t, c)
140#define ncp_toupper(t, c) nls_toupper(t, c) 140#define ncp_toupper(t, c) nls_toupper(t, c)
141#define ncp_strnicmp(t, s1, s2, len) \ 141#define ncp_strnicmp(t, s1, s2, len) \
@@ -150,15 +150,15 @@ int ncp__io2vol(unsigned char *, unsigned int *,
150int ncp__vol2io(unsigned char *, unsigned int *, 150int ncp__vol2io(unsigned char *, unsigned int *,
151 const unsigned char *, unsigned int, int); 151 const unsigned char *, unsigned int, int);
152 152
153#define NCP_IO_TABLE(dentry) NULL 153#define NCP_IO_TABLE(sb) NULL
154#define ncp_tolower(t, c) tolower(c) 154#define ncp_tolower(t, c) tolower(c)
155#define ncp_toupper(t, c) toupper(c) 155#define ncp_toupper(t, c) toupper(c)
156#define ncp_io2vol(S,m,i,n,k,U) ncp__io2vol(m,i,n,k,U) 156#define ncp_io2vol(S,m,i,n,k,U) ncp__io2vol(m,i,n,k,U)
157#define ncp_vol2io(S,m,i,n,k,U) ncp__vol2io(m,i,n,k,U) 157#define ncp_vol2io(S,m,i,n,k,U) ncp__vol2io(m,i,n,k,U)
158 158
159 159
160static inline int ncp_strnicmp(struct nls_table *t, const unsigned char *s1, 160static inline int ncp_strnicmp(const struct nls_table *t,
161 const unsigned char *s2, int len) 161 const unsigned char *s1, const unsigned char *s2, int len)
162{ 162{
163 while (len--) { 163 while (len--) {
164 if (tolower(*s1++) != tolower(*s2++)) 164 if (tolower(*s1++) != tolower(*s2++))
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index a256d770ea18..ae4b0fd9033f 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -397,15 +397,16 @@ static int proc_sys_delete(const struct dentry *dentry)
397 return !!PROC_I(dentry->d_inode)->sysctl->unregistering; 397 return !!PROC_I(dentry->d_inode)->sysctl->unregistering;
398} 398}
399 399
400static int proc_sys_compare(struct dentry *dir, struct qstr *qstr, 400static int proc_sys_compare(const struct dentry *parent,
401 struct qstr *name) 401 const struct inode *pinode,
402 const struct dentry *dentry, const struct inode *inode,
403 unsigned int len, const char *str, const struct qstr *name)
402{ 404{
403 struct dentry *dentry = container_of(qstr, struct dentry, d_name); 405 if (name->len != len)
404 if (qstr->len != name->len)
405 return 1; 406 return 1;
406 if (memcmp(qstr->name, name->name, name->len)) 407 if (memcmp(name->name, str, len))
407 return 1; 408 return 1;
408 return !sysctl_is_seen(PROC_I(dentry->d_inode)->sysctl); 409 return !sysctl_is_seen(PROC_I(inode)->sysctl);
409} 410}
410 411
411static const struct dentry_operations proc_sys_dentry_operations = { 412static const struct dentry_operations proc_sys_dentry_operations = {
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 6cdf4995c90a..75a072bf2a34 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -134,7 +134,9 @@ enum dentry_d_lock_class
134struct dentry_operations { 134struct 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)(struct dentry *, struct qstr *);
137 int (*d_compare)(struct dentry *, struct qstr *, struct qstr *); 137 int (*d_compare)(const struct dentry *, const struct inode *,
138 const struct dentry *, const struct inode *,
139 unsigned int, const char *, const struct qstr *);
138 int (*d_delete)(const struct dentry *); 140 int (*d_delete)(const struct dentry *);
139 void (*d_release)(struct dentry *); 141 void (*d_release)(struct dentry *);
140 void (*d_iput)(struct dentry *, struct inode *); 142 void (*d_iput)(struct dentry *, struct inode *);
@@ -145,12 +147,8 @@ struct dentry_operations {
145 * Locking rules for dentry_operations callbacks are to be found in 147 * Locking rules for dentry_operations callbacks are to be found in
146 * Documentation/filesystems/Locking. Keep it updated! 148 * Documentation/filesystems/Locking. Keep it updated!
147 * 149 *
148 * the dentry parameter passed to d_hash and d_compare is the parent 150 * FUrther descriptions are found in Documentation/filesystems/vfs.txt.
149 * directory of the entries to be compared. It is used in case these 151 * Keep it updated too!
150 * functions need any directory specific information for determining
151 * equivalency classes. Using the dentry itself might not work, as it
152 * might be a negative dentry which has no information associated with
153 * it.
154 */ 152 */
155 153
156/* d_flags entries */ 154/* d_flags entries */
diff --git a/include/linux/ncp_fs.h b/include/linux/ncp_fs.h
index ef663061d5ac..1c27f201c856 100644
--- a/include/linux/ncp_fs.h
+++ b/include/linux/ncp_fs.h
@@ -184,13 +184,13 @@ struct ncp_entry_info {
184 __u8 file_handle[6]; 184 __u8 file_handle[6];
185}; 185};
186 186
187static inline struct ncp_server *NCP_SBP(struct super_block *sb) 187static inline struct ncp_server *NCP_SBP(const struct super_block *sb)
188{ 188{
189 return sb->s_fs_info; 189 return sb->s_fs_info;
190} 190}
191 191
192#define NCP_SERVER(inode) NCP_SBP((inode)->i_sb) 192#define NCP_SERVER(inode) NCP_SBP((inode)->i_sb)
193static inline struct ncp_inode_info *NCP_FINFO(struct inode *inode) 193static inline struct ncp_inode_info *NCP_FINFO(const struct inode *inode)
194{ 194{
195 return container_of(inode, struct ncp_inode_info, vfs_inode); 195 return container_of(inode, struct ncp_inode_info, vfs_inode);
196} 196}