mtio/sa device response to bad blocks
James E. Flemer
jflemer at uvm.edu
Mon Jan 3 21:06:19 PST 2005
I have a SCSI DAT drive and have had some problems reading tapes with
bad blocks. It seems that a read(2) from the sa device returns 0 when a
bad block is read from the tape. Note that read(2) also correctly
returns 0 when a filemark is read. A userland application (see below)
can tell the difference between a filemark and a read error by looking
at the io_sense part of the scsi_tape_errors struct (via the
MTIOCERRSTAT ioctl). However this is cumbersome and requires the
knowledge of the scsi_sense_data struct. It would seem more appropriate
for the read to return -1 and set errno to EIO when a bad block is read.
With such a change "dd conv=noerror,sync" could be used to dump a tape
with bad blocks. Unfortunately, I'm not familiar enough with the
SCSI/CAM layers to know where make this change, could someone point me
where to look?
Thanks,
-James
/* This code will check the real reason for read to return 0
* and change the return code to -1 and set errno to EIO if there
* was a MEDIUM_ERROR. Other non-SSD_FILEMARK/SSD_EOM flags
* should probably also be handled via -1/errno.
*/
num_read = read(mtfd, buf, blk_size);
if (num_read == 0) {
ioctl(mtfd, MTIOCERRSTAT, &tape_err);
sense_data = (struct scsi_sense_data *)&tape_err.io_sense;
if (sense_data->flags & SSD_KEY_MEDIUM_ERROR) {
num_read = -1;
errno = EIO;
}
}
More information about the freebsd-scsi
mailing list