Commit ba54aef0 authored by Steven J. Magnani's avatar Steven J. Magnani Committed by Jan Kara

udf: refactor VRS descriptor identification

Extract code that parses a Volume Recognition Sequence descriptor
(component), in preparation for calling it twice against different
locations in a block.
Signed-off-by: default avatarSteven J. Magnani <steve@digidescorp.com>
Link: https://lore.kernel.org/r/20190711133852.16887-1-steve@digidescorp.comSigned-off-by: default avatarJan Kara <jack@suse.cz>
parent 609488bc
...@@ -646,16 +646,67 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options) ...@@ -646,16 +646,67 @@ static int udf_remount_fs(struct super_block *sb, int *flags, char *options)
return error; return error;
} }
/* Check Volume Structure Descriptors (ECMA 167 2/9.1) */ /*
/* We also check any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1) */ * Check VSD descriptor. Returns -1 in case we are at the end of volume
static loff_t udf_check_vsd(struct super_block *sb) * recognition area, 0 if the descriptor is valid but non-interesting, 1 if
* we found one of NSR descriptors we are looking for.
*/
static int identify_vsd(const struct volStructDesc *vsd)
{
int ret = 0;
if (!memcmp(vsd->stdIdent, VSD_STD_ID_CD001, VSD_STD_ID_LEN)) {
switch (vsd->structType) {
case 0:
udf_debug("ISO9660 Boot Record found\n");
break;
case 1:
udf_debug("ISO9660 Primary Volume Descriptor found\n");
break;
case 2:
udf_debug("ISO9660 Supplementary Volume Descriptor found\n");
break;
case 3:
udf_debug("ISO9660 Volume Partition Descriptor found\n");
break;
case 255:
udf_debug("ISO9660 Volume Descriptor Set Terminator found\n");
break;
default:
udf_debug("ISO9660 VRS (%u) found\n", vsd->structType);
break;
}
} else if (!memcmp(vsd->stdIdent, VSD_STD_ID_BEA01, VSD_STD_ID_LEN))
; /* ret = 0 */
else if (!memcmp(vsd->stdIdent, VSD_STD_ID_NSR02, VSD_STD_ID_LEN))
ret = 1;
else if (!memcmp(vsd->stdIdent, VSD_STD_ID_NSR03, VSD_STD_ID_LEN))
ret = 1;
else if (!memcmp(vsd->stdIdent, VSD_STD_ID_BOOT2, VSD_STD_ID_LEN))
; /* ret = 0 */
else if (!memcmp(vsd->stdIdent, VSD_STD_ID_CDW02, VSD_STD_ID_LEN))
; /* ret = 0 */
else {
/* TEA01 or invalid id : end of volume recognition area */
ret = -1;
}
return ret;
}
/*
* Check Volume Structure Descriptors (ECMA 167 2/9.1)
* We also check any "CD-ROM Volume Descriptor Set" (ECMA 167 2/8.3.1)
* @return 1 if NSR02 or NSR03 found,
* -1 if first sector read error, 0 otherwise
*/
static int udf_check_vsd(struct super_block *sb)
{ {
struct volStructDesc *vsd = NULL; struct volStructDesc *vsd = NULL;
loff_t sector = VSD_FIRST_SECTOR_OFFSET; loff_t sector = VSD_FIRST_SECTOR_OFFSET;
int sectorsize; int sectorsize;
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
int nsr02 = 0; int nsr = 0;
int nsr03 = 0;
struct udf_sb_info *sbi; struct udf_sb_info *sbi;
sbi = UDF_SB(sb); sbi = UDF_SB(sb);
...@@ -679,71 +730,20 @@ static loff_t udf_check_vsd(struct super_block *sb) ...@@ -679,71 +730,20 @@ static loff_t udf_check_vsd(struct super_block *sb)
* activity. This actually happened with uninitialised SSD partitions * activity. This actually happened with uninitialised SSD partitions
* (all 0xFF) before the check for the limit and all valid IDs were * (all 0xFF) before the check for the limit and all valid IDs were
* added */ * added */
for (; !nsr02 && !nsr03 && sector < VSD_MAX_SECTOR_OFFSET; for (; !nsr && sector < VSD_MAX_SECTOR_OFFSET; sector += sectorsize) {
sector += sectorsize) {
/* Read a block */ /* Read a block */
bh = udf_tread(sb, sector >> sb->s_blocksize_bits); bh = udf_tread(sb, sector >> sb->s_blocksize_bits);
if (!bh) if (!bh)
break; break;
/* Look for ISO descriptors */
vsd = (struct volStructDesc *)(bh->b_data + vsd = (struct volStructDesc *)(bh->b_data +
(sector & (sb->s_blocksize - 1))); (sector & (sb->s_blocksize - 1)));
nsr = identify_vsd(vsd);
if (!strncmp(vsd->stdIdent, VSD_STD_ID_CD001,
VSD_STD_ID_LEN)) {
switch (vsd->structType) {
case 0:
udf_debug("ISO9660 Boot Record found\n");
break;
case 1:
udf_debug("ISO9660 Primary Volume Descriptor found\n");
break;
case 2:
udf_debug("ISO9660 Supplementary Volume Descriptor found\n");
break;
case 3:
udf_debug("ISO9660 Volume Partition Descriptor found\n");
break;
case 255:
udf_debug("ISO9660 Volume Descriptor Set Terminator found\n");
break;
default:
udf_debug("ISO9660 VRS (%u) found\n",
vsd->structType);
break;
}
} else if (!strncmp(vsd->stdIdent, VSD_STD_ID_BEA01,
VSD_STD_ID_LEN))
; /* nothing */
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_TEA01,
VSD_STD_ID_LEN)) {
brelse(bh);
break;
} else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR02,
VSD_STD_ID_LEN))
nsr02 = sector;
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_NSR03,
VSD_STD_ID_LEN))
nsr03 = sector;
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_BOOT2,
VSD_STD_ID_LEN))
; /* nothing */
else if (!strncmp(vsd->stdIdent, VSD_STD_ID_CDW02,
VSD_STD_ID_LEN))
; /* nothing */
else {
/* invalid id : end of volume recognition area */
brelse(bh);
break;
}
brelse(bh); brelse(bh);
} }
if (nsr03) if (nsr > 0)
return nsr03; return 1;
else if (nsr02)
return nsr02;
else if (!bh && sector - (sbi->s_session << sb->s_blocksize_bits) == else if (!bh && sector - (sbi->s_session << sb->s_blocksize_bits) ==
VSD_FIRST_SECTOR_OFFSET) VSD_FIRST_SECTOR_OFFSET)
return -1; return -1;
...@@ -1915,7 +1915,7 @@ static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt, ...@@ -1915,7 +1915,7 @@ static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt,
int silent, struct kernel_lb_addr *fileset) int silent, struct kernel_lb_addr *fileset)
{ {
struct udf_sb_info *sbi = UDF_SB(sb); struct udf_sb_info *sbi = UDF_SB(sb);
loff_t nsr_off; int nsr = 0;
int ret; int ret;
if (!sb_set_blocksize(sb, uopt->blocksize)) { if (!sb_set_blocksize(sb, uopt->blocksize)) {
...@@ -1926,13 +1926,13 @@ static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt, ...@@ -1926,13 +1926,13 @@ static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt,
sbi->s_last_block = uopt->lastblock; sbi->s_last_block = uopt->lastblock;
if (!uopt->novrs) { if (!uopt->novrs) {
/* Check that it is NSR02 compliant */ /* Check that it is NSR02 compliant */
nsr_off = udf_check_vsd(sb); nsr = udf_check_vsd(sb);
if (!nsr_off) { if (!nsr) {
if (!silent) if (!silent)
udf_warn(sb, "No VRS found\n"); udf_warn(sb, "No VRS found\n");
return -EINVAL; return -EINVAL;
} }
if (nsr_off == -1) if (nsr == -1)
udf_debug("Failed to read sector at offset %d. " udf_debug("Failed to read sector at offset %d. "
"Assuming open disc. Skipping validity " "Assuming open disc. Skipping validity "
"check\n", VSD_FIRST_SECTOR_OFFSET); "check\n", VSD_FIRST_SECTOR_OFFSET);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment