|
@@ -20,12 +20,42 @@ static void hfsplus_destroy_inode(struct inode *inode);
|
|
|
|
|
|
#include "hfsplus_fs.h"
|
|
|
|
|
|
+static int hfsplus_system_read_inode(struct inode *inode)
|
|
|
+{
|
|
|
+ struct hfsplus_vh *vhdr = HFSPLUS_SB(inode->i_sb)->s_vhdr;
|
|
|
+
|
|
|
+ switch (inode->i_ino) {
|
|
|
+ case HFSPLUS_EXT_CNID:
|
|
|
+ hfsplus_inode_read_fork(inode, &vhdr->ext_file);
|
|
|
+ inode->i_mapping->a_ops = &hfsplus_btree_aops;
|
|
|
+ break;
|
|
|
+ case HFSPLUS_CAT_CNID:
|
|
|
+ hfsplus_inode_read_fork(inode, &vhdr->cat_file);
|
|
|
+ inode->i_mapping->a_ops = &hfsplus_btree_aops;
|
|
|
+ break;
|
|
|
+ case HFSPLUS_ALLOC_CNID:
|
|
|
+ hfsplus_inode_read_fork(inode, &vhdr->alloc_file);
|
|
|
+ inode->i_mapping->a_ops = &hfsplus_aops;
|
|
|
+ break;
|
|
|
+ case HFSPLUS_START_CNID:
|
|
|
+ hfsplus_inode_read_fork(inode, &vhdr->start_file);
|
|
|
+ break;
|
|
|
+ case HFSPLUS_ATTR_CNID:
|
|
|
+ hfsplus_inode_read_fork(inode, &vhdr->attr_file);
|
|
|
+ inode->i_mapping->a_ops = &hfsplus_btree_aops;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ return -EIO;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
struct inode *hfsplus_iget(struct super_block *sb, unsigned long ino)
|
|
|
{
|
|
|
struct hfs_find_data fd;
|
|
|
- struct hfsplus_vh *vhdr;
|
|
|
struct inode *inode;
|
|
|
- long err = -EIO;
|
|
|
+ int err;
|
|
|
|
|
|
inode = iget_locked(sb, ino);
|
|
|
if (!inode)
|
|
@@ -39,51 +69,24 @@ struct inode *hfsplus_iget(struct super_block *sb, unsigned long ino)
|
|
|
HFSPLUS_I(inode)->rsrc_inode = NULL;
|
|
|
atomic_set(&HFSPLUS_I(inode)->opencnt, 0);
|
|
|
|
|
|
- if (inode->i_ino >= HFSPLUS_FIRSTUSER_CNID) {
|
|
|
- read_inode:
|
|
|
+ if (inode->i_ino >= HFSPLUS_FIRSTUSER_CNID ||
|
|
|
+ inode->i_ino == HFSPLUS_ROOT_CNID) {
|
|
|
hfs_find_init(HFSPLUS_SB(inode->i_sb)->cat_tree, &fd);
|
|
|
err = hfsplus_find_cat(inode->i_sb, inode->i_ino, &fd);
|
|
|
if (!err)
|
|
|
err = hfsplus_cat_read_inode(inode, &fd);
|
|
|
hfs_find_exit(&fd);
|
|
|
- if (err)
|
|
|
- goto bad_inode;
|
|
|
- goto done;
|
|
|
+ } else {
|
|
|
+ err = hfsplus_system_read_inode(inode);
|
|
|
}
|
|
|
- vhdr = HFSPLUS_SB(inode->i_sb)->s_vhdr;
|
|
|
- switch(inode->i_ino) {
|
|
|
- case HFSPLUS_ROOT_CNID:
|
|
|
- goto read_inode;
|
|
|
- case HFSPLUS_EXT_CNID:
|
|
|
- hfsplus_inode_read_fork(inode, &vhdr->ext_file);
|
|
|
- inode->i_mapping->a_ops = &hfsplus_btree_aops;
|
|
|
- break;
|
|
|
- case HFSPLUS_CAT_CNID:
|
|
|
- hfsplus_inode_read_fork(inode, &vhdr->cat_file);
|
|
|
- inode->i_mapping->a_ops = &hfsplus_btree_aops;
|
|
|
- break;
|
|
|
- case HFSPLUS_ALLOC_CNID:
|
|
|
- hfsplus_inode_read_fork(inode, &vhdr->alloc_file);
|
|
|
- inode->i_mapping->a_ops = &hfsplus_aops;
|
|
|
- break;
|
|
|
- case HFSPLUS_START_CNID:
|
|
|
- hfsplus_inode_read_fork(inode, &vhdr->start_file);
|
|
|
- break;
|
|
|
- case HFSPLUS_ATTR_CNID:
|
|
|
- hfsplus_inode_read_fork(inode, &vhdr->attr_file);
|
|
|
- inode->i_mapping->a_ops = &hfsplus_btree_aops;
|
|
|
- break;
|
|
|
- default:
|
|
|
- goto bad_inode;
|
|
|
+
|
|
|
+ if (err) {
|
|
|
+ iget_failed(inode);
|
|
|
+ return ERR_PTR(err);
|
|
|
}
|
|
|
|
|
|
-done:
|
|
|
unlock_new_inode(inode);
|
|
|
return inode;
|
|
|
-
|
|
|
-bad_inode:
|
|
|
- iget_failed(inode);
|
|
|
- return ERR_PTR(err);
|
|
|
}
|
|
|
|
|
|
static int hfsplus_write_inode(struct inode *inode,
|