summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--fs/udf/partition.c10
-rw-r--r--fs/udf/super.c24
2 files changed, 22 insertions, 12 deletions
diff --git a/fs/udf/partition.c b/fs/udf/partition.c
index 307c9c33d184..b2e6e1eddb90 100644
--- a/fs/udf/partition.c
+++ b/fs/udf/partition.c
@@ -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_part_map *map;
 	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];
 	vdata = &map->s_type_specific.s_virtual;
-	index = (sb->s_blocksize - vdata->s_start_offset) / sizeof(uint32_t);
 
 	if (block > vdata->s_num_entries) {
 		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,
 		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) {
 		block -= index;
 		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,
 
 	brelse(bh);
 
-	iinfo = UDF_I(sbi->s_vat_inode);
+translate:
 	if (iinfo->i_location.partitionReferenceNum == partition) {
 		udf_debug("recursive call to udf_get_pblock!\n");
 		return 0xFFFFFFFF;
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);