summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--libblkid/src/superblocks/udf.c45
2 files changed, 31 insertions, 15 deletions
diff --git a/AUTHORS b/AUTHORS
index f29f9a3a2..54fe7cec2 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -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);