diff options
Diffstat (limited to 'fs/isofs/inode.c')
-rw-r--r-- | fs/isofs/inode.c | 131 |
1 files changed, 74 insertions, 57 deletions
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index bfdeb82a53be..844a7903c72f 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
@@ -26,16 +26,32 @@ | |||
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_dentry_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b); | 31 | static int isofs_hash(const struct dentry *parent, const struct inode *inode, |
32 | static int isofs_dentry_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b); | 32 | struct qstr *qstr); |
33 | static int isofs_dentry_cmpi(const struct dentry *parent, | ||
34 | const struct inode *pinode, | ||
35 | const struct dentry *dentry, const struct inode *inode, | ||
36 | unsigned int len, const char *str, const struct qstr *name); | ||
37 | static int isofs_dentry_cmp(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); | ||
33 | 41 | ||
34 | #ifdef CONFIG_JOLIET | 42 | #ifdef CONFIG_JOLIET |
35 | 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, |
36 | static int isofs_hash_ms(struct dentry *parent, struct qstr *qstr); | 44 | struct qstr *qstr); |
37 | static int isofs_dentry_cmpi_ms(struct dentry *dentry, struct qstr *a, struct qstr *b); | 45 | static int isofs_hash_ms(const struct dentry *parent, const struct inode *inode, |
38 | static int isofs_dentry_cmp_ms(struct dentry *dentry, struct qstr *a, struct qstr *b); | 46 | struct qstr *qstr); |
47 | static int isofs_dentry_cmpi_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); | ||
51 | static int isofs_dentry_cmp_ms(const struct dentry *parent, | ||
52 | const struct inode *pinode, | ||
53 | const struct dentry *dentry, const struct inode *inode, | ||
54 | unsigned int len, const char *str, const struct qstr *name); | ||
39 | #endif | 55 | #endif |
40 | 56 | ||
41 | static void isofs_put_super(struct super_block *sb) | 57 | static void isofs_put_super(struct super_block *sb) |
@@ -65,11 +81,18 @@ static struct inode *isofs_alloc_inode(struct super_block *sb) | |||
65 | return &ei->vfs_inode; | 81 | return &ei->vfs_inode; |
66 | } | 82 | } |
67 | 83 | ||
68 | static void isofs_destroy_inode(struct inode *inode) | 84 | static void isofs_i_callback(struct rcu_head *head) |
69 | { | 85 | { |
86 | struct inode *inode = container_of(head, struct inode, i_rcu); | ||
87 | INIT_LIST_HEAD(&inode->i_dentry); | ||
70 | kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode)); | 88 | kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode)); |
71 | } | 89 | } |
72 | 90 | ||
91 | static void isofs_destroy_inode(struct inode *inode) | ||
92 | { | ||
93 | call_rcu(&inode->i_rcu, isofs_i_callback); | ||
94 | } | ||
95 | |||
73 | static void init_once(void *foo) | 96 | static void init_once(void *foo) |
74 | { | 97 | { |
75 | struct iso_inode_info *ei = foo; | 98 | struct iso_inode_info *ei = foo; |
@@ -160,7 +183,7 @@ struct iso9660_options{ | |||
160 | * Compute the hash for the isofs name corresponding to the dentry. | 183 | * Compute the hash for the isofs name corresponding to the dentry. |
161 | */ | 184 | */ |
162 | static int | 185 | static int |
163 | isofs_hash_common(struct dentry *dentry, struct qstr *qstr, int ms) | 186 | isofs_hash_common(const struct dentry *dentry, struct qstr *qstr, int ms) |
164 | { | 187 | { |
165 | const char *name; | 188 | const char *name; |
166 | int len; | 189 | int len; |
@@ -181,7 +204,7 @@ isofs_hash_common(struct dentry *dentry, struct qstr *qstr, int ms) | |||
181 | * Compute the hash for the isofs name corresponding to the dentry. | 204 | * Compute the hash for the isofs name corresponding to the dentry. |
182 | */ | 205 | */ |
183 | static int | 206 | static int |
184 | isofs_hashi_common(struct dentry *dentry, struct qstr *qstr, int ms) | 207 | isofs_hashi_common(const struct dentry *dentry, struct qstr *qstr, int ms) |
185 | { | 208 | { |
186 | const char *name; | 209 | const char *name; |
187 | int len; | 210 | int len; |
@@ -206,100 +229,94 @@ isofs_hashi_common(struct dentry *dentry, struct qstr *qstr, int ms) | |||
206 | } | 229 | } |
207 | 230 | ||
208 | /* | 231 | /* |
209 | * Case insensitive compare of two isofs names. | 232 | * Compare of two isofs names. |
210 | */ | ||
211 | static int isofs_dentry_cmpi_common(struct dentry *dentry, struct qstr *a, | ||
212 | struct qstr *b, int ms) | ||
213 | { | ||
214 | int alen, blen; | ||
215 | |||
216 | /* A filename cannot end in '.' or we treat it like it has none */ | ||
217 | alen = a->len; | ||
218 | blen = b->len; | ||
219 | if (ms) { | ||
220 | while (alen && a->name[alen-1] == '.') | ||
221 | alen--; | ||
222 | while (blen && b->name[blen-1] == '.') | ||
223 | blen--; | ||
224 | } | ||
225 | if (alen == blen) { | ||
226 | if (strnicmp(a->name, b->name, alen) == 0) | ||
227 | return 0; | ||
228 | } | ||
229 | return 1; | ||
230 | } | ||
231 | |||
232 | /* | ||
233 | * Case sensitive compare of two isofs names. | ||
234 | */ | 233 | */ |
235 | static int isofs_dentry_cmp_common(struct dentry *dentry, struct qstr *a, | 234 | static int isofs_dentry_cmp_common( |
236 | struct qstr *b, int ms) | 235 | unsigned int len, const char *str, |
236 | const struct qstr *name, int ms, int ci) | ||
237 | { | 237 | { |
238 | int alen, blen; | 238 | int alen, blen; |
239 | 239 | ||
240 | /* A filename cannot end in '.' or we treat it like it has none */ | 240 | /* A filename cannot end in '.' or we treat it like it has none */ |
241 | alen = a->len; | 241 | alen = name->len; |
242 | blen = b->len; | 242 | blen = len; |
243 | if (ms) { | 243 | if (ms) { |
244 | while (alen && a->name[alen-1] == '.') | 244 | while (alen && name->name[alen-1] == '.') |
245 | alen--; | 245 | alen--; |
246 | while (blen && b->name[blen-1] == '.') | 246 | while (blen && str[blen-1] == '.') |
247 | blen--; | 247 | blen--; |
248 | } | 248 | } |
249 | if (alen == blen) { | 249 | if (alen == blen) { |
250 | if (strncmp(a->name, b->name, alen) == 0) | 250 | if (ci) { |
251 | return 0; | 251 | if (strnicmp(name->name, str, alen) == 0) |
252 | return 0; | ||
253 | } else { | ||
254 | if (strncmp(name->name, str, alen) == 0) | ||
255 | return 0; | ||
256 | } | ||
252 | } | 257 | } |
253 | return 1; | 258 | return 1; |
254 | } | 259 | } |
255 | 260 | ||
256 | static int | 261 | static int |
257 | isofs_hash(struct dentry *dentry, struct qstr *qstr) | 262 | isofs_hash(const struct dentry *dentry, const struct inode *inode, |
263 | struct qstr *qstr) | ||
258 | { | 264 | { |
259 | return isofs_hash_common(dentry, qstr, 0); | 265 | return isofs_hash_common(dentry, qstr, 0); |
260 | } | 266 | } |
261 | 267 | ||
262 | static int | 268 | static int |
263 | isofs_hashi(struct dentry *dentry, struct qstr *qstr) | 269 | isofs_hashi(const struct dentry *dentry, const struct inode *inode, |
270 | struct qstr *qstr) | ||
264 | { | 271 | { |
265 | return isofs_hashi_common(dentry, qstr, 0); | 272 | return isofs_hashi_common(dentry, qstr, 0); |
266 | } | 273 | } |
267 | 274 | ||
268 | static int | 275 | static int |
269 | isofs_dentry_cmp(struct dentry *dentry,struct qstr *a,struct qstr *b) | 276 | isofs_dentry_cmp(const struct dentry *parent, const struct inode *pinode, |
277 | const struct dentry *dentry, const struct inode *inode, | ||
278 | unsigned int len, const char *str, const struct qstr *name) | ||
270 | { | 279 | { |
271 | return isofs_dentry_cmp_common(dentry, a, b, 0); | 280 | return isofs_dentry_cmp_common(len, str, name, 0, 0); |
272 | } | 281 | } |
273 | 282 | ||
274 | static int | 283 | static int |
275 | isofs_dentry_cmpi(struct dentry *dentry,struct qstr *a,struct qstr *b) | 284 | isofs_dentry_cmpi(const struct dentry *parent, const struct inode *pinode, |
285 | const struct dentry *dentry, const struct inode *inode, | ||
286 | unsigned int len, const char *str, const struct qstr *name) | ||
276 | { | 287 | { |
277 | return isofs_dentry_cmpi_common(dentry, a, b, 0); | 288 | return isofs_dentry_cmp_common(len, str, name, 0, 1); |
278 | } | 289 | } |
279 | 290 | ||
280 | #ifdef CONFIG_JOLIET | 291 | #ifdef CONFIG_JOLIET |
281 | static int | 292 | static int |
282 | isofs_hash_ms(struct dentry *dentry, struct qstr *qstr) | 293 | isofs_hash_ms(const struct dentry *dentry, const struct inode *inode, |
294 | struct qstr *qstr) | ||
283 | { | 295 | { |
284 | return isofs_hash_common(dentry, qstr, 1); | 296 | return isofs_hash_common(dentry, qstr, 1); |
285 | } | 297 | } |
286 | 298 | ||
287 | static int | 299 | static int |
288 | isofs_hashi_ms(struct dentry *dentry, struct qstr *qstr) | 300 | isofs_hashi_ms(const struct dentry *dentry, const struct inode *inode, |
301 | struct qstr *qstr) | ||
289 | { | 302 | { |
290 | return isofs_hashi_common(dentry, qstr, 1); | 303 | return isofs_hashi_common(dentry, qstr, 1); |
291 | } | 304 | } |
292 | 305 | ||
293 | static int | 306 | static int |
294 | isofs_dentry_cmp_ms(struct dentry *dentry,struct qstr *a,struct qstr *b) | 307 | isofs_dentry_cmp_ms(const struct dentry *parent, const struct inode *pinode, |
308 | const struct dentry *dentry, const struct inode *inode, | ||
309 | unsigned int len, const char *str, const struct qstr *name) | ||
295 | { | 310 | { |
296 | return isofs_dentry_cmp_common(dentry, a, b, 1); | 311 | return isofs_dentry_cmp_common(len, str, name, 1, 0); |
297 | } | 312 | } |
298 | 313 | ||
299 | static int | 314 | static int |
300 | isofs_dentry_cmpi_ms(struct dentry *dentry,struct qstr *a,struct qstr *b) | 315 | isofs_dentry_cmpi_ms(const struct dentry *parent, const struct inode *pinode, |
316 | const struct dentry *dentry, const struct inode *inode, | ||
317 | unsigned int len, const char *str, const struct qstr *name) | ||
301 | { | 318 | { |
302 | return isofs_dentry_cmpi_common(dentry, a, b, 1); | 319 | return isofs_dentry_cmp_common(len, str, name, 1, 1); |
303 | } | 320 | } |
304 | #endif | 321 | #endif |
305 | 322 | ||
@@ -932,7 +949,7 @@ root_found: | |||
932 | table += 2; | 949 | table += 2; |
933 | if (opt.check == 'r') | 950 | if (opt.check == 'r') |
934 | table++; | 951 | table++; |
935 | s->s_root->d_op = &isofs_dentry_ops[table]; | 952 | d_set_d_op(s->s_root, &isofs_dentry_ops[table]); |
936 | 953 | ||
937 | kfree(opt.iocharset); | 954 | kfree(opt.iocharset); |
938 | 955 | ||