提交 fa5e0815 编写于 作者: J Jan Kara

udf: Handle VAT packed inside inode properly

We didn't handle VAT packed inside the inode - we tried to call udf_block_map()
on such file which lead to strange results at best. Add proper handling of
packed VAT as we do it with other packed files.
Signed-off-by: NJan Kara <jack@suse.cz>
上级 742e1795
...@@ -54,11 +54,10 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block, ...@@ -54,11 +54,10 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block,
struct udf_sb_info *sbi = UDF_SB(sb); struct udf_sb_info *sbi = UDF_SB(sb);
struct udf_part_map *map; struct udf_part_map *map;
struct udf_virtual_data *vdata; struct udf_virtual_data *vdata;
struct udf_inode_info *iinfo; struct udf_inode_info *iinfo = UDF_I(sbi->s_vat_inode);
map = &sbi->s_partmaps[partition]; map = &sbi->s_partmaps[partition];
vdata = &map->s_type_specific.s_virtual; vdata = &map->s_type_specific.s_virtual;
index = (sb->s_blocksize - vdata->s_start_offset) / sizeof(uint32_t);
if (block > vdata->s_num_entries) { if (block > vdata->s_num_entries) {
udf_debug("Trying to access block beyond end of VAT " udf_debug("Trying to access block beyond end of VAT "
...@@ -66,6 +65,11 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block, ...@@ -66,6 +65,11 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block,
return 0xFFFFFFFF; return 0xFFFFFFFF;
} }
if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
loc = le32_to_cpu(((__le32 *)iinfo->i_ext.i_data)[block]);
goto translate;
}
index = (sb->s_blocksize - vdata->s_start_offset) / sizeof(uint32_t);
if (block >= index) { if (block >= index) {
block -= index; block -= index;
newblock = 1 + (block / (sb->s_blocksize / sizeof(uint32_t))); newblock = 1 + (block / (sb->s_blocksize / sizeof(uint32_t)));
...@@ -88,7 +92,7 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block, ...@@ -88,7 +92,7 @@ uint32_t udf_get_pblock_virt15(struct super_block *sb, uint32_t block,
brelse(bh); brelse(bh);
iinfo = UDF_I(sbi->s_vat_inode); translate:
if (iinfo->i_location.partitionReferenceNum == partition) { if (iinfo->i_location.partitionReferenceNum == partition) {
udf_debug("recursive call to udf_get_pblock!\n"); udf_debug("recursive call to udf_get_pblock!\n");
return 0xFFFFFFFF; return 0xFFFFFFFF;
......
...@@ -1107,7 +1107,10 @@ static int udf_load_vat(struct super_block *sb, int p_index, int type1_index) ...@@ -1107,7 +1107,10 @@ static int udf_load_vat(struct super_block *sb, int p_index, int type1_index)
struct udf_sb_info *sbi = UDF_SB(sb); struct udf_sb_info *sbi = UDF_SB(sb);
struct udf_part_map *map = &sbi->s_partmaps[p_index]; struct udf_part_map *map = &sbi->s_partmaps[p_index];
kernel_lb_addr ino; kernel_lb_addr ino;
struct buffer_head *bh; struct buffer_head *bh = NULL;
struct udf_inode_info *vati;
uint32_t pos;
struct virtualAllocationTable20 *vat20;
/* VAT file entry is in the last recorded block */ /* VAT file entry is in the last recorded block */
ino.partitionReferenceNum = type1_index; ino.partitionReferenceNum = type1_index;
...@@ -1122,15 +1125,18 @@ static int udf_load_vat(struct super_block *sb, int p_index, int type1_index) ...@@ -1122,15 +1125,18 @@ static int udf_load_vat(struct super_block *sb, int p_index, int type1_index)
map->s_type_specific.s_virtual.s_num_entries = map->s_type_specific.s_virtual.s_num_entries =
(sbi->s_vat_inode->i_size - 36) >> 2; (sbi->s_vat_inode->i_size - 36) >> 2;
} else if (map->s_partition_type == UDF_VIRTUAL_MAP20) { } else if (map->s_partition_type == UDF_VIRTUAL_MAP20) {
uint32_t pos; vati = UDF_I(sbi->s_vat_inode);
struct virtualAllocationTable20 *vat20; if (vati->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
pos = udf_block_map(sbi->s_vat_inode, 0);
bh = sb_bread(sb, pos);
if (!bh)
return 1;
vat20 = (struct virtualAllocationTable20 *)bh->b_data;
} else {
vat20 = (struct virtualAllocationTable20 *)
vati->i_ext.i_data;
}
pos = udf_block_map(sbi->s_vat_inode, 0);
bh = sb_bread(sb, pos);
if (!bh)
return 1;
vat20 = (struct virtualAllocationTable20 *)bh->b_data +
udf_ext0_offset(sbi->s_vat_inode);
map->s_type_specific.s_virtual.s_start_offset = map->s_type_specific.s_virtual.s_start_offset =
le16_to_cpu(vat20->lengthHeader) + le16_to_cpu(vat20->lengthHeader) +
udf_ext0_offset(sbi->s_vat_inode); udf_ext0_offset(sbi->s_vat_inode);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册