Commit e971b0b9e0dd50d9ceecb67a6a6ab80a80906033

Authored by Jan Kara
1 parent 1fefd086df

udf: Try harder when looking for VAT inode

Some disks do not contain VAT inode in the last recorded block as required
by the standard but a few blocks earlier (or the number of recorded blocks
is wrong). So look for the VAT inode a bit before the end of the media.

Signed-off-by: Jan Kara <jack@suse.cz>

Showing 1 changed file with 24 additions and 8 deletions Side-by-side Diff

... ... @@ -1078,21 +1078,39 @@
1078 1078 return 0;
1079 1079 }
1080 1080  
1081   -static int udf_load_vat(struct super_block *sb, int p_index, int type1_index)
  1081 +static void udf_find_vat_block(struct super_block *sb, int p_index,
  1082 + int type1_index, sector_t start_block)
1082 1083 {
1083 1084 struct udf_sb_info *sbi = UDF_SB(sb);
1084 1085 struct udf_part_map *map = &sbi->s_partmaps[p_index];
  1086 + sector_t vat_block;
1085 1087 struct kernel_lb_addr ino;
  1088 +
  1089 + /*
  1090 + * VAT file entry is in the last recorded block. Some broken disks have
  1091 + * it a few blocks before so try a bit harder...
  1092 + */
  1093 + ino.partitionReferenceNum = type1_index;
  1094 + for (vat_block = start_block;
  1095 + vat_block >= map->s_partition_root &&
  1096 + vat_block >= start_block - 3 &&
  1097 + !sbi->s_vat_inode; vat_block--) {
  1098 + ino.logicalBlockNum = vat_block - map->s_partition_root;
  1099 + sbi->s_vat_inode = udf_iget(sb, &ino);
  1100 + }
  1101 +}
  1102 +
  1103 +static int udf_load_vat(struct super_block *sb, int p_index, int type1_index)
  1104 +{
  1105 + struct udf_sb_info *sbi = UDF_SB(sb);
  1106 + struct udf_part_map *map = &sbi->s_partmaps[p_index];
1086 1107 struct buffer_head *bh = NULL;
1087 1108 struct udf_inode_info *vati;
1088 1109 uint32_t pos;
1089 1110 struct virtualAllocationTable20 *vat20;
1090 1111 sector_t blocks = sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits;
1091 1112  
1092   - /* VAT file entry is in the last recorded block */
1093   - ino.partitionReferenceNum = type1_index;
1094   - ino.logicalBlockNum = sbi->s_last_block - map->s_partition_root;
1095   - sbi->s_vat_inode = udf_iget(sb, &ino);
  1113 + udf_find_vat_block(sb, p_index, type1_index, sbi->s_last_block);
1096 1114 if (!sbi->s_vat_inode &&
1097 1115 sbi->s_last_block != blocks - 1) {
1098 1116 printk(KERN_NOTICE "UDF-fs: Failed to read VAT inode from the"
... ... @@ -1100,9 +1118,7 @@
1100 1118 "block of the device (%lu).\n",
1101 1119 (unsigned long)sbi->s_last_block,
1102 1120 (unsigned long)blocks - 1);
1103   - ino.partitionReferenceNum = type1_index;
1104   - ino.logicalBlockNum = blocks - 1 - map->s_partition_root;
1105   - sbi->s_vat_inode = udf_iget(sb, &ino);
  1121 + udf_find_vat_block(sb, p_index, type1_index, blocks - 1);
1106 1122 }
1107 1123 if (!sbi->s_vat_inode)
1108 1124 return 1;