aboutsummaryrefslogtreecommitdiffstats
path: root/fs/isofs
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 /fs/isofs
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>
Diffstat (limited to 'fs/isofs')
-rw-r--r--fs/isofs/inode.c92
-rw-r--r--fs/isofs/namei.c3
2 files changed, 49 insertions, 46 deletions
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/*