diff options
author | Christoph Hellwig <hch@tuxera.com> | 2010-09-30 23:43:41 -0400 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2010-09-30 23:43:41 -0400 |
commit | fc4fff82104fa096eada73943fe5249500acd5fa (patch) | |
tree | 5fefc3512525a08d9a77723706cde96d001c167f /fs/hfsplus/super.c | |
parent | 6af502de224c3742936d54eee7e3690c09822934 (diff) |
hfsplus: clean up hfsplus_iget
Add a new hfsplus_system_read_inode for reading the special system inodes
and streamline the fastpath iget code.
Signed-off-by: Christoph Hellwig <hch@tuxera.com>
Diffstat (limited to 'fs/hfsplus/super.c')
-rw-r--r-- | fs/hfsplus/super.c | 77 |
1 files changed, 40 insertions, 37 deletions
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index a7bf89e85b3b..bd09ea23435b 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
@@ -20,12 +20,42 @@ static void hfsplus_destroy_inode(struct inode *inode); | |||
20 | 20 | ||
21 | #include "hfsplus_fs.h" | 21 | #include "hfsplus_fs.h" |
22 | 22 | ||
23 | static int hfsplus_system_read_inode(struct inode *inode) | ||
24 | { | ||
25 | struct hfsplus_vh *vhdr = HFSPLUS_SB(inode->i_sb)->s_vhdr; | ||
26 | |||
27 | switch (inode->i_ino) { | ||
28 | case HFSPLUS_EXT_CNID: | ||
29 | hfsplus_inode_read_fork(inode, &vhdr->ext_file); | ||
30 | inode->i_mapping->a_ops = &hfsplus_btree_aops; | ||
31 | break; | ||
32 | case HFSPLUS_CAT_CNID: | ||
33 | hfsplus_inode_read_fork(inode, &vhdr->cat_file); | ||
34 | inode->i_mapping->a_ops = &hfsplus_btree_aops; | ||
35 | break; | ||
36 | case HFSPLUS_ALLOC_CNID: | ||
37 | hfsplus_inode_read_fork(inode, &vhdr->alloc_file); | ||
38 | inode->i_mapping->a_ops = &hfsplus_aops; | ||
39 | break; | ||
40 | case HFSPLUS_START_CNID: | ||
41 | hfsplus_inode_read_fork(inode, &vhdr->start_file); | ||
42 | break; | ||
43 | case HFSPLUS_ATTR_CNID: | ||
44 | hfsplus_inode_read_fork(inode, &vhdr->attr_file); | ||
45 | inode->i_mapping->a_ops = &hfsplus_btree_aops; | ||
46 | break; | ||
47 | default: | ||
48 | return -EIO; | ||
49 | } | ||
50 | |||
51 | return 0; | ||
52 | } | ||
53 | |||
23 | struct inode *hfsplus_iget(struct super_block *sb, unsigned long ino) | 54 | struct inode *hfsplus_iget(struct super_block *sb, unsigned long ino) |
24 | { | 55 | { |
25 | struct hfs_find_data fd; | 56 | struct hfs_find_data fd; |
26 | struct hfsplus_vh *vhdr; | ||
27 | struct inode *inode; | 57 | struct inode *inode; |
28 | long err = -EIO; | 58 | int err; |
29 | 59 | ||
30 | inode = iget_locked(sb, ino); | 60 | inode = iget_locked(sb, ino); |
31 | if (!inode) | 61 | if (!inode) |
@@ -39,51 +69,24 @@ struct inode *hfsplus_iget(struct super_block *sb, unsigned long ino) | |||
39 | HFSPLUS_I(inode)->rsrc_inode = NULL; | 69 | HFSPLUS_I(inode)->rsrc_inode = NULL; |
40 | atomic_set(&HFSPLUS_I(inode)->opencnt, 0); | 70 | atomic_set(&HFSPLUS_I(inode)->opencnt, 0); |
41 | 71 | ||
42 | if (inode->i_ino >= HFSPLUS_FIRSTUSER_CNID) { | 72 | if (inode->i_ino >= HFSPLUS_FIRSTUSER_CNID || |
43 | read_inode: | 73 | inode->i_ino == HFSPLUS_ROOT_CNID) { |
44 | hfs_find_init(HFSPLUS_SB(inode->i_sb)->cat_tree, &fd); | 74 | hfs_find_init(HFSPLUS_SB(inode->i_sb)->cat_tree, &fd); |
45 | err = hfsplus_find_cat(inode->i_sb, inode->i_ino, &fd); | 75 | err = hfsplus_find_cat(inode->i_sb, inode->i_ino, &fd); |
46 | if (!err) | 76 | if (!err) |
47 | err = hfsplus_cat_read_inode(inode, &fd); | 77 | err = hfsplus_cat_read_inode(inode, &fd); |
48 | hfs_find_exit(&fd); | 78 | hfs_find_exit(&fd); |
49 | if (err) | 79 | } else { |
50 | goto bad_inode; | 80 | err = hfsplus_system_read_inode(inode); |
51 | goto done; | ||
52 | } | 81 | } |
53 | vhdr = HFSPLUS_SB(inode->i_sb)->s_vhdr; | 82 | |
54 | switch(inode->i_ino) { | 83 | if (err) { |
55 | case HFSPLUS_ROOT_CNID: | 84 | iget_failed(inode); |
56 | goto read_inode; | 85 | return ERR_PTR(err); |
57 | case HFSPLUS_EXT_CNID: | ||
58 | hfsplus_inode_read_fork(inode, &vhdr->ext_file); | ||
59 | inode->i_mapping->a_ops = &hfsplus_btree_aops; | ||
60 | break; | ||
61 | case HFSPLUS_CAT_CNID: | ||
62 | hfsplus_inode_read_fork(inode, &vhdr->cat_file); | ||
63 | inode->i_mapping->a_ops = &hfsplus_btree_aops; | ||
64 | break; | ||
65 | case HFSPLUS_ALLOC_CNID: | ||
66 | hfsplus_inode_read_fork(inode, &vhdr->alloc_file); | ||
67 | inode->i_mapping->a_ops = &hfsplus_aops; | ||
68 | break; | ||
69 | case HFSPLUS_START_CNID: | ||
70 | hfsplus_inode_read_fork(inode, &vhdr->start_file); | ||
71 | break; | ||
72 | case HFSPLUS_ATTR_CNID: | ||
73 | hfsplus_inode_read_fork(inode, &vhdr->attr_file); | ||
74 | inode->i_mapping->a_ops = &hfsplus_btree_aops; | ||
75 | break; | ||
76 | default: | ||
77 | goto bad_inode; | ||
78 | } | 86 | } |
79 | 87 | ||
80 | done: | ||
81 | unlock_new_inode(inode); | 88 | unlock_new_inode(inode); |
82 | return inode; | 89 | return inode; |
83 | |||
84 | bad_inode: | ||
85 | iget_failed(inode); | ||
86 | return ERR_PTR(err); | ||
87 | } | 90 | } |
88 | 91 | ||
89 | static int hfsplus_write_inode(struct inode *inode, | 92 | static int hfsplus_write_inode(struct inode *inode, |