[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: mkisofs -M makes no attempt to reconstruct multi-extent files



You used mkisofs incorrectly
Command line sequence was *tailored* to allow to produce usable input for *hex editor* in less than minute.
Why did you use -C16,xxx?

This is definitely wrong.
The reason is in the beginning of merge_isofs() in multi.c. In particular for (i=0;i<100;i++) loop. As area prior sector 16 is allowed to be and customarily used for other purposes (such as hybrid disks), there is no guarantee that data there does not resemble iso9660 volume descriptor. I don't want mkisofs to look at sectors prior 16th at all, but start directly with volume descriptor. One can argue that mkisofs should have seek-ed to 16th sector all by itself, but the code has been around for so long, that it should be considered feature, not bug.

In theory, I could change mkisofs to start looking at sector #16

Once again, the code has been around for so long, that it should be considered to be a feature, and therefore no modifications should me made. In other words, don't.

But if you put something that looks like a PVD between sector #0 and sector #15, then your software is wrong anyway. Are you really doing this?

I'm not putting anything between sectors #0 and #15, but it does not mean that some other program does not. And by doing so such program does *not* violate any standards, moreover, it's common practice. mkisofs itself puts data there if instructed to generate hybrid disk. Data put by mkisofs does not normally resemble PVD, but *formally* there is no guarantee that it won't. Therefore it's not inappropriate (or in other words it's not "definitely wrong") to guide mkisofs directly to 16th sector.

Your claim that the file is non-contiguous is just wrong.
Having 9GB 5G.0 file in XP (previously discussed), if I read byte prior 4GB-2KB offset in the file, I get last byte from LBA X+0x200000-2, and when I read next byte, i.e. at 4GB-2KB offset in file I get data from LBA Y, and there is >1GB gap between X+0x200000 and Y.

I cannot speak for the sofware you used to look at the image.....

In other words you're implying that under no circumstances results obtained with software of my choice could be possibly right.

I looked at my test results using isoinfo and isoinfo did not show non-contiguous files.

Already mentioned 'isoinfo -l -i /dev/dvd' output:

Directory listing of /
d---------   0    0    0       2048 May 20 2008 [2621639 02] .
d---------   0    0    0       2048 May 20 2008 [2621639 02] ..
----------   0    0    0 9663674368 May 20 2008 [     24 80] 5G.1;1
----------   0    0    0 1073743872 May 20 2008 [2097175 00] 5G000.0;1

In other words, like Windows XP kernel, isoinfo also reckoned that there are one ~9GB and one ~1GB file. Now suggested 'isoinfo -debug -l -i /dev/dvd' output:

Directory listing of /
d---------   0    0    0       2048 May 20 2008 [2621639 02] .
d---------   0    0    0       2048 May 20 2008 [2621639 02] ..
----------   0    0    0 4294965248 May 20 2008 [     24 80] 5G.0;1
----------   0    0    0 4294965248 May 20 2008 [2621640 80] 5G.1;1
----------   0    0    0 1073743872 May 20 2008 [4718791 00] 5G.1;1
----------   0    0    0 9663674368 May 20 2008 [     24 00] 5G.1;1
----------   0    0    0 1073743872 May 20 2008 [2097175 00] 5G000.0;1

It depicts that 9GB file consists of 3 extents, 1st starting at LBA 24, 2nd at 2621640, and finally 3rd one at 4718791. But where does first extent end? At 24 + 4294965248 / 2048 = 2097175, which is more than 1GB apart from start of 2nd extent.

P.S.: The solution to correctly import directory entries from old sessions is not trivial but a first hacky solution seems to work....

Just for reference, attached patch would handle even shrinking multi-extent files. Once again I want to point out that I make no claims that the patches are complete solution to the problem. Their purpose is to support claims in original bug report. A.

--- ./mkisofs/multi.c.orig	2007-08-20 18:17:17.000000000 +0200
+++ ./mkisofs/multi.c	2008-05-23 14:05:38.000000000 +0200
@@ -538,6 +538,7 @@
 	unsigned char	*tt_buf;
 	UInt32_t	tt_extent;
 	UInt32_t		tt_size;
+	int		mxpart;
 
 	static int	warning_given = 0;
 
@@ -589,6 +590,7 @@
 	tt_extent = 0;
 	seen_rockridge = 0;
 	tt_size = 0;
+	mxpart = 0;
 	while (i < len) {
 		idr = (struct iso_directory_record *) & dirbuff[i];
 		if ((i + (idr->length[0] & 0xFF)) > len) {
@@ -635,6 +637,20 @@
 		(*pnt)->rr_attr_size = 0;
 		(*pnt)->total_rr_attr_size = 0;
 		(*pnt)->de_flags = SAFE_TO_REUSE_TABLE_ENTRY;
+
+		/*
+		 * Track multi-extent files.
+		 */
+		if (idr->flags[0]&ISO_MULTIEXTENT) {
+			(*pnt)->de_flags |= MULTI_EXTENT;
+			(*pnt)->mxpart = ++mxpart;
+		}
+		else if (mxpart) {
+			(*pnt)->de_flags |= MULTI_EXTENT;
+			(*pnt)->mxpart = ++mxpart;
+			mxpart = 0;
+		}
+
 #ifdef APPLE_HYB
 		(*pnt)->assoc = NULL;
 		(*pnt)->hfs_ent = NULL;
@@ -947,6 +963,7 @@
 {
 	int		i;
 	int		rr;
+	int		same;
 	int		retcode = 0;	/* Default not found */
 
 	for (i = 0; i < len; i++) {
@@ -996,6 +1013,7 @@
 		 * out again.
 		 */
 		retcode = 1;	/* We found a non directory */
+		same = 0;	/* assume not same */
 
 		if (ptr[i]->rr_attributes != NULL) {
 			if ((rr = check_rr_dates(ptr[i], curr_entry, statbuf,
@@ -1024,11 +1042,22 @@
 		memcpy(curr_entry->isorec.extent, ptr[i]->isorec.extent, 8);
 		curr_entry->starting_block = get_733(ptr[i]->isorec.extent);
 		curr_entry->de_flags |= SAFE_TO_REUSE_TABLE_ENTRY;
+		same = 1;
 		goto found_it;
 	}
 	return (retcode);
 
 found_it:
+	if (retcode==1 && !same && ptr[i]->mxpart==1) {
+		/* if out-of-date file is multi-extent,
+		 * retire all extents */
+		int j=i;
+		while (++j<len && ptr[j] && ptr[j]->mxpart>1) {
+			free(ptr[j]);
+			ptr[j] = NULL;
+		}
+	}
+
 	if (odpnt != NULL) {
 		*odpnt = ptr[i];
 	} else {

Reply to: