aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hfsplus/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/hfsplus/super.c')
-rw-r--r--fs/hfsplus/super.c47
1 files changed, 33 insertions, 14 deletions
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
23static void hfsplus_read_inode(struct inode *inode) 23struct 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; 80done:
81 unlock_new_inode(inode);
82 return inode;
74 83
75 bad_inode: 84bad_inode:
76 make_bad_inode(inode); 85 iget_failed(inode);
86 return ERR_PTR(err);
77} 87}
78 88
79static int hfsplus_write_inode(struct inode *inode, int unused) 89static 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)
262static const struct super_operations hfsplus_sops = { 272static 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