Skip to contentSkip to conversation

PROBLEM: Impossible to read files from a CD-Rom

DISCUSSION Sébastien Hinderer 4 participants 6 messages Aug 18, 2003 – Oct 8, 2003

lore
Share & tools
lore
#0 lore raw

Dear all,

I'm using a vanila linux-2.6.0-test3.
When I try to use a CD-Rom, the mount is successful, so are the calls to ls.
However, as soon as I try to read a file, I get a lot of messages such as :

hdc: rw=0, want=505092, limit=31544
Buffer I/O error on device hdc, logical block 126272 attempt to access beyond end of device

The computer is a Dell Lattitude laptop.
On the same machine, I can use CDs properly with a 2.4.18 kernel.

Cheers,
Sébastien.

#1 lore raw

Hi,

Quoted 8 lines · Sébastien Hinderer

I'm using a vanila linux-2.6.0-test3.
When I try to use a CD-Rom, the mount is successful, so are the calls to ls.
However, as soon as I try to read a file, I get a lot of messages such as :

hdc: rw=0, want=505092, limit=31544
Buffer I/O error on device hdc, logical block 126272 attempt to access beyond end of device

We dug a little bit this Monday with Sebastien, and found out some
troubles: the call to set_capacity at the end of cdrom_read_toc() writes a strange value, which is not always the same, even for the same reinserted CD-ROM, seemingly because it came from cdrom_get_last_written():

cdrom_get_last_written() calls cdrom_get_disc_info(), then cdrom_get_track_info() and uses the track_start and track_size to compute the limit of the disk. The trouble seems to come from the fact that in cdrom_get_track_info(), the info size is got from the drive, but no check is done to ensure that it will fill up the whole track_information structure, which is not reset to 0 either, so that random values remain:

(linux-2.6.0-test4/drivers/cdrom/cdrom.c:2214)

	if ((ret = cdo->generic_packet(cdi, &cgc)))
		return ret;
	
	cgc.buflen = be16_to_cpu(ti->track_information_length) +
		     sizeof(ti->track_information_length);

	if (cgc.buflen > sizeof(track_information))
		cgc.buflen = sizeof(track_information);

	cgc.cmd[8] = cgc.buflen;
	return cdo->generic_packet(cdi, &cgc);

The solution would be to return an error if
cgc.buflen != sizeof(track_information) after the truncation to sizeof(track_information), so that cdrom_get_last_written() will correctly fail, and make cdrom_read_toc() use cdrom_read_capacity() instead, which gives the correct answer.

The same remark applies to cdrom_get_disc_info().

Regards,
Samuel Thibault

#2 lore raw
Quoted 38 lines · Samuel Thibault

Hi,

Quoted 8 lines · Sébastien Hinderer

I'm using a vanila linux-2.6.0-test3.
When I try to use a CD-Rom, the mount is successful, so are the calls to ls.
However, as soon as I try to read a file, I get a lot of messages such as :

hdc: rw=0, want=505092, limit=31544
Buffer I/O error on device hdc, logical block 126272 attempt to access beyond end of device

We dug a little bit this Monday with Sebastien, and found out some
troubles: the call to set_capacity at the end of cdrom_read_toc() writes a strange value, which is not always the same, even for the same reinserted CD-ROM, seemingly because it came from cdrom_get_last_written():

cdrom_get_last_written() calls cdrom_get_disc_info(), then cdrom_get_track_info() and uses the track_start and track_size to compute the limit of the disk. The trouble seems to come from the fact that in cdrom_get_track_info(), the info size is got from the drive, but no check is done to ensure that it will fill up the whole track_information structure, which is not reset to 0 either, so that random values remain:

(linux-2.6.0-test4/drivers/cdrom/cdrom.c:2214)

	if ((ret = cdo->generic_packet(cdi, &cgc)))
		return ret;
	
	cgc.buflen = be16_to_cpu(ti->track_information_length) +
		     sizeof(ti->track_information_length);

	if (cgc.buflen > sizeof(track_information))
		cgc.buflen = sizeof(track_information);

	cgc.cmd[8] = cgc.buflen;
	return cdo->generic_packet(cdi, &cgc);
Quoted 5 lines

The solution would be to return an error if
cgc.buflen != sizeof(track_information) after the truncation to sizeof(track_information), so that cdrom_get_last_written() will correctly fail, and make cdrom_read_toc() use cdrom_read_capacity() instead, which gives the correct answer.

It isn't that easy, if that were the case there would be no need for the above code would there?

