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

Phillip Susi psusi at ubuntu.com
Thu Aug 23 17:31:36 BST 2018


On 8/22/2018 2:38 PM, Pali Rohár wrote:
> Hi! I tried to implement it correctly. In attachment is a simple program
> which check if input file is UDF filesystem or not.
> 
> But I do not know to easily re-write it to parted API as for reading
> buffer there is just ped_geometry_read() function. Which does not take
> offset in bytes, but in number of sectors. Anyway, if you have some idea
> how to do it easily let me know...

It looks like the vrs is in the first 2 MB + 32KB of the disk so I'd
allocate a buffer and read all of that in, then change your search code
to just index into that buffer instead of seeking and reading.  Then
when looking for the anchor, just take your byte offset and divide by
the sector size to get the sector number.  Take the block size and
divide by the sector size to get the number of sectors to read.  Read
that into a buffer, then index to the offsets for the signatures.

Also you can skip the block sizes that are less than the sector size.

> /* 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?

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 473 bytes
Desc: OpenPGP digital signature
URL: <http://alioth-lists.debian.net/pipermail/parted-devel/attachments/20180823/cbb01e45/attachment.sig>


More information about the parted-devel mailing list