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 | /* |
