Skip to content

Commit

Permalink
udf: Try harder when looking for VAT inode
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
jankara committed Dec 14, 2009
1 parent 1fefd08 commit e971b0b
Showing 1 changed file with 24 additions and 8 deletions.
32 changes: 24 additions & 8 deletions fs/udf/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -1078,31 +1078,47 @@ static int udf_fill_partdesc_info(struct super_block *sb,
return 0;
}

static int udf_load_vat(struct super_block *sb, int p_index, int type1_index)
static void udf_find_vat_block(struct super_block *sb, int p_index,
int type1_index, sector_t start_block)
{
struct udf_sb_info *sbi = UDF_SB(sb);
struct udf_part_map *map = &sbi->s_partmaps[p_index];
sector_t vat_block;
struct kernel_lb_addr ino;

/*
* VAT file entry is in the last recorded block. Some broken disks have
* it a few blocks before so try a bit harder...
*/
ino.partitionReferenceNum = type1_index;
for (vat_block = start_block;
vat_block >= map->s_partition_root &&
vat_block >= start_block - 3 &&
!sbi->s_vat_inode; vat_block--) {
ino.logicalBlockNum = vat_block - map->s_partition_root;
sbi->s_vat_inode = udf_iget(sb, &ino);
}
}

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];
struct buffer_head *bh = NULL;
struct udf_inode_info *vati;
uint32_t pos;
struct virtualAllocationTable20 *vat20;
sector_t blocks = sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits;

/* VAT file entry is in the last recorded block */
ino.partitionReferenceNum = type1_index;
ino.logicalBlockNum = sbi->s_last_block - map->s_partition_root;
sbi->s_vat_inode = udf_iget(sb, &ino);
udf_find_vat_block(sb, p_index, type1_index, sbi->s_last_block);
if (!sbi->s_vat_inode &&
sbi->s_last_block != blocks - 1) {
printk(KERN_NOTICE "UDF-fs: Failed to read VAT inode from the"
" last recorded block (%lu), retrying with the last "
"block of the device (%lu).\n",
(unsigned long)sbi->s_last_block,
(unsigned long)blocks - 1);
ino.partitionReferenceNum = type1_index;
ino.logicalBlockNum = blocks - 1 - map->s_partition_root;
sbi->s_vat_inode = udf_iget(sb, &ino);
udf_find_vat_block(sb, p_index, type1_index, blocks - 1);
}
if (!sbi->s_vat_inode)
return 1;
Expand Down

0 comments on commit e971b0b

Please sign in to comment.