This basically boils down to a typical problem with CDROM/DVD drives - some specific structure may vary a little in size depending on when in the spec cycle they were implemented. Some drives barf if you try and read to much, some when you read too little. So the approach that typically works the best is to just read the very first of the structure, check the length, and issue a read for the complete data.

I'd be more interested in fixing the real bug: why does your drive return zero length, and only sporadically?

Signature · 1 line
Jens Axboe
#3 lore raw

Le ven 12 sep 2003 08:51:16 GMT, Jens Axboe a tapoté sur son clavier :

Quoted 10 lines · Samuel Thibault
Quoted 5 lines

The solution would be to return an error if
cgc.buflen != sizeof(track_information) after the truncation to sizeof(track_information), so that cdrom_get_last_written() will correctly fail, and make cdrom_read_toc() use cdrom_read_capacity() instead, which gives the correct answer.

It isn't that easy, if that were the case there would be no need for the above code would there?

Quoted 6 lines

This basically boils down to a typical problem with CDROM/DVD drives - some specific structure may vary a little in size depending on when in the spec cycle they were implemented. Some drives barf if you try and read to much, some when you read too little. So the approach that typically works the best is to just read the very first of the structure, check the length, and issue a read for the complete data.

This is fine. Another solution would be that cdrom_get_track_info returns the actual amount of data that was read, so that the caller may check that the field it needs was really filled up.

Quoted 2 lines

I'd be more interested in fixing the real bug: why does your drive return zero length, and only sporadically?

This we don't know, and I don't think we may do much about it. The cdrom drive is a Dell one, connected to a dell laptop. They don't come from the same laptop package at first, but it should still work (or linux may try to work it around).

The very funny thing about it is that with 2.4 there was no problem merely because it happened that the not filled up track_size field already had a very big value, so that linux would think the cd is actually very big and let i/o go...

Regards,
Samuel Thibault

#4 lore raw

Hi,

Le ven 12 sep 2003 11:58:25 GMT, Samuel Thibault a tapoté sur son clavier :

Quoted 9 lines

Le ven 12 sep 2003 08:51:16 GMT, Jens Axboe a tapoté sur son clavier :

Quoted 6 lines

This basically boils down to a typical problem with CDROM/DVD drives - some specific structure may vary a little in size depending on when in the spec cycle they were implemented. Some drives barf if you try and read to much, some when you read too little. So the approach that typically works the best is to just read the very first of the structure, check the length, and issue a read for the complete data.

Quoted 3 lines

This is fine. Another solution would be that cdrom_get_track_info returns the actual amount of data that was read, so that the caller may check that the field it needs was really filled up.

I tested this and it worked fine.

Quoted 2 lines
Quoted 2 lines

I'd be more interested in fixing the real bug: why does your drive return zero length, and only sporadically?

Not sporadically, it always returns the same amount of data, but this amount is not sufficient to give the size, so that an arbitrary size is taken. The function should see that and report an error instead, which will fix the problem we had by trigging another size discovery mean.

Regards,
Samuel Thibault

#5 lore raw
In reply to Jens Axboe
Quoted 5 lines · Jens Axboe
Quoted 4 lines · Samuel Thibault
Quoted 3 lines · Sébastien Hinderer

I'm using a vanila linux-2.6.0-test3. When I try to use a CD-Rom, the mount is successful, so are the calls to ls. However, as soon as I try to read a file, I get a lot of messages such as :

[...]

Quoted 5 lines
Quoted 5 lines

We dug a little bit this Monday with Sebastien, and found out some
troubles: the call to set_capacity at the end of cdrom_read_toc() writes a strange value, which is not always the same, even for the same reinserted CD-ROM, seemingly because it came from cdrom_get_last_written():

[...]

Quoted 2 lines

I'd be more interested in fixing the real bug: why does your drive return zero length, and only sporadically?

This sounds somewhat like a problem I have playing DVD-R discs on one DVD drive (Pioneer slot-loader), using Xine and the RAW device.

Basically, for some discs, the raw device cannot read any block, as the capacity of the disc is reported as zero blocks.

I don't have trouble accessing the content on any other machine, though, and can access the files through a mounted filesystem.

/proc/ide/hdc/capacity contains zero in these cases.

Occasionally, for a disc that does this, I get a valid (looking) size, but not very often -- one time in twenty, at most.

I am happy to work on debugging this, if there is anything that can be done to help identify the problem.

This only seems to occur with DVD-R discs, and without any predictable pattern.

Daniel

Signature · 3 lines
Gratitude is one of the least articulate of the emotions, 
especially when it is deep.
        -- Felix Frankfurter