summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZachary Catlin2013-03-02 03:34:25 +0100
committerZachary Catlin2013-03-02 03:54:00 +0100
commit5a45eb2d2c70dc7ea2ff4c7b56ab8dba2780f033 (patch)
tree0d8139dee0474bb78f274b964b8e3d3f66c76144
parentlibmount: ignore name=value if only 'name' is expected (diff)
downloadkernel-qcow2-util-linux-5a45eb2d2c70dc7ea2ff4c7b56ab8dba2780f033.tar.gz
kernel-qcow2-util-linux-5a45eb2d2c70dc7ea2ff4c7b56ab8dba2780f033.tar.xz
kernel-qcow2-util-linux-5a45eb2d2c70dc7ea2ff4c7b56ab8dba2780f033.zip
libblkid: use correct block size for UDF probe
In UDF, Volume Structure Descriptors are always 2048 bytes long (ECMA-167, 3rd ed., §2/9.1), while filesystem sectors are the same size as the sectors of the underlying media (e.g., UDF 2.01 §1.3.2). Before this commit, the block size was estimated from VSD offsets, which gives incorrect answers for non-optical media. Now, the UDF probe uses the device block size by default, falling back to 2048-byte sectors for the case of optical-disk images. Signed-off-by: Zachary Catlin <z@zc.is>
-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);