mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-01 09:26:44 +07:00
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hch/hfsplus
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hch/hfsplus: hfsplus: fix up a comparism in hfsplus_file_extend hfsplus: fix two memory leaks in wrapper.c hfsplus: do not leak buffer on error hfsplus: fix failed mount handling
This commit is contained in:
commit
89840966c5
@ -397,8 +397,8 @@ int hfsplus_file_extend(struct inode *inode)
|
|||||||
u32 start, len, goal;
|
u32 start, len, goal;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (sbi->total_blocks - sbi->free_blocks + 8 >
|
if (sbi->alloc_file->i_size * 8 <
|
||||||
sbi->alloc_file->i_size * 8) {
|
sbi->total_blocks - sbi->free_blocks + 8) {
|
||||||
/* extend alloc file */
|
/* extend alloc file */
|
||||||
printk(KERN_ERR "hfs: extend alloc file! "
|
printk(KERN_ERR "hfs: extend alloc file! "
|
||||||
"(%llu,%u,%u)\n",
|
"(%llu,%u,%u)\n",
|
||||||
|
@ -134,7 +134,7 @@ int hfs_part_find(struct super_block *sb,
|
|||||||
res = hfsplus_submit_bio(sb->s_bdev, *part_start + HFS_PMAP_BLK,
|
res = hfsplus_submit_bio(sb->s_bdev, *part_start + HFS_PMAP_BLK,
|
||||||
data, READ);
|
data, READ);
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
goto out;
|
||||||
|
|
||||||
switch (be16_to_cpu(*((__be16 *)data))) {
|
switch (be16_to_cpu(*((__be16 *)data))) {
|
||||||
case HFS_OLD_PMAP_MAGIC:
|
case HFS_OLD_PMAP_MAGIC:
|
||||||
@ -147,7 +147,7 @@ int hfs_part_find(struct super_block *sb,
|
|||||||
res = -ENOENT;
|
res = -ENOENT;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
kfree(data);
|
kfree(data);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -338,20 +338,22 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
|
|||||||
struct inode *root, *inode;
|
struct inode *root, *inode;
|
||||||
struct qstr str;
|
struct qstr str;
|
||||||
struct nls_table *nls = NULL;
|
struct nls_table *nls = NULL;
|
||||||
int err = -EINVAL;
|
int err;
|
||||||
|
|
||||||
|
err = -EINVAL;
|
||||||
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
|
sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
|
||||||
if (!sbi)
|
if (!sbi)
|
||||||
return -ENOMEM;
|
goto out;
|
||||||
|
|
||||||
sb->s_fs_info = sbi;
|
sb->s_fs_info = sbi;
|
||||||
mutex_init(&sbi->alloc_mutex);
|
mutex_init(&sbi->alloc_mutex);
|
||||||
mutex_init(&sbi->vh_mutex);
|
mutex_init(&sbi->vh_mutex);
|
||||||
hfsplus_fill_defaults(sbi);
|
hfsplus_fill_defaults(sbi);
|
||||||
|
|
||||||
|
err = -EINVAL;
|
||||||
if (!hfsplus_parse_options(data, sbi)) {
|
if (!hfsplus_parse_options(data, sbi)) {
|
||||||
printk(KERN_ERR "hfs: unable to parse mount options\n");
|
printk(KERN_ERR "hfs: unable to parse mount options\n");
|
||||||
err = -EINVAL;
|
goto out_unload_nls;
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* temporarily use utf8 to correctly find the hidden dir below */
|
/* temporarily use utf8 to correctly find the hidden dir below */
|
||||||
@ -359,16 +361,14 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
|
|||||||
sbi->nls = load_nls("utf8");
|
sbi->nls = load_nls("utf8");
|
||||||
if (!sbi->nls) {
|
if (!sbi->nls) {
|
||||||
printk(KERN_ERR "hfs: unable to load nls for utf8\n");
|
printk(KERN_ERR "hfs: unable to load nls for utf8\n");
|
||||||
err = -EINVAL;
|
goto out_unload_nls;
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Grab the volume header */
|
/* Grab the volume header */
|
||||||
if (hfsplus_read_wrapper(sb)) {
|
if (hfsplus_read_wrapper(sb)) {
|
||||||
if (!silent)
|
if (!silent)
|
||||||
printk(KERN_WARNING "hfs: unable to find HFS+ superblock\n");
|
printk(KERN_WARNING "hfs: unable to find HFS+ superblock\n");
|
||||||
err = -EINVAL;
|
goto out_unload_nls;
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
vhdr = sbi->s_vhdr;
|
vhdr = sbi->s_vhdr;
|
||||||
|
|
||||||
@ -377,7 +377,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
|
|||||||
if (be16_to_cpu(vhdr->version) < HFSPLUS_MIN_VERSION ||
|
if (be16_to_cpu(vhdr->version) < HFSPLUS_MIN_VERSION ||
|
||||||
be16_to_cpu(vhdr->version) > HFSPLUS_CURRENT_VERSION) {
|
be16_to_cpu(vhdr->version) > HFSPLUS_CURRENT_VERSION) {
|
||||||
printk(KERN_ERR "hfs: wrong filesystem version\n");
|
printk(KERN_ERR "hfs: wrong filesystem version\n");
|
||||||
goto cleanup;
|
goto out_free_vhdr;
|
||||||
}
|
}
|
||||||
sbi->total_blocks = be32_to_cpu(vhdr->total_blocks);
|
sbi->total_blocks = be32_to_cpu(vhdr->total_blocks);
|
||||||
sbi->free_blocks = be32_to_cpu(vhdr->free_blocks);
|
sbi->free_blocks = be32_to_cpu(vhdr->free_blocks);
|
||||||
@ -421,19 +421,19 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
|
|||||||
sbi->ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID);
|
sbi->ext_tree = hfs_btree_open(sb, HFSPLUS_EXT_CNID);
|
||||||
if (!sbi->ext_tree) {
|
if (!sbi->ext_tree) {
|
||||||
printk(KERN_ERR "hfs: failed to load extents file\n");
|
printk(KERN_ERR "hfs: failed to load extents file\n");
|
||||||
goto cleanup;
|
goto out_free_vhdr;
|
||||||
}
|
}
|
||||||
sbi->cat_tree = hfs_btree_open(sb, HFSPLUS_CAT_CNID);
|
sbi->cat_tree = hfs_btree_open(sb, HFSPLUS_CAT_CNID);
|
||||||
if (!sbi->cat_tree) {
|
if (!sbi->cat_tree) {
|
||||||
printk(KERN_ERR "hfs: failed to load catalog file\n");
|
printk(KERN_ERR "hfs: failed to load catalog file\n");
|
||||||
goto cleanup;
|
goto out_close_ext_tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
inode = hfsplus_iget(sb, HFSPLUS_ALLOC_CNID);
|
inode = hfsplus_iget(sb, HFSPLUS_ALLOC_CNID);
|
||||||
if (IS_ERR(inode)) {
|
if (IS_ERR(inode)) {
|
||||||
printk(KERN_ERR "hfs: failed to load allocation file\n");
|
printk(KERN_ERR "hfs: failed to load allocation file\n");
|
||||||
err = PTR_ERR(inode);
|
err = PTR_ERR(inode);
|
||||||
goto cleanup;
|
goto out_close_cat_tree;
|
||||||
}
|
}
|
||||||
sbi->alloc_file = inode;
|
sbi->alloc_file = inode;
|
||||||
|
|
||||||
@ -442,14 +442,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
|
|||||||
if (IS_ERR(root)) {
|
if (IS_ERR(root)) {
|
||||||
printk(KERN_ERR "hfs: failed to load root directory\n");
|
printk(KERN_ERR "hfs: failed to load root directory\n");
|
||||||
err = PTR_ERR(root);
|
err = PTR_ERR(root);
|
||||||
goto cleanup;
|
goto out_put_alloc_file;
|
||||||
}
|
|
||||||
sb->s_d_op = &hfsplus_dentry_operations;
|
|
||||||
sb->s_root = d_alloc_root(root);
|
|
||||||
if (!sb->s_root) {
|
|
||||||
iput(root);
|
|
||||||
err = -ENOMEM;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
str.len = sizeof(HFSP_HIDDENDIR_NAME) - 1;
|
str.len = sizeof(HFSP_HIDDENDIR_NAME) - 1;
|
||||||
@ -459,46 +452,69 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent)
|
|||||||
if (!hfs_brec_read(&fd, &entry, sizeof(entry))) {
|
if (!hfs_brec_read(&fd, &entry, sizeof(entry))) {
|
||||||
hfs_find_exit(&fd);
|
hfs_find_exit(&fd);
|
||||||
if (entry.type != cpu_to_be16(HFSPLUS_FOLDER))
|
if (entry.type != cpu_to_be16(HFSPLUS_FOLDER))
|
||||||
goto cleanup;
|
goto out_put_root;
|
||||||
inode = hfsplus_iget(sb, be32_to_cpu(entry.folder.id));
|
inode = hfsplus_iget(sb, be32_to_cpu(entry.folder.id));
|
||||||
if (IS_ERR(inode)) {
|
if (IS_ERR(inode)) {
|
||||||
err = PTR_ERR(inode);
|
err = PTR_ERR(inode);
|
||||||
goto cleanup;
|
goto out_put_root;
|
||||||
}
|
}
|
||||||
sbi->hidden_dir = inode;
|
sbi->hidden_dir = inode;
|
||||||
} else
|
} else
|
||||||
hfs_find_exit(&fd);
|
hfs_find_exit(&fd);
|
||||||
|
|
||||||
if (sb->s_flags & MS_RDONLY)
|
if (!(sb->s_flags & MS_RDONLY)) {
|
||||||
goto out;
|
/*
|
||||||
|
* H+LX == hfsplusutils, H+Lx == this driver, H+lx is unused
|
||||||
|
* all three are registered with Apple for our use
|
||||||
|
*/
|
||||||
|
vhdr->last_mount_vers = cpu_to_be32(HFSP_MOUNT_VERSION);
|
||||||
|
vhdr->modify_date = hfsp_now2mt();
|
||||||
|
be32_add_cpu(&vhdr->write_count, 1);
|
||||||
|
vhdr->attributes &= cpu_to_be32(~HFSPLUS_VOL_UNMNT);
|
||||||
|
vhdr->attributes |= cpu_to_be32(HFSPLUS_VOL_INCNSTNT);
|
||||||
|
hfsplus_sync_fs(sb, 1);
|
||||||
|
|
||||||
/* H+LX == hfsplusutils, H+Lx == this driver, H+lx is unused
|
if (!sbi->hidden_dir) {
|
||||||
* all three are registered with Apple for our use
|
mutex_lock(&sbi->vh_mutex);
|
||||||
*/
|
sbi->hidden_dir = hfsplus_new_inode(sb, S_IFDIR);
|
||||||
vhdr->last_mount_vers = cpu_to_be32(HFSP_MOUNT_VERSION);
|
hfsplus_create_cat(sbi->hidden_dir->i_ino, root, &str,
|
||||||
vhdr->modify_date = hfsp_now2mt();
|
sbi->hidden_dir);
|
||||||
be32_add_cpu(&vhdr->write_count, 1);
|
mutex_unlock(&sbi->vh_mutex);
|
||||||
vhdr->attributes &= cpu_to_be32(~HFSPLUS_VOL_UNMNT);
|
|
||||||
vhdr->attributes |= cpu_to_be32(HFSPLUS_VOL_INCNSTNT);
|
|
||||||
hfsplus_sync_fs(sb, 1);
|
|
||||||
|
|
||||||
if (!sbi->hidden_dir) {
|
hfsplus_mark_inode_dirty(sbi->hidden_dir,
|
||||||
mutex_lock(&sbi->vh_mutex);
|
HFSPLUS_I_CAT_DIRTY);
|
||||||
sbi->hidden_dir = hfsplus_new_inode(sb, S_IFDIR);
|
}
|
||||||
hfsplus_create_cat(sbi->hidden_dir->i_ino, sb->s_root->d_inode,
|
|
||||||
&str, sbi->hidden_dir);
|
|
||||||
mutex_unlock(&sbi->vh_mutex);
|
|
||||||
|
|
||||||
hfsplus_mark_inode_dirty(sbi->hidden_dir, HFSPLUS_I_CAT_DIRTY);
|
|
||||||
}
|
}
|
||||||
out:
|
|
||||||
|
sb->s_d_op = &hfsplus_dentry_operations;
|
||||||
|
sb->s_root = d_alloc_root(root);
|
||||||
|
if (!sb->s_root) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto out_put_hidden_dir;
|
||||||
|
}
|
||||||
|
|
||||||
unload_nls(sbi->nls);
|
unload_nls(sbi->nls);
|
||||||
sbi->nls = nls;
|
sbi->nls = nls;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cleanup:
|
out_put_hidden_dir:
|
||||||
hfsplus_put_super(sb);
|
iput(sbi->hidden_dir);
|
||||||
|
out_put_root:
|
||||||
|
iput(sbi->alloc_file);
|
||||||
|
out_put_alloc_file:
|
||||||
|
iput(sbi->alloc_file);
|
||||||
|
out_close_cat_tree:
|
||||||
|
hfs_btree_close(sbi->cat_tree);
|
||||||
|
out_close_ext_tree:
|
||||||
|
hfs_btree_close(sbi->ext_tree);
|
||||||
|
out_free_vhdr:
|
||||||
|
kfree(sbi->s_vhdr);
|
||||||
|
kfree(sbi->s_backup_vhdr);
|
||||||
|
out_unload_nls:
|
||||||
|
unload_nls(sbi->nls);
|
||||||
unload_nls(nls);
|
unload_nls(nls);
|
||||||
|
kfree(sbi);
|
||||||
|
out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ int hfsplus_read_wrapper(struct super_block *sb)
|
|||||||
break;
|
break;
|
||||||
case cpu_to_be16(HFSP_WRAP_MAGIC):
|
case cpu_to_be16(HFSP_WRAP_MAGIC):
|
||||||
if (!hfsplus_read_mdb(sbi->s_vhdr, &wd))
|
if (!hfsplus_read_mdb(sbi->s_vhdr, &wd))
|
||||||
goto out;
|
goto out_free_backup_vhdr;
|
||||||
wd.ablk_size >>= HFSPLUS_SECTOR_SHIFT;
|
wd.ablk_size >>= HFSPLUS_SECTOR_SHIFT;
|
||||||
part_start += wd.ablk_start + wd.embed_start * wd.ablk_size;
|
part_start += wd.ablk_start + wd.embed_start * wd.ablk_size;
|
||||||
part_size = wd.embed_count * wd.ablk_size;
|
part_size = wd.embed_count * wd.ablk_size;
|
||||||
@ -179,7 +179,7 @@ int hfsplus_read_wrapper(struct super_block *sb)
|
|||||||
* (should do this only for cdrom/loop though)
|
* (should do this only for cdrom/loop though)
|
||||||
*/
|
*/
|
||||||
if (hfs_part_find(sb, &part_start, &part_size))
|
if (hfs_part_find(sb, &part_start, &part_size))
|
||||||
goto out;
|
goto out_free_backup_vhdr;
|
||||||
goto reread;
|
goto reread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user