summaryrefslogtreecommitdiffstats
path: root/fs/hfsplus/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/hfsplus/super.c')
-rw-r--r--fs/hfsplus/super.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index b49b55584c8..c106ca22e81 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -73,11 +73,13 @@ struct inode *hfsplus_iget(struct super_block *sb, unsigned long ino)
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);
+ err = hfs_find_init(HFSPLUS_SB(inode->i_sb)->cat_tree, &fd);
+ if (!err) {
+ err = hfsplus_find_cat(inode->i_sb, inode->i_ino, &fd);
+ if (!err)
+ err = hfsplus_cat_read_inode(inode, &fd);
+ hfs_find_exit(&fd);
+ }
} else {
err = hfsplus_system_read_inode(inode);
}
@@ -133,9 +135,13 @@ static int hfsplus_system_write_inode(struct inode *inode)
static int hfsplus_write_inode(struct inode *inode,
struct writeback_control *wbc)
{
+ int err;
+
dprint(DBG_INODE, "hfsplus_write_inode: %lu\n", inode->i_ino);
- hfsplus_ext_write_extent(inode);
+ err = hfsplus_ext_write_extent(inode);
+ if (err)
+ return err;
if (inode->i_ino >= HFSPLUS_FIRSTUSER_CNID ||
inode->i_ino == HFSPLUS_ROOT_CNID)
@@ -197,17 +203,17 @@ int hfsplus_sync_fs(struct super_block *sb, int wait)
write_backup = 1;
}
- error2 = hfsplus_submit_bio(sb->s_bdev,
+ error2 = hfsplus_submit_bio(sb,
sbi->part_start + HFSPLUS_VOLHEAD_SECTOR,
- sbi->s_vhdr, WRITE_SYNC);
+ sbi->s_vhdr_buf, NULL, WRITE_SYNC);
if (!error)
error = error2;
if (!write_backup)
goto out;
- error2 = hfsplus_submit_bio(sb->s_bdev,
+ error2 = hfsplus_submit_bio(sb,
sbi->part_start + sbi->sect_count - 2,
- sbi->s_backup_vhdr, WRITE_SYNC);
+ sbi->s_backup_vhdr_buf, NULL, WRITE_SYNC);
if (!error)
error2 = error;
out:
@@ -251,8 +257,8 @@ static void hfsplus_put_super(struct super_block *sb)
hfs_btree_close(sbi->ext_tree);
iput(sbi->alloc_file);
iput(sbi->hidden_dir);
- kfree(sbi->s_vhdr);
- kfree(sbi->s_backup_vhdr);
+ kfree(sbi->s_vhdr_buf);
+ kfree(sbi->s_backup_vhdr_buf);
unload_nls(sbi->nls);
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
@@ -393,6 +399,13 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
if (!sbi->rsrc_clump_blocks)
sbi->rsrc_clump_blocks = 1;
+ err = generic_check_addressable(sbi->alloc_blksz_shift,
+ sbi->total_blocks);
+ if (err) {
+ printk(KERN_ERR "hfs: filesystem size too large.\n");
+ goto out_free_vhdr;
+ }
+
/* Set up operations so we can load metadata */
sb->s_op = &hfsplus_sops;
sb->s_maxbytes = MAX_LFS_FILESIZE;
@@ -417,6 +430,8 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
sb->s_flags |= MS_RDONLY;
}
+ err = -EINVAL;
+
/* Load metadata objects (B*Trees) */
sbi->ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID);
if (!sbi->ext_tree) {
@@ -447,7 +462,9 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
str.len = sizeof(HFSP_HIDDENDIR_NAME) - 1;
str.name = HFSP_HIDDENDIR_NAME;
- hfs_find_init(sbi->cat_tree, &fd);
+ err = hfs_find_init(sbi->cat_tree, &fd);
+ if (err)
+ goto out_put_root;
hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_ROOT_CNID, &str);
if (!hfs_brec_read(&fd, &entry, sizeof(entry))) {
hfs_find_exit(&fd);
@@ -500,7 +517,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
out_put_hidden_dir:
iput(sbi->hidden_dir);
out_put_root:
- iput(sbi->alloc_file);
+ iput(root);
out_put_alloc_file:
iput(sbi->alloc_file);
out_close_cat_tree: