Merge branch 'udf' of https://github.com/pali/util-linux
* 'udf' of https://github.com/pali/util-linux: test: Add UDF hdd image with final block size 4096 created by Linux mkudffs 1.3 libblkid: udf: Optimize and fix probing when block size > 2048 bytes
This commit is contained in:
commit
cfcbf7526a
|
@ -167,12 +167,13 @@ static int probe_udf(blkid_probe pr,
|
||||||
uint32_t lvid_count = 0;
|
uint32_t lvid_count = 0;
|
||||||
uint32_t lvid_loc = 0;
|
uint32_t lvid_loc = 0;
|
||||||
uint32_t bs;
|
uint32_t bs;
|
||||||
uint32_t pbs[5];
|
|
||||||
uint32_t b;
|
uint32_t b;
|
||||||
uint16_t type;
|
uint16_t type;
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
uint32_t loc;
|
uint32_t loc;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
uint32_t vsd_len;
|
||||||
|
int vsd_2048_valid = -1;
|
||||||
int have_label = 0;
|
int have_label = 0;
|
||||||
int have_uuid = 0;
|
int have_uuid = 0;
|
||||||
int have_logvolid = 0;
|
int have_logvolid = 0;
|
||||||
|
@ -183,55 +184,81 @@ static int probe_udf(blkid_probe pr,
|
||||||
/* The block size of a UDF filesystem is that of the underlying
|
/* The block size of a UDF filesystem is that of the underlying
|
||||||
* storage; we check later on for the special case of image files,
|
* storage; we check later on for the special case of image files,
|
||||||
* which may have any block size valid for UDF filesystem */
|
* which may have any block size valid for UDF filesystem */
|
||||||
|
uint32_t pbs[] = { 0, 512, 1024, 2048, 4096 };
|
||||||
pbs[0] = blkid_probe_get_sectorsize(pr);
|
pbs[0] = blkid_probe_get_sectorsize(pr);
|
||||||
pbs[1] = 512;
|
|
||||||
pbs[2] = 1024;
|
|
||||||
pbs[3] = 2048;
|
|
||||||
pbs[4] = 4096;
|
|
||||||
|
|
||||||
/* check for a Volume Structure Descriptor (VSD); each is
|
for (i = 0; i < ARRAY_SIZE(pbs); i++) {
|
||||||
* 2048 bytes long */
|
/* Do not try with block size same as sector size two times */
|
||||||
for (b = 0; b < 0x8000; b += 0x800) {
|
if (i != 0 && pbs[0] == pbs[i])
|
||||||
vsd = (struct volume_structure_descriptor *)
|
continue;
|
||||||
blkid_probe_get_buffer(pr,
|
|
||||||
UDF_VSD_OFFSET + b,
|
|
||||||
sizeof(*vsd));
|
|
||||||
if (!vsd)
|
|
||||||
return errno ? -errno : 1;
|
|
||||||
if (vsd->id[0] != '\0')
|
|
||||||
goto nsr;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
nsr:
|
/* ECMA-167 2/8.4, 2/9.1: Each VSD is either 2048 bytes long or
|
||||||
/* search the list of VSDs for a NSR descriptor */
|
* its size is same as blocksize (for blocksize > 2048 bytes)
|
||||||
for (b = 0; b < 64; b++) {
|
* plus padded with zeros */
|
||||||
vsd = (struct volume_structure_descriptor *)
|
vsd_len = pbs[i] > 2048 ? pbs[i] : 2048;
|
||||||
blkid_probe_get_buffer(pr,
|
|
||||||
UDF_VSD_OFFSET + ((uint64_t) b * 0x800),
|
/* Process 2048 bytes long VSD only once */
|
||||||
sizeof(*vsd));
|
if (vsd_len == 2048) {
|
||||||
if (!vsd)
|
if (vsd_2048_valid == 0)
|
||||||
return errno ? -errno : 1;
|
continue;
|
||||||
if (memcmp(vsd->id, "NSR02", 5) == 0)
|
else if (vsd_2048_valid == 1)
|
||||||
goto anchor;
|
goto anchor;
|
||||||
if (memcmp(vsd->id, "NSR03", 5) == 0)
|
}
|
||||||
goto anchor;
|
|
||||||
}
|
/* Check for a Volume Structure Descriptor (VSD) */
|
||||||
return 1;
|
for (b = 0; b < 64; b++) {
|
||||||
|
vsd = (struct volume_structure_descriptor *)
|
||||||
|
blkid_probe_get_buffer(pr,
|
||||||
|
UDF_VSD_OFFSET + b * vsd_len,
|
||||||
|
sizeof(*vsd));
|
||||||
|
if (!vsd)
|
||||||
|
return errno ? -errno : 1;
|
||||||
|
if (vsd->id[0] == '\0')
|
||||||
|
break;
|
||||||
|
if (memcmp(vsd->id, "NSR02", 5) == 0 ||
|
||||||
|
memcmp(vsd->id, "NSR03", 5) == 0)
|
||||||
|
goto anchor;
|
||||||
|
else if (memcmp(vsd->id, "BEA01", 5) != 0 &&
|
||||||
|
memcmp(vsd->id, "BOOT2", 5) != 0 &&
|
||||||
|
memcmp(vsd->id, "CD001", 5) != 0 &&
|
||||||
|
memcmp(vsd->id, "CDW02", 5) != 0 &&
|
||||||
|
memcmp(vsd->id, "TEA01", 5) != 0)
|
||||||
|
/* ECMA-167 2/8.3.1: The volume recognition sequence is
|
||||||
|
* terminated by the first sector which is not a valid
|
||||||
|
* descriptor.
|
||||||
|
* UDF-2.60 2.1.7: UDF 2.00 and lower revisions do not
|
||||||
|
* have requirement that NSR descritor is in Extended Area
|
||||||
|
* (between BEA01 and TEA01) and that there is only one
|
||||||
|
* Extended Area. So do not stop scanning after TEA01. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vsd_len == 2048)
|
||||||
|
vsd_2048_valid = 0;
|
||||||
|
|
||||||
|
/* NSR was not found, try with next block size */
|
||||||
|
continue;
|
||||||
|
|
||||||
anchor:
|
anchor:
|
||||||
/* read Anchor Volume Descriptor (AVDP), checking block size */
|
if (vsd_len == 2048)
|
||||||
for (i = 0; i < ARRAY_SIZE(pbs); i++) {
|
vsd_2048_valid = 1;
|
||||||
|
|
||||||
|
/* Read Anchor Volume Descriptor (AVDP), detect block size */
|
||||||
vd = (struct volume_descriptor *)
|
vd = (struct volume_descriptor *)
|
||||||
blkid_probe_get_buffer(pr, 256 * pbs[i], sizeof(*vd));
|
blkid_probe_get_buffer(pr, 256 * pbs[i], sizeof(*vd));
|
||||||
if (!vd)
|
if (!vd)
|
||||||
return errno ? -errno : 1;
|
return errno ? -errno : 1;
|
||||||
|
|
||||||
|
/* Check that we read correct sector and detected correct block size */
|
||||||
|
if (le32_to_cpu(vd->tag.location) != 256)
|
||||||
|
continue;
|
||||||
|
|
||||||
type = le16_to_cpu(vd->tag.id);
|
type = le16_to_cpu(vd->tag.id);
|
||||||
if (type == TAG_ID_AVDP)
|
if (type == TAG_ID_AVDP)
|
||||||
goto real_blksz;
|
goto real_blksz;
|
||||||
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 1;
|
||||||
|
|
||||||
real_blksz:
|
real_blksz:
|
||||||
/* Use the actual block size from here on out */
|
/* Use the actual block size from here on out */
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
ID_FS_LABEL=Label4096
|
||||||
|
ID_FS_LABEL_ENC=Label4096
|
||||||
|
ID_FS_LOGICAL_VOLUME_ID=Label4096
|
||||||
|
ID_FS_TYPE=udf
|
||||||
|
ID_FS_USAGE=filesystem
|
||||||
|
ID_FS_UUID=5a08b6f521891529
|
||||||
|
ID_FS_UUID_ENC=5a08b6f521891529
|
||||||
|
ID_FS_VERSION=2.01
|
||||||
|
ID_FS_VOLUME_ID=Label4096
|
||||||
|
ID_FS_VOLUME_SET_ID=5a08b6f521891529LinuxUDF
|
Binary file not shown.
Loading…
Reference in New Issue