diff options
author | David Howells <dhowells@redhat.com> | 2008-02-07 03:15:40 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2008-02-07 11:42:28 -0500 |
commit | 635253915b3297435e178371407d568522aae3d4 (patch) | |
tree | 98e102b111d0aa8703c8b971cb130acf19ce34d0 /fs/hfsplus | |
parent | fa300b1914f892196acb385677047bc978466de7 (diff) |
iget: stop HFSPLUS from using iget() and read_inode()
Stop the HFSPLUS filesystem from using iget() and read_inode(). Replace
hfsplus_read_inode() with hfsplus_iget(), and call that instead of iget().
hfsplus_iget() then uses iget_locked() directly and returns a proper error
code instead of an inode in the event of an error.
hfsplus_fill_super() returns any error incurred when getting the root inode.
Signed-off-by: David Howells <dhowells@redhat.com>
Cc: Roman Zippel <zippel@linux-m68k.org>
Acked-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/hfsplus')
-rw-r--r-- | fs/hfsplus/btree.c | 6 | ||||
-rw-r--r-- | fs/hfsplus/dir.c | 6 | ||||
-rw-r--r-- | fs/hfsplus/hfsplus_fs.h | 3 | ||||
-rw-r--r-- | fs/hfsplus/super.c | 47 |
4 files changed, 43 insertions, 19 deletions
diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c index 050d29c0a5b5..bb5433608a42 100644 --- a/fs/hfsplus/btree.c +++ b/fs/hfsplus/btree.c | |||
@@ -22,6 +22,7 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id) | |||
22 | struct hfs_btree *tree; | 22 | struct hfs_btree *tree; |
23 | struct hfs_btree_header_rec *head; | 23 | struct hfs_btree_header_rec *head; |
24 | struct address_space *mapping; | 24 | struct address_space *mapping; |
25 | struct inode *inode; | ||
25 | struct page *page; | 26 | struct page *page; |
26 | unsigned int size; | 27 | unsigned int size; |
27 | 28 | ||
@@ -33,9 +34,10 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id) | |||
33 | spin_lock_init(&tree->hash_lock); | 34 | spin_lock_init(&tree->hash_lock); |
34 | tree->sb = sb; | 35 | tree->sb = sb; |
35 | tree->cnid = id; | 36 | tree->cnid = id; |
36 | tree->inode = iget(sb, id); | 37 | inode = hfsplus_iget(sb, id); |
37 | if (!tree->inode) | 38 | if (IS_ERR(inode)) |
38 | goto free_tree; | 39 | goto free_tree; |
40 | tree->inode = inode; | ||
39 | 41 | ||
40 | mapping = tree->inode->i_mapping; | 42 | mapping = tree->inode->i_mapping; |
41 | page = read_mapping_page(mapping, 0, NULL); | 43 | page = read_mapping_page(mapping, 0, NULL); |
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 1955ee61251c..29683645fa0a 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c | |||
@@ -97,9 +97,9 @@ again: | |||
97 | goto fail; | 97 | goto fail; |
98 | } | 98 | } |
99 | hfs_find_exit(&fd); | 99 | hfs_find_exit(&fd); |
100 | inode = iget(dir->i_sb, cnid); | 100 | inode = hfsplus_iget(dir->i_sb, cnid); |
101 | if (!inode) | 101 | if (IS_ERR(inode)) |
102 | return ERR_PTR(-EACCES); | 102 | return ERR_CAST(inode); |
103 | if (S_ISREG(inode->i_mode)) | 103 | if (S_ISREG(inode->i_mode)) |
104 | HFSPLUS_I(inode).dev = linkid; | 104 | HFSPLUS_I(inode).dev = linkid; |
105 | out: | 105 | out: |
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index d9f5eda6d039..d72d0a8b25aa 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h | |||
@@ -345,6 +345,9 @@ int hfsplus_parse_options(char *, struct hfsplus_sb_info *); | |||
345 | void hfsplus_fill_defaults(struct hfsplus_sb_info *); | 345 | void hfsplus_fill_defaults(struct hfsplus_sb_info *); |
346 | int hfsplus_show_options(struct seq_file *, struct vfsmount *); | 346 | int hfsplus_show_options(struct seq_file *, struct vfsmount *); |
347 | 347 | ||
348 | /* super.c */ | ||
349 | struct inode *hfsplus_iget(struct super_block *, unsigned long); | ||
350 | |||
348 | /* tables.c */ | 351 | /* tables.c */ |
349 | extern u16 hfsplus_case_fold_table[]; | 352 | extern u16 hfsplus_case_fold_table[]; |
350 | extern u16 hfsplus_decompose_table[]; | 353 | extern u16 hfsplus_decompose_table[]; |
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index ecf70dafb643..b0f9ad362d1d 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
@@ -20,11 +20,18 @@ static void hfsplus_destroy_inode(struct inode *inode); | |||
20 | 20 | ||
21 | #include "hfsplus_fs.h" | 21 | #include "hfsplus_fs.h" |
22 | 22 | ||
23 | static void hfsplus_read_inode(struct inode *inode) | 23 | struct inode *hfsplus_iget(struct super_block *sb, unsigned long ino) |
24 | { | 24 | { |
25 | struct hfs_find_data fd; | 25 | struct hfs_find_data fd; |
26 | struct hfsplus_vh *vhdr; | 26 | struct hfsplus_vh *vhdr; |
27 | int err; | 27 | struct inode *inode; |
28 | long err = -EIO; | ||
29 | |||
30 | inode = iget_locked(sb, ino); | ||
31 | if (!inode) | ||
32 | return ERR_PTR(-ENOMEM); | ||
33 | if (!(inode->i_state & I_NEW)) | ||
34 | return inode; | ||
28 | 35 | ||
29 | INIT_LIST_HEAD(&HFSPLUS_I(inode).open_dir_list); | 36 | INIT_LIST_HEAD(&HFSPLUS_I(inode).open_dir_list); |
30 | init_MUTEX(&HFSPLUS_I(inode).extents_lock); | 37 | init_MUTEX(&HFSPLUS_I(inode).extents_lock); |
@@ -41,7 +48,7 @@ static void hfsplus_read_inode(struct inode *inode) | |||
41 | hfs_find_exit(&fd); | 48 | hfs_find_exit(&fd); |
42 | if (err) | 49 | if (err) |
43 | goto bad_inode; | 50 | goto bad_inode; |
44 | return; | 51 | goto done; |
45 | } | 52 | } |
46 | vhdr = HFSPLUS_SB(inode->i_sb).s_vhdr; | 53 | vhdr = HFSPLUS_SB(inode->i_sb).s_vhdr; |
47 | switch(inode->i_ino) { | 54 | switch(inode->i_ino) { |
@@ -70,10 +77,13 @@ static void hfsplus_read_inode(struct inode *inode) | |||
70 | goto bad_inode; | 77 | goto bad_inode; |
71 | } | 78 | } |
72 | 79 | ||
73 | return; | 80 | done: |
81 | unlock_new_inode(inode); | ||
82 | return inode; | ||
74 | 83 | ||
75 | bad_inode: | 84 | bad_inode: |
76 | make_bad_inode(inode); | 85 | iget_failed(inode); |
86 | return ERR_PTR(err); | ||
77 | } | 87 | } |
78 | 88 | ||
79 | static int hfsplus_write_inode(struct inode *inode, int unused) | 89 | static int hfsplus_write_inode(struct inode *inode, int unused) |
@@ -262,7 +272,6 @@ static int hfsplus_remount(struct super_block *sb, int *flags, char *data) | |||
262 | static const struct super_operations hfsplus_sops = { | 272 | static const struct super_operations hfsplus_sops = { |
263 | .alloc_inode = hfsplus_alloc_inode, | 273 | .alloc_inode = hfsplus_alloc_inode, |
264 | .destroy_inode = hfsplus_destroy_inode, | 274 | .destroy_inode = hfsplus_destroy_inode, |
265 | .read_inode = hfsplus_read_inode, | ||
266 | .write_inode = hfsplus_write_inode, | 275 | .write_inode = hfsplus_write_inode, |
267 | .clear_inode = hfsplus_clear_inode, | 276 | .clear_inode = hfsplus_clear_inode, |
268 | .put_super = hfsplus_put_super, | 277 | .put_super = hfsplus_put_super, |
@@ -278,7 +287,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
278 | struct hfsplus_sb_info *sbi; | 287 | struct hfsplus_sb_info *sbi; |
279 | hfsplus_cat_entry entry; | 288 | hfsplus_cat_entry entry; |
280 | struct hfs_find_data fd; | 289 | struct hfs_find_data fd; |
281 | struct inode *root; | 290 | struct inode *root, *inode; |
282 | struct qstr str; | 291 | struct qstr str; |
283 | struct nls_table *nls = NULL; | 292 | struct nls_table *nls = NULL; |
284 | int err = -EINVAL; | 293 | int err = -EINVAL; |
@@ -366,18 +375,25 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
366 | goto cleanup; | 375 | goto cleanup; |
367 | } | 376 | } |
368 | 377 | ||
369 | HFSPLUS_SB(sb).alloc_file = iget(sb, HFSPLUS_ALLOC_CNID); | 378 | inode = hfsplus_iget(sb, HFSPLUS_ALLOC_CNID); |
370 | if (!HFSPLUS_SB(sb).alloc_file) { | 379 | if (IS_ERR(inode)) { |
371 | printk(KERN_ERR "hfs: failed to load allocation file\n"); | 380 | printk(KERN_ERR "hfs: failed to load allocation file\n"); |
381 | err = PTR_ERR(inode); | ||
372 | goto cleanup; | 382 | goto cleanup; |
373 | } | 383 | } |
384 | HFSPLUS_SB(sb).alloc_file = inode; | ||
374 | 385 | ||
375 | /* Load the root directory */ | 386 | /* Load the root directory */ |
376 | root = iget(sb, HFSPLUS_ROOT_CNID); | 387 | root = hfsplus_iget(sb, HFSPLUS_ROOT_CNID); |
388 | if (IS_ERR(root)) { | ||
389 | printk(KERN_ERR "hfs: failed to load root directory\n"); | ||
390 | err = PTR_ERR(root); | ||
391 | goto cleanup; | ||
392 | } | ||
377 | sb->s_root = d_alloc_root(root); | 393 | sb->s_root = d_alloc_root(root); |
378 | if (!sb->s_root) { | 394 | if (!sb->s_root) { |
379 | printk(KERN_ERR "hfs: failed to load root directory\n"); | ||
380 | iput(root); | 395 | iput(root); |
396 | err = -ENOMEM; | ||
381 | goto cleanup; | 397 | goto cleanup; |
382 | } | 398 | } |
383 | sb->s_root->d_op = &hfsplus_dentry_operations; | 399 | sb->s_root->d_op = &hfsplus_dentry_operations; |
@@ -390,9 +406,12 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
390 | hfs_find_exit(&fd); | 406 | hfs_find_exit(&fd); |
391 | if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) | 407 | if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) |
392 | goto cleanup; | 408 | goto cleanup; |
393 | HFSPLUS_SB(sb).hidden_dir = iget(sb, be32_to_cpu(entry.folder.id)); | 409 | inode = hfsplus_iget(sb, be32_to_cpu(entry.folder.id)); |
394 | if (!HFSPLUS_SB(sb).hidden_dir) | 410 | if (IS_ERR(inode)) { |
411 | err = PTR_ERR(inode); | ||
395 | goto cleanup; | 412 | goto cleanup; |
413 | } | ||
414 | HFSPLUS_SB(sb).hidden_dir = inode; | ||
396 | } else | 415 | } else |
397 | hfs_find_exit(&fd); | 416 | hfs_find_exit(&fd); |
398 | 417 | ||