summaryrefslogtreecommitdiffstats
path: root/fs/udf/super.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2008-04-08 02:08:53 +0200
committerJan Kara <jack@suse.cz>2008-04-17 14:25:35 +0200
commitfa5e08156335d0687c85b4e724db9448fb166601 (patch)
tree196b9d20b70129d892ceb3cf43ffb611b0067075 /fs/udf/super.c
parent742e1795e2d9dc99657742e5bbbb7907596bf6c3 (diff)
downloadlinux-fa5e08156335d0687c85b4e724db9448fb166601.tar.gz
linux-fa5e08156335d0687c85b4e724db9448fb166601.tar.bz2
linux-fa5e08156335d0687c85b4e724db9448fb166601.zip
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: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/udf/super.c')
-rw-r--r--fs/udf/super.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 14f965e8a738..abdb9b31da46 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -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_part_map *map = &sbi->s_partmaps[p_index];
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 */
ino.partitionReferenceNum = 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 =
(sbi->s_vat_inode->i_size - 36) >> 2;
} else if (map->s_partition_type == UDF_VIRTUAL_MAP20) {
- uint32_t pos;
- struct virtualAllocationTable20 *vat20;
+ vati = UDF_I(sbi->s_vat_inode);
+ 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 =
le16_to_cpu(vat20->lengthHeader) +
udf_ext0_offset(sbi->s_vat_inode);