diff options
author | Nick Piggin <npiggin@kernel.dk> | 2011-01-07 01:49:27 -0500 |
---|---|---|
committer | Nick Piggin <npiggin@kernel.dk> | 2011-01-07 01:50:19 -0500 |
commit | 621e155a3591962420eacdd39f6f0aa29ceb221e (patch) | |
tree | 387a9fb396f1bf24514b712c294182e36ba51076 /fs/isofs | |
parent | fb2d5b86aff355a27ebfc132d3c99f4a940cc3fe (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.c | 92 | ||||
-rw-r--r-- | fs/isofs/namei.c | 3 |
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 | ||
29 | static int isofs_hashi(struct dentry *parent, struct qstr *qstr); | 29 | static int isofs_hashi(struct dentry *parent, struct qstr *qstr); |
30 | static int isofs_hash(struct dentry *parent, struct qstr *qstr); | 30 | static int isofs_hash(struct dentry *parent, struct qstr *qstr); |
31 | static int isofs_dentry_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b); | 31 | static int isofs_dentry_cmpi(const struct dentry *parent, |
32 | static 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); | ||
35 | static 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 |
35 | static int isofs_hashi_ms(struct dentry *parent, struct qstr *qstr); | 41 | static int isofs_hashi_ms(struct dentry *parent, struct qstr *qstr); |
36 | static int isofs_hash_ms(struct dentry *parent, struct qstr *qstr); | 42 | static int isofs_hash_ms(struct dentry *parent, struct qstr *qstr); |
37 | static int isofs_dentry_cmpi_ms(struct dentry *dentry, struct qstr *a, struct qstr *b); | 43 | static int isofs_dentry_cmpi_ms(const struct dentry *parent, |
38 | static 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); | ||
47 | static 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 | ||
41 | static void isofs_put_super(struct super_block *sb) | 53 | static 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 | */ |
211 | static int isofs_dentry_cmpi_common(struct dentry *dentry, struct qstr *a, | 223 | static 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 | */ | ||
235 | static 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 | ||
268 | static int | 262 | static int |
269 | isofs_dentry_cmp(struct dentry *dentry,struct qstr *a,struct qstr *b) | 263 | isofs_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 | ||
274 | static int | 270 | static int |
275 | isofs_dentry_cmpi(struct dentry *dentry,struct qstr *a,struct qstr *b) | 271 | isofs_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 | ||
293 | static int | 291 | static int |
294 | isofs_dentry_cmp_ms(struct dentry *dentry,struct qstr *a,struct qstr *b) | 292 | isofs_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 | ||
299 | static int | 299 | static int |
300 | isofs_dentry_cmpi_ms(struct dentry *dentry,struct qstr *a,struct qstr *b) | 300 | isofs_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 | /* |