[parted-devel] [PATCH] libparted: Add support for MBR id and GPT GUID of UDF filesystem

Pali Rohár pali.rohar at gmail.com
Thu Aug 23 17:53:29 BST 2018


On Thursday 23 August 2018 12:31:36 Phillip Susi wrote:
> On 8/22/2018 2:38 PM, Pali Rohár wrote:
> > /* Detect UDF filesystem, it must have VRS and AVDP, returns UDF block size */
> > static unsigned int detect_udf(int fd, off_t size)
> > {
> > 	/* All possible combinations of UDF block size and location of AVDP block */
> > 	static int anchors[] = { 256, -257, -1, 512 };
> > 	static unsigned int blocksizes[] = { 512, 1024, 2048, 4096, 8192, 16384, 32768 };
> > 
> > 	int detected_vrs[sizeof(blocksizes)/sizeof(*blocksizes)];
> > 	size_t i, j;
> > 
> > 	/* VSD size is min(2048, UDF block size) */
> > 	detected_vrs[0] = detected_vrs[1] = detected_vrs[2] = detect_vrs(fd, 2048);
> > 	if (detected_vrs[0])
> > 	{
> > 		for (i = 0; i < 3; i++)
> > 		{
> > 			if (detect_anchor(fd, blocksizes[i], anchors[0], size))
> > 				return blocksizes[i];
> > 		}
> > 	}
> > 	/* Check for block sizes larger then 2048 */
> > 	for (i = 3; i < sizeof(blocksizes)/sizeof(*blocksizes); i++)
> > 	{
> > 		detected_vrs[i] = detect_vrs(fd, blocksizes[i]);
> > 		if (!detected_vrs[i])
> > 			continue;
> > 		if (detect_anchor(fd, blocksizes[i], anchors[0], size))
> > 			return blocksizes[i];
> > 	}
> > 
> > 	/* Check remaining possible AVDP locations and all block sizes */
> > 	for (i = 1; i < sizeof(anchors)/sizeof(*anchors); i++)
> > 	{
> > 		for (j = 0; j < sizeof(blocksizes)/sizeof(*blocksizes); j++)
> > 		{
> > 			if (!detected_vrs[j])
> > 				continue;
> > 			if (detect_anchor(fd, blocksizes[j], anchors[i], size))
> > 				return blocksizes[j];
> > 		}
> > 	}
> 
> I'm a little confused as to why the 3 different loops.  Why do you only
> check the first anchor location in the first two loops, then finally go
> back in the third loop and try the remaining locations?  Why not have
> detect_anchor try all 4 locations internally?

UDF must have VRS and AVDP. So first check if there is VRS. Check for
AVDP does not make sense if VRS was not detected (VRS = Volume
Recognition Sequence). And normally AVDP should be at block 256 (but
other 3 locations are possible too). So algorithm is:

for possible AVDP locations do:
    for every valid block size do:
        if there is no valid VRS for block size:
            continue
        if AVDP at location for block size is missing:
            continue
        report valid UDF with block size

But to prevent calling detection of VRS multiple times for different
AVDP location, result of VRS detection is cached.

And because size of VSD is min(2048, block size), detection for VRS with
block sizes 512 - 2048 is same too.

So 3 loops is just optimization. First one checks VRS for block size 512
- 2048 with (the most common) AVDP location 256. Second loop checks VRS
and AVDP 256 for higher block sizes and last loop use cached result of
VRS and checks remaining (less common) AVDP location for every block
size.

-- 
Pali Rohár
pali.rohar at gmail.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 195 bytes
Desc: not available
URL: <http://alioth-lists.debian.net/pipermail/parted-devel/attachments/20180823/0c7d1b65/attachment.sig>


More information about the parted-devel mailing list