diff options
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | libblkid/src/superblocks/udf.c | 45 |
2 files changed, 31 insertions, 15 deletions
@@ -385,5 +385,6 @@ CONTRIBUTORS: Yoshihiro Takahashi <ytakahashi@miraclelinux.com> Yuri Chornoivan <yurchor@ukr.net> Yu Zhiguo <yuzg@cn.fujitsu.com> + Zachary Catlin <z@zc.is> Zdenek Behan <rain@matfyz.cz> Zhi Li <lizhi1215@gmail.com> diff --git a/libblkid/src/superblocks/udf.c b/libblkid/src/superblocks/udf.c index 2cb471df2..c9fb02285 100644 --- a/libblkid/src/superblocks/udf.c +++ b/libblkid/src/superblocks/udf.c @@ -64,17 +64,25 @@ static int probe_udf(blkid_probe pr, struct volume_descriptor *vd; struct volume_structure_descriptor *vsd; unsigned int bs; + unsigned int pbs[2]; unsigned int b; unsigned int type; unsigned int count; unsigned int loc; + unsigned int i; - /* search Volume Sequence Descriptor (VSD) to get the logical - * block size of the volume */ - for (bs = 0x800; bs < 0x8000; bs += 0x800) { + /* The block size of a UDF filesystem is that of the underlying + * storage; we check later on for the special case of image files, + * which may have the 2048-byte block size of optical media. */ + pbs[0] = blkid_probe_get_sectorsize(pr); + pbs[1] = 0x800; + + /* check for a Volume Structure Descriptor (VSD); each is + * 2048 bytes long */ + for (b = 0; b < 0x8000; b += 0x800) { vsd = (struct volume_structure_descriptor *) blkid_probe_get_buffer(pr, - UDF_VSD_OFFSET + bs, + UDF_VSD_OFFSET + b, sizeof(*vsd)); if (!vsd) return 1; @@ -88,7 +96,7 @@ nsr: for (b = 0; b < 64; b++) { vsd = (struct volume_structure_descriptor *) blkid_probe_get_buffer(pr, - UDF_VSD_OFFSET + ((blkid_loff_t) b * bs), + UDF_VSD_OFFSET + ((blkid_loff_t) b * 0x800), sizeof(*vsd)); if (!vsd) return -1; @@ -102,17 +110,24 @@ nsr: return -1; anchor: - /* read Anchor Volume Descriptor (AVDP) */ - vd = (struct volume_descriptor *) - blkid_probe_get_buffer(pr, 256 * bs, sizeof(*vd)); - if (!vd) - return -1; - - type = le16_to_cpu(vd->tag.id); - if (type != 2) /* TAG_ID_AVDP */ - return 0; + /* read Anchor Volume Descriptor (AVDP), checking block size */ + for (i = 0; i < 2; i++) { + vd = (struct volume_descriptor *) + blkid_probe_get_buffer(pr, 256 * pbs[i], sizeof(*vd)); + if (!vd) + return -1; + + type = le16_to_cpu(vd->tag.id); + if (type == 2) /* TAG_ID_AVDP */ + goto real_blksz; + } + return 0; + +real_blksz: + /* Use the actual block size from here on out */ + bs = pbs[i]; - /* get desriptor list address and block count */ + /* get descriptor list address and block count */ count = le32_to_cpu(vd->type.anchor.length) / bs; loc = le32_to_cpu(vd->type.anchor.location); |